Changeset 7981 in project


Ignore:
Timestamp:
01/28/08 20:57:18 (10 years ago)
Author:
kon
Message:

Made sqlite3 null column value Scheme value explicit. Added note about the sql-null egg. Collapsed some common code into shared procedures.

Location:
release/3/sqlite3
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • release/3/sqlite3/tags/2.0.3/doc.scm

    r6115 r7981  
    66     (description (p "Bindings to version 3.x of the SQLite API."))
    77     (author (url "http://www.chust.org/" "Thomas Chust"))
     8     (usage)
     9     (download "sqlite3.egg")
     10     (requires "synch" "tinyclos" "easyffi")
     11
     12     (documentation
     13      (p "The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.")
     14      (p "For in-depth information on the functionality of the routines and general information you should consult the " (url "http://www.sqlite.org/" "SQLite documentation") " as well as this manual.")
     15
     16      (subsection
     17       "Exceptions"
     18       (p "Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind " (tt "(exn sqlite3)") " if something goes wrong. This exception will contain a " (tt "status") " property indicating the return value of the operation that failed:"
     19        (table
     20         (tr (th "Symbol") (th "Meaning"))
     21         #;(tr (td (tt "ok")) (td "Successful result"))
     22         (tr (td (tt "error")) (td "SQL error or missing database "))
     23         (tr (td (tt "internal")) (td "An internal logic error in SQLite "))
     24         (tr (td (tt "permission")) (td "Access permission denied "))
     25         (tr (td (tt "abort")) (td "Callback routine requested an abort "))
     26         (tr (td (tt "busy")) (td "The database file is locked "))
     27         (tr (td (tt "locked")) (td "A table in the database is locked "))
     28         (tr (td (tt "no-memory")) (td "A malloc() failed "))
     29         (tr (td (tt "read-only")) (td "Attempt to write a readonly database "))
     30         (tr (td (tt "interrupt")) (td "Operation terminated by sqlite-interrupt() "))
     31         (tr (td (tt "io-error")) (td "Some kind of disk I/O error occurred "))
     32         (tr (td (tt "corrupt")) (td "The database disk image is malformed "))
     33         (tr (td (tt "not-found")) (td "(Internal Only) Table or record not found "))
     34         (tr (td (tt "full")) (td "Insertion failed because database is full "))
     35         (tr (td (tt "cant-open")) (td "Unable to open the database file "))
     36         (tr (td (tt "protocol")) (td "Database lock protocol error "))
     37         (tr (td (tt "empty")) (td "(Internal Only) Database table is empty "))
     38         (tr (td (tt "schema")) (td "The database schema changed "))
     39         (tr (td (tt "too-big")) (td "Too much data for one row of a table "))
     40         (tr (td (tt "constraint")) (td "Abort due to contraint violation "))
     41         (tr (td (tt "mismatch")) (td "Data type mismatch "))
     42         (tr (td (tt "misuse")) (td "Library used incorrectly "))
     43         (tr (td (tt "no-lfs")) (td "Uses OS features not supported on host "))
     44         (tr (td (tt "authorization")) (td " Authorization denied"))
     45         #;(tr (td (tt "row")) (td (tt "sqlite3:step!") " has another row ready "))
     46         (tr (td (tt "done")) (td (tt "sqlite3:step!") " has finished executing, so no further data is ready")))))
     47
     48      (subsection
     49       "Classes"
     50       (group
     51        (definition
     52          (signatures
     53           (signature "class" "<sqlite3:database>")
     54           (signature "class" "<sqlite3:statement>"))
     55          (p "These classes are derived from " (tt "<c++-object>") ". They hold a pointer to the underlying C-structure in their " (tt "this") " slot.")
     56          (p (tt "<sqlite3:statement>") " also has a " (tt "database") " slot pointing to the database object it belongs to."))))
     57
     58      (subsection
     59       "Managing databases"
     60       (group
     61        (procedure
     62         "(sqlite3:open (path <string>)) => <sqlite3:database>"
     63         (p "Opens the indicated database file and returns a " (tt "<sqlite3:database>") " object for it.")
     64         (p "The given path is subject to the same special expansion as paths passed to " (p "open-input-file") " and similar procedures."))
     65        (definition
     66          (signatures
     67           (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>)) => <void>")
     68           (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>) (proc <procedure-class>)) => <void>"))
     69          (p "If " (tt "proc") " is given, registers a new collation sequence identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If no procedure is passed, the collation sequence with the given name is removed.")
     70          (p (tt "proc") " should have the signature " (tt "(proc (a <string>) (b <string>)) => <exact>") ". It should return a negative number if " (tt "a") " sorts before " (tt "b") ", a positive number if " (tt "b") " sorts before " (tt "a") " and zero if " (tt "a") " and " (tt "b") " are equal.")
     71          (p "As " (tt "proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a " (tt "0") " return value and warning messages."))
     72        (definition
     73          (signatures
     74           (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (proc <procedure-class>)) => <void>")
     75           (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (step-proc <procedure-class>) (seed <top>) #!optional ((final-proc <procedure-class>) identity)) => <void>"))
     76          (p "If " (tt "proc") " is given, registers a new SQL function identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If " (tt "step-proc") " and " (tt "final-proc") " are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.")
     77          (p (tt "n") " is the number of parameters the new SQL function takes or " (tt "-1") " to allow any number of arguments.")
     78          (p (tt "proc") " should have the signature " (tt "(proc . params) => <top>") ". It is called with the " (tt "n") " parameters given to the SQL function converted into Scheme objects like by " (tt "sqlite3:column-data") ". The return value is converted into an SQLite3 data object like by " (tt "sqlite3:bind!") ". A return value of " (tt "(void)") " corresponds to " (tt "NULL") " in SQLite3.")
     79          (p (tt "step-proc") " should have the signature " (tt "(step-proc (seed <top>) . params) => <top>") ". It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to " (tt "sqlite3:define-function") "; for subsequent calls it is the last value returned by " (tt "step-proc") " and after completion of " (tt "final-proc") " it will be the initial value again.")
     80          (p (tt "final-proc") " should have the signature " (tt "(final-proc (seed <top>)) => <top>") " and transforms the last seed value into the value to be returned from the aggregate function.")
     81          (p "As " (tt "proc") ", " (tt "step-proc") " and " (tt "final-proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in " (tt "NULL") " return values and warning messages."))
     82        (procedure
     83         "(sqlite3:set-busy-timeout! (db <sqlite3:database>) #!optional ((ms <exact>) 0)) => <void>"
     84         (p "Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If " (tt "(<= ms 0)") " though, all busy handlers for the database are uninstalled."))
     85        (procedure
     86         "(sqlite3:interrupt! (db <sqlite3:database>)) => <void>"
     87         (p "Cancels any running database operation as soon as possible.")
     88         (p "This function is always successful and never throws an exception."))
     89        (procedure
     90         "(sqlite3:auto-committing? (db <sqlite3:database>)) => <bool>"
     91         (p "Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.")
     92         (p "This function always returns a state and never throws an exception."))
     93        (procedure
     94         "(sqlite3:changes (db <sqlite3:database>) #!optional ((total <bool>) #f)) => <number>"
     95         (p "Returns the number of rows changed by the last statement (if " (tt "(not total)") ") or since the database was opened (if " (tt "total") ").")
     96         (p "This function always returns a count and never throws an exception."))
     97        (procedure
     98         "(sqlite3:last-insert-rowid (db <sqlite3:database>)) => <number>"
     99         (p "Returns the row ID of the last row inserted in " (tt "db") ".")
     100         (p "This function always returns a number and never throws an exception."))
     101        (method
     102         "(sqlite3:finalize! (db <sqlite3:database>)) => <void>"
     103         (p "Closes the given database."))))
     104
     105      (subsection
     106       "Managing statements"
     107       (group
     108        (procedure
     109         "(sqlite3:prepare (db <sqlite3:database>) (sql <string>)) => <sqlite3:statement>, <string>"
     110         (p "Compiles the first SQL statement in " (tt "sql") " and returns a " (tt "<sqlite3:statement>") " and the rest of " (tt "sql") ", which was not compiled (or an empty string)."))
     111        (procedure
     112         "(sqlite3:repair! (stmt <sqlite3:statement>)) => <void>"
     113         (p "Recompiles the SQL statement used to create " (tt "stmt") ", transfers all existing bindings from the old statement handle to the new one and destructively modifies " (tt "stmt") " to point to the new statement handle.")
     114         (p "If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.")
     115         (p "Usually you should not have to call this routine by hand. It is invoked by " (tt "sqlite3:step!") " to automagically repair a stale statement handle after a database schema change."))
     116        (procedure
     117         "(sqlite3:column-count (stmt <sqlite3:statement>)) => <exact>"
     118         (p "Can be applied to any statement and returns the number of columns it will return as results.")
     119         (p "This procedure always succeeds and never throws an exception."))
     120        (procedure
     121         "(sqlite3:column-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     122         (p "Can be applied to any statement and returns the name of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no name.")
     123         (p "This procedure always succeeds and never throws an exception."))
     124        (procedure
     125         "(sqlite3:column-declared-type (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     126         (p "Can be applied to any statement and returns the declared type (as given in the " (tt "CREATE") " statement) of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no declared type.")
     127         (p "This procedure always succeeds and never throws an exception."))
     128        (procedure
     129         "(sqlite3:bind-parameter-count (stmt <sqlite3:statement>)) => <exact>"
     130         (p "Can be applied to any statement and returns the number of free parameters that can be bound in the statement.")
     131         (p "This procedure always succeeds and never throws an exception."))
     132        (procedure
     133         "(sqlite3:bind-parameter-index (stmt <sqlite3:statement>) (name <string>)) => <exact>"
     134         (p "Can be applied to any statement and returns the index of the bindable parameter called " (tt "name") " or " (tt "#f") " if no such parameter exists.")
     135         (p "This procedure always succeeds and never throws an exception."))
     136        (procedure
     137         "(sqlite3:bind-parameter-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     138         (p "Can be applied to any statement and returns the name of the bindable parameter number " (tt "i") " (counting from 0) or " (tt "#f") " if no such parameter exists or the parameter has no name.")
     139         (p "This procedure always succeeds and never throws an exception."))
     140        (definition
     141          (signatures
     142           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)) => <void>")
     143           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <void>)) => <void>")
     144           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <exact>)) => <void>")
     145           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <number>)) => <void>")
     146           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <string>)) => <void>")
     147           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <byte-vector>)) => <void>"))
     148          (p "Can be applied to any statement to bind its free parameter number " (tt "i") " (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:"
     149             (table
     150              (tr (th "Scheme type") (th "SQLite type"))
     151              (tr (td "none") (td (tt "null")))
     152              (tr (td (tt "<sqlite3:null-value>")) (td (tt "null")))
     153              (tr (td (tt "<exact>")) (td (tt "integer")))
     154              (tr (td (tt "<number>")) (td (tt "float")))
     155              (tr (td (tt "<string>")) (td (tt "text")))
     156              (tr (td (tt "<byte-vector>")) (td (tt "blob")))))
     157          (p "Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing."))
     158        (procedure
     159         "(sqlite3:step! (stmt <sqlite3:statement>)) => <boolean>"
     160         (p "Single-steps the execution of " (tt "stmt") " and returns " (tt "#t") " if a result row was produced, " (tt "#f") " if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement."))
     161        (procedure
     162         "(sqlite3:column-type (stmt <sqlite3:statement>) (i <exact>)) => <symbol>"
     163         (p "Can be applied to a statement that has just been stepped (otherwise it returns " (tt "#f") ") and returns the SQLite type of the result column number " (tt "i") " (counting from 0) as a symbol.")
     164         (p "The return value can be one of the symbols " (tt "null") ", " (tt "integer") ", " (tt "float") ", " (tt "text") " or " (tt "blob") ".")
     165         (p "This procedure always succeeds and never throws an exception."))
     166        (procedure
     167         "(sqlite3:column-data (stmt <sqlite3:statement>) (i <exact>)) => <void | exact | number | string | byte-vector>"
     168         (p "Can be applied to a statement that has just been stepped. Consults " (tt "sqlite3:column-type") " to determine the type of the indicated column and to return its data as an appropriate scheme object.")
     169         (p "See " (tt "sqlite3:bind!") " for the mapping between Scheme and SQLite data types. Columns of type " (tt "null") " are returned as " (tt "<sqlite3:null-value>") ". Also keep in mind that CHICKEN's " (tt "<exact>") " datatype can only hold a subset of the values an SQLite " (tt "integer") " can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class " (tt "<integer>") ".")
     170         (p "This procedure always succeeds and never throws an exception."))
     171        (procedure
     172         "(sqlite3:reset! (stmt <sqlite3:statement>)) => <void>"
     173         (p "Can be applied to any statement and resets it such that execution using " (tt "sqlite3:step!") " will perform all operations of the statement again."))
     174        (method
     175         "(sqlite3:finalize! (stmt <sqlite3:statement>)) => <void>"
     176         (p "Must be applied to every statement to free its resources and discard it.")
     177         (p (tt "sqlite3:close") " will not be able to close a database that has associated unfinalized statements."))))
     178
     179      (subsection
     180       "Simple statement interface"
     181       (group
     182        (procedure
     183         "(sqlite3:call-with-temporary-statements (proc <procedure-class>) (db <sqlite3:database>) . sqls) => <top>"
     184         (p "Compiles the SQL sources in " (tt "sqls") " into statements in the context of " (tt "db") ", applies " (tt "proc") " to these statements and returns " (tt "proc") "'s result. The statements are created and finalized in " (tt "dynamic-wind") " entry and exit blocks around the application of " (tt "proc") "."))
     185        (definition
     186          (signatures
     187           (signature "method" "(sqlite3:exec (stmt <sqlite3:statement>) . params) => <void>")
     188           (signature "method" "(sqlite3:exec (db <sqlite3:database>) (sql <string>) . params) => <void>"))
     189          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it."))
     190        (definition
     191          (signatures
     192           (signature "method" "(sqlite3:update (stmt <sqlite3:statement>) . params) => <exact>")
     193           (signature "method" "(sqlite3:update (db <sqlite3:database>) (sql <string>) . params) => <exact>"))
     194          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying " (tt "sqlite3:changes") " to the affected database after the execution of the statement instead."))
     195        (definition
     196          (signatures
     197           (signature "method" "(sqlite3:first-result (stmt <sqlite3:statement>) . params) => <void | exact | number | string | byte-vector>")
     198           (signature "method" "(sqlite3:first-result (db <sqlite3:database>) (sql <string>) . params) => <void | exact | number | string | byte-vector>"))
     199          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.")
     200          (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
     201        (definition
     202          (signatures
     203           (signature "method" "(sqlite3:first-row (stmt <sqlite3:statement>) . params) => <list>")
     204           (signature "method" "(sqlite3:first-row (db <sqlite3:database>) (sql <string>) . params) => <list>"))
     205          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.")
     206          (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
     207        (definition
     208          (signatures
     209           (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <void>")
     210           (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <void>"))
     211          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of this application are discarded."))
     212        (definition
     213          (signatures
     214           (signature "method" "(sqlite3:map-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <list>")
     215           (signature "method" "(sqlite3:map-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <list>"))
     216          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of these applications are collected into a list."))))
     217
     218      (subsection
     219       "Utility functions"
     220       (group
     221        (procedure
     222         "(sqlite3:with-transaction (db <sqlite3:database>) (thunk <procedure-class>) #!optional ((type <symbol>) 'deferred)) => <void>"
     223         (p "Runs " (tt "thunk") " within the scope of a transaction on the dataase " (tt "db") ".")
     224         (p "The transaction is committed upon exit from " (tt "thunk") " if " (tt "thunk") " returns a true value. If " (tt "thunk") " returns a false value or throws an exception, the transaction is rolled back.")
     225         (p "The " (tt "type") " of the transaction can be specified as one of the symbols " (tt "deferred") ", " (tt "immediate") " or " (tt "exclusive") "."))
     226        (procedure
     227         "(sqlite3:complete? (sql <string>)) => <boolean>"
     228         (p "Checks whether " (tt "sql") " comprises at least one complete SQL statement."))
     229        (procedure
     230         "(sqlite3:library-version) => <string>"
     231         (p "Returns a string identifying the version of SQLite in use."))
     232        (procedure
     233         "(sqlite3:null-value? <object>) => <boolean>"
     234         (p "Is the " (tt "<object>") " a <sqlite3:null-value>?")
     235         (p "The <sqlite3:null-value> is compatible with the \"sql-null\" egg. "
     236            "The default \"sql-null\" egg function " (code "(sql-null)") " "
     237            "= the <sqlite3:null-value>. "
     238            "But to ensure equality - " (code "(define sql-null sqlite3:null)") ".")))))
     239
    8240     (history
     241      (version "2.0.3" "Added " (code "sqlite3:null-value") ", " (code "sqlite3:null-value?") ", and " (code "sqlite3:null") ". [Kon Lovett]")
    9242      (version "2.0.2" "Use of extended " (tt "define-foreign-enum") ". Removed deprecated " (tt "pointer") " use. [Kon Lovett]")
    10243      (version "2.0.1" "Deprecated " (tt "<byte-vector>") ", use " (tt "<blob>") " [Kon Lovett]")
     
    33266      (version "1.0.1" "Fixed type mistakes in the source")
    34267      (version "1.0.0" "Initial release"))
    35      
    36      (usage)
    37      (download "sqlite3.egg")
    38      (requires "synch")
    39      
    40      (documentation
    41       (p "The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.")
    42       (p "For in-depth information on the functionality of the routines and general information you should consult the " (url "http://www.sqlite.org/" "SQLite documentation") " as well as this manual.")
    43       (p "Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind " (tt "(exn sqlite3)") " if something goes wrong. This exception will contain a " (tt "status") " property indicating the return value of the operation that failed:"
    44          (table
    45           (tr (th "Symbol") (th "Meaning"))
    46           ;; (tr (td (tt "ok")) (td "Successful result"))
    47           (tr (td (tt "error")) (td "SQL error or missing database "))
    48           (tr (td (tt "internal")) (td "An internal logic error in SQLite "))
    49           (tr (td (tt "permission")) (td "Access permission denied "))
    50           (tr (td (tt "abort")) (td "Callback routine requested an abort "))
    51           (tr (td (tt "busy")) (td "The database file is locked "))
    52           (tr (td (tt "locked")) (td "A table in the database is locked "))
    53           (tr (td (tt "no-memory")) (td "A malloc() failed "))
    54           (tr (td (tt "read-only")) (td "Attempt to write a readonly database "))
    55           (tr (td (tt "interrupt")) (td "Operation terminated by sqlite-interrupt() "))
    56           (tr (td (tt "io-error")) (td "Some kind of disk I/O error occurred "))
    57           (tr (td (tt "corrupt")) (td "The database disk image is malformed "))
    58           (tr (td (tt "not-found")) (td "(Internal Only) Table or record not found "))
    59           (tr (td (tt "full")) (td "Insertion failed because database is full "))
    60           (tr (td (tt "cant-open")) (td "Unable to open the database file "))
    61           (tr (td (tt "protocol")) (td "Database lock protocol error "))
    62           (tr (td (tt "empty")) (td "(Internal Only) Database table is empty "))
    63           (tr (td (tt "schema")) (td "The database schema changed "))
    64           (tr (td (tt "too-big")) (td "Too much data for one row of a table "))
    65           (tr (td (tt "constraint")) (td "Abort due to contraint violation "))
    66           (tr (td (tt "mismatch")) (td "Data type mismatch "))
    67           (tr (td (tt "misuse")) (td "Library used incorrectly "))
    68           (tr (td (tt "no-lfs")) (td "Uses OS features not supported on host "))
    69           (tr (td (tt "authorization")) (td " Authorization denied"))
    70           ;;(tr (td (tt "row")) (td (tt "sqlite3:step!") " has another row ready "))
    71           (tr (td (tt "done")) (td (tt "sqlite3:step!") " has finished executing, so no further data is ready"))
    72           ))
    73          
    74       (subsection
    75        "Classes"
    76        (group
    77         (definition
    78           (signatures
    79            (signature "class" "<sqlite3:database>")
    80            (signature "class" "<sqlite3:statement>"))
    81           (p "These classes are derived from " (tt "<c++-object>") ". They hold a pointer to the underlying C-structure in their " (tt "this") " slot.")
    82           (p (tt "<sqlite3:statement>") " also has a " (tt "database") " slot pointing to the database object it belongs to."))))
    83      
    84       (subsection
    85        "Managing databases"
    86        (group
    87         (procedure
    88          "(sqlite3:open (path <string>)) => <sqlite3:database>"
    89          (p "Opens the indicated database file and returns a " (tt "<sqlite3:database>") " object for it.")
    90          (p "The given path is subject to the same special expansion as paths passed to " (p "open-input-file") " and similar procedures."))
    91         (definition
    92           (signatures
    93            (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>)) => <void>")
    94            (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>) (proc <procedure-class>)) => <void>"))
    95           (p "If " (tt "proc") " is given, registers a new collation sequence identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If no procedure is passed, the collation sequence with the given name is removed.")
    96           (p (tt "proc") " should have the signature " (tt "(proc (a <string>) (b <string>)) => <exact>") ". It should return a negative number if " (tt "a") " sorts before " (tt "b") ", a positive number if " (tt "b") " sorts before " (tt "a") " and zero if " (tt "a") " and " (tt "b") " are equal.")
    97           (p "As " (tt "proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a " (tt "0") " return value and warning messages."))
    98         (definition
    99           (signatures
    100            (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (proc <procedure-class>)) => <void>")
    101            (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (step-proc <procedure-class>) (seed <top>) #!optional ((final-proc <procedure-class>) identity)) => <void>"))
    102           (p "If " (tt "proc") " is given, registers a new SQL function identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If " (tt "step-proc") " and " (tt "final-proc") " are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.")
    103           (p (tt "n") " is the number of parameters the new SQL function takes or " (tt "-1") " to allow any number of arguments.")
    104           (p (tt "proc") " should have the signature " (tt "(proc . params) => <top>") ". It is called with the " (tt "n") " parameters given to the SQL function converted into Scheme objects like by " (tt "sqlite3:column-data") ". The return value is converted into an SQLite3 data object like by " (tt "sqlite3:bind!") ". A return value of " (tt "(void)") " corresponds to " (tt "NULL") " in SQLite3.")
    105           (p (tt "step-proc") " should have the signature " (tt "(step-proc (seed <top>) . params) => <top>") ". It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to " (tt "sqlite3:define-function") "; for subsequent calls it is the last value returned by " (tt "step-proc") " and after completion of " (tt "final-proc") " it will be the initial value again.")
    106           (p (tt "final-proc") " should have the signature " (tt "(final-proc (seed <top>)) => <top>") " and transforms the last seed value into the value to be returned from the aggregate function.")
    107           (p "As " (tt "proc") ", " (tt "step-proc") " and " (tt "final-proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in " (tt "NULL") " return values and warning messages."))
    108         (procedure
    109          "(sqlite3:set-busy-timeout! (db <sqlite3:database>) #!optional ((ms <exact>) 0)) => <void>"
    110          (p "Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If " (tt "(<= ms 0)") " though, all busy handlers for the database are uninstalled."))
    111         (procedure
    112          "(sqlite3:interrupt! (db <sqlite3:database>)) => <void>"
    113          (p "Cancels any running database operation as soon as possible.")
    114          (p "This function is always successful and never throws an exception."))
    115         (procedure
    116          "(sqlite3:auto-committing? (db <sqlite3:database>)) => <bool>"
    117          (p "Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.")
    118          (p "This function always returns a state and never throws an exception."))
    119         (procedure
    120          "(sqlite3:changes (db <sqlite3:database>) #!optional ((total <bool>) #f)) => <number>"
    121          (p "Returns the number of rows changed by the last statement (if " (tt "(not total)") ") or since the database was opened (if " (tt "total") ").")
    122          (p "This function always returns a count and never throws an exception."))
    123         (procedure
    124          "(sqlite3:last-insert-rowid (db <sqlite3:database>)) => <number>"
    125          (p "Returns the row ID of the last row inserted in " (tt "db") ".")
    126          (p "This function always returns a number and never throws an exception."))
    127         (method
    128          "(sqlite3:finalize! (db <sqlite3:database>)) => <void>"
    129          (p "Closes the given database."))))
    130      
    131       (subsection
    132        "Managing statements"
    133        (group
    134         (procedure
    135          "(sqlite3:prepare (db <sqlite3:database>) (sql <string>)) => <sqlite3:statement>, <string>"
    136          (p "Compiles the first SQL statement in " (tt "sql") " and returns a " (tt "<sqlite3:statement>") " and the rest of " (tt "sql") ", which was not compiled (or an empty string)."))
    137         (procedure
    138          "(sqlite3:repair! (stmt <sqlite3:statement>)) => <void>"
    139          (p "Recompiles the SQL statement used to create " (tt "stmt") ", transfers all existing bindings from the old statement handle to the new one and destructively modifies " (tt "stmt") " to point to the new statement handle.")
    140          (p "If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.")
    141          (p "Usually you should not have to call this routine by hand. It is invoked by " (tt "sqlite3:step!") " to automagically repair a stale statement handle after a database schema change."))
    142         (procedure
    143          "(sqlite3:column-count (stmt <sqlite3:statement>)) => <exact>"
    144          (p "Can be applied to any statement and returns the number of columns it will return as results.")
    145          (p "This procedure always succeeds and never throws an exception."))
    146         (procedure
    147          "(sqlite3:column-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    148          (p "Can be applied to any statement and returns the name of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no name.")
    149          (p "This procedure always succeeds and never throws an exception."))
    150         (procedure
    151          "(sqlite3:column-declared-type (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    152          (p "Can be applied to any statement and returns the declared type (as given in the " (tt "CREATE") " statement) of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no declared type.")
    153          (p "This procedure always succeeds and never throws an exception."))
    154         (procedure
    155          "(sqlite3:bind-parameter-count (stmt <sqlite3:statement>)) => <exact>"
    156          (p "Can be applied to any statement and returns the number of free parameters that can be bound in the statement.")
    157          (p "This procedure always succeeds and never throws an exception."))
    158         (procedure
    159          "(sqlite3:bind-parameter-index (stmt <sqlite3:statement>) (name <string>)) => <exact>"
    160          (p "Can be applied to any statement and returns the index of the bindable parameter called " (tt "name") " or " (tt "#f") " if no such parameter exists.")
    161          (p "This procedure always succeeds and never throws an exception."))
    162         (procedure
    163          "(sqlite3:bind-parameter-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    164          (p "Can be applied to any statement and returns the name of the bindable parameter number " (tt "i") " (counting from 0) or " (tt "#f") " if no such parameter exists or the parameter has no name.")
    165          (p "This procedure always succeeds and never throws an exception."))
    166         (definition
    167           (signatures
    168            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)) => <void>")
    169            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <void>)) => <void>")
    170            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <exact>)) => <void>")
    171            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <number>)) => <void>")
    172            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <string>)) => <void>")
    173            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <byte-vector>)) => <void>"))
    174           (p "Can be applied to any statement to bind its free parameter number " (tt "i") " (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:"
    175              (table
    176               (tr (th "Scheme type") (th "SQLite type"))
    177               (tr (td "none") (td (tt "null")))
    178               (tr (td (tt "<void>")) (td (tt "null")))
    179               (tr (td (tt "<exact>")) (td (tt "integer")))
    180               (tr (td (tt "<number>")) (td (tt "float")))
    181               (tr (td (tt "<string>")) (td (tt "text")))
    182               (tr (td (tt "<byte-vector>")) (td (tt "blob")))))
    183           (p "Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing."))
    184         (procedure
    185          "(sqlite3:step! (stmt <sqlite3:statement>)) => <boolean>"
    186          (p "Single-steps the execution of " (tt "stmt") " and returns " (tt "#t") " if a result row was produced, " (tt "#f") " if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement."))
    187         (procedure
    188          "(sqlite3:column-type (stmt <sqlite3:statement>) (i <exact>)) => <symbol>"
    189          (p "Can be applied to a statement that has just been stepped (otherwise it returns " (tt "#f") ") and returns the SQLite type of the result column number " (tt "i") " (counting from 0) as a symbol.")
    190          (p "The return value can be one of the symbols " (tt "null") ", " (tt "integer") ", " (tt "float") ", " (tt "text") " or " (tt "blob") ".")
    191          (p "This procedure always succeeds and never throws an exception."))
    192         (procedure
    193          "(sqlite3:column-data (stmt <sqlite3:statement>) (i <exact>)) => <void | exact | number | string | byte-vector>"
    194          (p "Can be applied to a statement that has just been stepped. Consults " (tt "sqlite3:column-type") " to determine the type of the indicated column and to return its data as an appropriate scheme object.")
    195          (p "See " (tt "sqlite3:bind!") " for the mapping between Scheme and SQLite data types. Columns of type " (tt "null") " are returned as " (tt "(void)") ". Also keep in mind that CHICKEN's " (tt "<exact>") " datatype can only hold a subset of the values an SQLite " (tt "integer") " can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class " (tt "<integer>") ".")
    196          (p "This procedure always succeeds and never throws an exception."))
    197         (procedure
    198          "(sqlite3:reset! (stmt <sqlite3:statement>)) => <void>"
    199          (p "Can be applied to any statement and resets it such that execution using " (tt "sqlite3:step!") " will perform all operations of the statement again."))
    200         (method
    201          "(sqlite3:finalize! (stmt <sqlite3:statement>)) => <void>"
    202          (p "Must be applied to every statement to free its resources and discard it.")
    203          (p (tt "sqlite3:close") " will not be able to close a database that has associated unfinalized statements."))))
    204 
    205       (subsection
    206        "Simple statement interface"
    207        (group
    208         (procedure
    209          "(sqlite3:call-with-temporary-statements (proc <procedure-class>) (db <sqlite3:database>) . sqls) => <top>"
    210          (p "Compiles the SQL sources in " (tt "sqls") " into statements in the context of " (tt "db") ", applies " (tt "proc") " to these statements and returns " (tt "proc") "'s result. The statements are created and finalized in " (tt "dynamic-wind") " entry and exit blocks around the application of " (tt "proc") "."))
    211         (definition
    212           (signatures
    213            (signature "method" "(sqlite3:exec (stmt <sqlite3:statement>) . params) => <void>")
    214            (signature "method" "(sqlite3:exec (db <sqlite3:database>) (sql <string>) . params) => <void>"))
    215           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it."))
    216         (definition
    217           (signatures
    218            (signature "method" "(sqlite3:update (stmt <sqlite3:statement>) . params) => <exact>")
    219            (signature "method" "(sqlite3:update (db <sqlite3:database>) (sql <string>) . params) => <exact>"))
    220           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying " (tt "sqlite3:changes") " to the affected database after the execution of the statement instead."))
    221         (definition
    222           (signatures
    223            (signature "method" "(sqlite3:first-result (stmt <sqlite3:statement>) . params) => <void | exact | number | string | byte-vector>")
    224            (signature "method" "(sqlite3:first-result (db <sqlite3:database>) (sql <string>) . params) => <void | exact | number | string | byte-vector>"))
    225           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.")
    226           (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
    227         (definition
    228           (signatures
    229            (signature "method" "(sqlite3:first-row (stmt <sqlite3:statement>) . params) => <list>")
    230            (signature "method" "(sqlite3:first-row (db <sqlite3:database>) (sql <string>) . params) => <list>"))
    231           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.")
    232           (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
    233         (definition
    234           (signatures
    235            (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <void>")
    236            (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <void>"))
    237           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of this application are discarded."))
    238         (definition
    239           (signatures
    240            (signature "method" "(sqlite3:map-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <list>")
    241            (signature "method" "(sqlite3:map-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <list>"))
    242           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of these applications are collected into a list."))))
    243 
    244       (subsection
    245        "Utility functions"
    246        (group
    247         (procedure
    248          "(sqlite3:with-transaction (db <sqlite3:database>) (thunk <procedure-class>) #!optional ((type <symbol>) 'deferred)) => <void>"
    249          (p "Runs " (tt "thunk") " within the scope of a transaction on the dataase " (tt "db") ".")
    250          (p "The transaction is committed upon exit from " (tt "thunk") " if " (tt "thunk") " returns a true value. If " (tt "thunk") " returns a false value or throws an exception, the transaction is rolled back.")
    251          (p "The " (tt "type") " of the transaction can be specified as one of the symbols " (tt "deferred") ", " (tt "immediate") " or " (tt "exclusive") "."))
    252         (procedure
    253          "(sqlite3:complete? (sql <string>)) => <boolean>"
    254          (p "Checks whether " (tt "sql") " comprises at least one complete SQL statement."))
    255         (procedure
    256          "(sqlite3:library-version) => <string>"
    257          (p "Returns a string identifying the version of SQLite in use.")))))
    258      
     268
    259269      (license
    260270       "Copyright (c) 2005, Thomas Chust <chust@web.de>.  All rights reserved.
  • release/3/sqlite3/tags/2.0.3/sqlite3.html

    r6115 r7981  
    156156<h3>Author</h3><a href="http://www.chust.org/">Thomas Chust</a></div>
    157157<div class="section">
     158<h3>Usage</h3><tt>(require-extension sqlite3)</tt></div>
     159<div class="section">
     160<h3>Download</h3><a href="sqlite3.egg">sqlite3.egg</a></div>
     161<div class="section">
     162<h3>Requires</h3>
     163<ul>
     164<li>synch</li>
     165<li>tinyclos</li>
     166<li>easyffi</li></ul></div>
     167<div class="section">
     168<h3>Documentation</h3>
     169<p>The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.</p>
     170<p>For in-depth information on the functionality of the routines and general information you should consult the <a href="http://www.sqlite.org/">SQLite documentation</a> as well as this manual.</p>
     171<div class="subsection">
     172<h4>Exceptions</h4>
     173<p>Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind <tt>(exn sqlite3)</tt> if something goes wrong. This exception will contain a <tt>status</tt> property indicating the return value of the operation that failed:
     174<table>
     175<tr>
     176<th>Symbol</th>
     177<th>Meaning</th></tr>
     178<tr>
     179<td><tt>error</tt></td>
     180<td>SQL error or missing database </td></tr>
     181<tr>
     182<td><tt>internal</tt></td>
     183<td>An internal logic error in SQLite </td></tr>
     184<tr>
     185<td><tt>permission</tt></td>
     186<td>Access permission denied </td></tr>
     187<tr>
     188<td><tt>abort</tt></td>
     189<td>Callback routine requested an abort </td></tr>
     190<tr>
     191<td><tt>busy</tt></td>
     192<td>The database file is locked </td></tr>
     193<tr>
     194<td><tt>locked</tt></td>
     195<td>A table in the database is locked </td></tr>
     196<tr>
     197<td><tt>no-memory</tt></td>
     198<td>A malloc() failed </td></tr>
     199<tr>
     200<td><tt>read-only</tt></td>
     201<td>Attempt to write a readonly database </td></tr>
     202<tr>
     203<td><tt>interrupt</tt></td>
     204<td>Operation terminated by sqlite-interrupt() </td></tr>
     205<tr>
     206<td><tt>io-error</tt></td>
     207<td>Some kind of disk I/O error occurred </td></tr>
     208<tr>
     209<td><tt>corrupt</tt></td>
     210<td>The database disk image is malformed </td></tr>
     211<tr>
     212<td><tt>not-found</tt></td>
     213<td>(Internal Only) Table or record not found </td></tr>
     214<tr>
     215<td><tt>full</tt></td>
     216<td>Insertion failed because database is full </td></tr>
     217<tr>
     218<td><tt>cant-open</tt></td>
     219<td>Unable to open the database file </td></tr>
     220<tr>
     221<td><tt>protocol</tt></td>
     222<td>Database lock protocol error </td></tr>
     223<tr>
     224<td><tt>empty</tt></td>
     225<td>(Internal Only) Database table is empty </td></tr>
     226<tr>
     227<td><tt>schema</tt></td>
     228<td>The database schema changed </td></tr>
     229<tr>
     230<td><tt>too-big</tt></td>
     231<td>Too much data for one row of a table </td></tr>
     232<tr>
     233<td><tt>constraint</tt></td>
     234<td>Abort due to contraint violation </td></tr>
     235<tr>
     236<td><tt>mismatch</tt></td>
     237<td>Data type mismatch </td></tr>
     238<tr>
     239<td><tt>misuse</tt></td>
     240<td>Library used incorrectly </td></tr>
     241<tr>
     242<td><tt>no-lfs</tt></td>
     243<td>Uses OS features not supported on host </td></tr>
     244<tr>
     245<td><tt>authorization</tt></td>
     246<td> Authorization denied</td></tr>
     247<tr>
     248<td><tt>done</tt></td>
     249<td><tt>sqlite3:step!</tt> has finished executing, so no further data is ready</td></tr></table></p></div>
     250<div class="subsection">
     251<h4>Classes</h4>
     252<dl>
     253<dt class="definition"><strong>class:</strong> &lt;sqlite3:database&gt;
     254<br /><strong>class:</strong> &lt;sqlite3:statement&gt;</dt>
     255<dd>
     256<p>These classes are derived from <tt>&lt;c++-object&gt;</tt>. They hold a pointer to the underlying C-structure in their <tt>this</tt> slot.</p>
     257<p><tt>&lt;sqlite3:statement&gt;</tt> also has a <tt>database</tt> slot pointing to the database object it belongs to.</p></dd></dl></div>
     258<div class="subsection">
     259<h4>Managing databases</h4>
     260<dl>
     261<dt class="definition"><strong>procedure:</strong> (sqlite3:open (path &lt;string&gt;)) =&gt; &lt;sqlite3:database&gt;</dt>
     262<dd>
     263<p>Opens the indicated database file and returns a <tt>&lt;sqlite3:database&gt;</tt> object for it.</p>
     264<p>The given path is subject to the same special expansion as paths passed to
     265<p>open-input-file</p> and similar procedures.</p></dd>
     266<dt class="definition"><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;)) =&gt; &lt;void&gt;
     267<br /><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;</dt>
     268<dd>
     269<p>If <tt>proc</tt> is given, registers a new collation sequence identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If no procedure is passed, the collation sequence with the given name is removed.</p>
     270<p><tt>proc</tt> should have the signature <tt>(proc (a &lt;string&gt;) (b &lt;string&gt;)) =&gt; &lt;exact&gt;</tt>. It should return a negative number if <tt>a</tt> sorts before <tt>b</tt>, a positive number if <tt>b</tt> sorts before <tt>a</tt> and zero if <tt>a</tt> and <tt>b</tt> are equal.</p>
     271<p>As <tt>proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a <tt>0</tt> return value and warning messages.</p></dd>
     272<dt class="definition"><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;
     273<br /><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (step-proc &lt;procedure-class&gt;) (seed &lt;top&gt;) #!optional ((final-proc &lt;procedure-class&gt;) identity)) =&gt; &lt;void&gt;</dt>
     274<dd>
     275<p>If <tt>proc</tt> is given, registers a new SQL function identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If <tt>step-proc</tt> and <tt>final-proc</tt> are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.</p>
     276<p><tt>n</tt> is the number of parameters the new SQL function takes or <tt>-1</tt> to allow any number of arguments.</p>
     277<p><tt>proc</tt> should have the signature <tt>(proc . params) =&gt; &lt;top&gt;</tt>. It is called with the <tt>n</tt> parameters given to the SQL function converted into Scheme objects like by <tt>sqlite3:column-data</tt>. The return value is converted into an SQLite3 data object like by <tt>sqlite3:bind!</tt>. A return value of <tt>(void)</tt> corresponds to <tt>NULL</tt> in SQLite3.</p>
     278<p><tt>step-proc</tt> should have the signature <tt>(step-proc (seed &lt;top&gt;) . params) =&gt; &lt;top&gt;</tt>. It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to <tt>sqlite3:define-function</tt>; for subsequent calls it is the last value returned by <tt>step-proc</tt> and after completion of <tt>final-proc</tt> it will be the initial value again.</p>
     279<p><tt>final-proc</tt> should have the signature <tt>(final-proc (seed &lt;top&gt;)) =&gt; &lt;top&gt;</tt> and transforms the last seed value into the value to be returned from the aggregate function.</p>
     280<p>As <tt>proc</tt>, <tt>step-proc</tt> and <tt>final-proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in <tt>NULL</tt> return values and warning messages.</p></dd>
     281<dt class="definition"><strong>procedure:</strong> (sqlite3:set-busy-timeout! (db &lt;sqlite3:database&gt;) #!optional ((ms &lt;exact&gt;) 0)) =&gt; &lt;void&gt;</dt>
     282<dd>
     283<p>Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If <tt>(&lt;= ms 0)</tt> though, all busy handlers for the database are uninstalled.</p></dd>
     284<dt class="definition"><strong>procedure:</strong> (sqlite3:interrupt! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
     285<dd>
     286<p>Cancels any running database operation as soon as possible.</p>
     287<p>This function is always successful and never throws an exception.</p></dd>
     288<dt class="definition"><strong>procedure:</strong> (sqlite3:auto-committing? (db &lt;sqlite3:database&gt;)) =&gt; &lt;bool&gt;</dt>
     289<dd>
     290<p>Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.</p>
     291<p>This function always returns a state and never throws an exception.</p></dd>
     292<dt class="definition"><strong>procedure:</strong> (sqlite3:changes (db &lt;sqlite3:database&gt;) #!optional ((total &lt;bool&gt;) #f)) =&gt; &lt;number&gt;</dt>
     293<dd>
     294<p>Returns the number of rows changed by the last statement (if <tt>(not total)</tt>) or since the database was opened (if <tt>total</tt>).</p>
     295<p>This function always returns a count and never throws an exception.</p></dd>
     296<dt class="definition"><strong>procedure:</strong> (sqlite3:last-insert-rowid (db &lt;sqlite3:database&gt;)) =&gt; &lt;number&gt;</dt>
     297<dd>
     298<p>Returns the row ID of the last row inserted in <tt>db</tt>.</p>
     299<p>This function always returns a number and never throws an exception.</p></dd>
     300<dt class="definition"><strong>method:</strong> (sqlite3:finalize! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
     301<dd>
     302<p>Closes the given database.</p></dd></dl></div>
     303<div class="subsection">
     304<h4>Managing statements</h4>
     305<dl>
     306<dt class="definition"><strong>procedure:</strong> (sqlite3:prepare (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;)) =&gt; &lt;sqlite3:statement&gt;, &lt;string&gt;</dt>
     307<dd>
     308<p>Compiles the first SQL statement in <tt>sql</tt> and returns a <tt>&lt;sqlite3:statement&gt;</tt> and the rest of <tt>sql</tt>, which was not compiled (or an empty string).</p></dd>
     309<dt class="definition"><strong>procedure:</strong> (sqlite3:repair! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     310<dd>
     311<p>Recompiles the SQL statement used to create <tt>stmt</tt>, transfers all existing bindings from the old statement handle to the new one and destructively modifies <tt>stmt</tt> to point to the new statement handle.</p>
     312<p>If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.</p>
     313<p>Usually you should not have to call this routine by hand. It is invoked by <tt>sqlite3:step!</tt> to automagically repair a stale statement handle after a database schema change.</p></dd>
     314<dt class="definition"><strong>procedure:</strong> (sqlite3:column-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
     315<dd>
     316<p>Can be applied to any statement and returns the number of columns it will return as results.</p>
     317<p>This procedure always succeeds and never throws an exception.</p></dd>
     318<dt class="definition"><strong>procedure:</strong> (sqlite3:column-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     319<dd>
     320<p>Can be applied to any statement and returns the name of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no name.</p>
     321<p>This procedure always succeeds and never throws an exception.</p></dd>
     322<dt class="definition"><strong>procedure:</strong> (sqlite3:column-declared-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     323<dd>
     324<p>Can be applied to any statement and returns the declared type (as given in the <tt>CREATE</tt> statement) of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no declared type.</p>
     325<p>This procedure always succeeds and never throws an exception.</p></dd>
     326<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
     327<dd>
     328<p>Can be applied to any statement and returns the number of free parameters that can be bound in the statement.</p>
     329<p>This procedure always succeeds and never throws an exception.</p></dd>
     330<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-index (stmt &lt;sqlite3:statement&gt;) (name &lt;string&gt;)) =&gt; &lt;exact&gt;</dt>
     331<dd>
     332<p>Can be applied to any statement and returns the index of the bindable parameter called <tt>name</tt> or <tt>#f</tt> if no such parameter exists.</p>
     333<p>This procedure always succeeds and never throws an exception.</p></dd>
     334<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     335<dd>
     336<p>Can be applied to any statement and returns the name of the bindable parameter number <tt>i</tt> (counting from 0) or <tt>#f</tt> if no such parameter exists or the parameter has no name.</p>
     337<p>This procedure always succeeds and never throws an exception.</p></dd>
     338<dt class="definition"><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void&gt;
     339<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;void&gt;)) =&gt; &lt;void&gt;
     340<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;exact&gt;)) =&gt; &lt;void&gt;
     341<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;number&gt;)) =&gt; &lt;void&gt;
     342<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;string&gt;)) =&gt; &lt;void&gt;
     343<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;byte-vector&gt;)) =&gt; &lt;void&gt;</dt>
     344<dd>
     345<p>Can be applied to any statement to bind its free parameter number <tt>i</tt> (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:
     346<table>
     347<tr>
     348<th>Scheme type</th>
     349<th>SQLite type</th></tr>
     350<tr>
     351<td>none</td>
     352<td><tt>null</tt></td></tr>
     353<tr>
     354<td><tt>&lt;sqlite3:null-value&gt;</tt></td>
     355<td><tt>null</tt></td></tr>
     356<tr>
     357<td><tt>&lt;exact&gt;</tt></td>
     358<td><tt>integer</tt></td></tr>
     359<tr>
     360<td><tt>&lt;number&gt;</tt></td>
     361<td><tt>float</tt></td></tr>
     362<tr>
     363<td><tt>&lt;string&gt;</tt></td>
     364<td><tt>text</tt></td></tr>
     365<tr>
     366<td><tt>&lt;byte-vector&gt;</tt></td>
     367<td><tt>blob</tt></td></tr></table></p>
     368<p>Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing.</p></dd>
     369<dt class="definition"><strong>procedure:</strong> (sqlite3:step! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;boolean&gt;</dt>
     370<dd>
     371<p>Single-steps the execution of <tt>stmt</tt> and returns <tt>#t</tt> if a result row was produced, <tt>#f</tt> if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement.</p></dd>
     372<dt class="definition"><strong>procedure:</strong> (sqlite3:column-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;symbol&gt;</dt>
     373<dd>
     374<p>Can be applied to a statement that has just been stepped (otherwise it returns <tt>#f</tt>) and returns the SQLite type of the result column number <tt>i</tt> (counting from 0) as a symbol.</p>
     375<p>The return value can be one of the symbols <tt>null</tt>, <tt>integer</tt>, <tt>float</tt>, <tt>text</tt> or <tt>blob</tt>.</p>
     376<p>This procedure always succeeds and never throws an exception.</p></dd>
     377<dt class="definition"><strong>procedure:</strong> (sqlite3:column-data (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
     378<dd>
     379<p>Can be applied to a statement that has just been stepped. Consults <tt>sqlite3:column-type</tt> to determine the type of the indicated column and to return its data as an appropriate scheme object.</p>
     380<p>See <tt>sqlite3:bind!</tt> for the mapping between Scheme and SQLite data types. Columns of type <tt>null</tt> are returned as <tt>&lt;sqlite3:null-value&gt;</tt>. Also keep in mind that CHICKEN's <tt>&lt;exact&gt;</tt> datatype can only hold a subset of the values an SQLite <tt>integer</tt> can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class <tt>&lt;integer&gt;</tt>.</p>
     381<p>This procedure always succeeds and never throws an exception.</p></dd>
     382<dt class="definition"><strong>procedure:</strong> (sqlite3:reset! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     383<dd>
     384<p>Can be applied to any statement and resets it such that execution using <tt>sqlite3:step!</tt> will perform all operations of the statement again.</p></dd>
     385<dt class="definition"><strong>method:</strong> (sqlite3:finalize! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     386<dd>
     387<p>Must be applied to every statement to free its resources and discard it.</p>
     388<p><tt>sqlite3:close</tt> will not be able to close a database that has associated unfinalized statements.</p></dd></dl></div>
     389<div class="subsection">
     390<h4>Simple statement interface</h4>
     391<dl>
     392<dt class="definition"><strong>procedure:</strong> (sqlite3:call-with-temporary-statements (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) . sqls) =&gt; &lt;top&gt;</dt>
     393<dd>
     394<p>Compiles the SQL sources in <tt>sqls</tt> into statements in the context of <tt>db</tt>, applies <tt>proc</tt> to these statements and returns <tt>proc</tt>'s result. The statements are created and finalized in <tt>dynamic-wind</tt> entry and exit blocks around the application of <tt>proc</tt>.</p></dd>
     395<dt class="definition"><strong>method:</strong> (sqlite3:exec (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
     396<br /><strong>method:</strong> (sqlite3:exec (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
     397<dd>
     398<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it.</p></dd>
     399<dt class="definition"><strong>method:</strong> (sqlite3:update (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;exact&gt;
     400<br /><strong>method:</strong> (sqlite3:update (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;exact&gt;</dt>
     401<dd>
     402<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying <tt>sqlite3:changes</tt> to the affected database after the execution of the statement instead.</p></dd>
     403<dt class="definition"><strong>method:</strong> (sqlite3:first-result (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;
     404<br /><strong>method:</strong> (sqlite3:first-result (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
     405<dd>
     406<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.</p>
     407<p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
     408<dt class="definition"><strong>method:</strong> (sqlite3:first-row (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
     409<br /><strong>method:</strong> (sqlite3:first-row (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
     410<dd>
     411<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.</p>
     412<p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
     413<dt class="definition"><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
     414<br /><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
     415<dd>
     416<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of this application are discarded.</p></dd>
     417<dt class="definition"><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
     418<br /><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
     419<dd>
     420<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of these applications are collected into a list.</p></dd></dl></div>
     421<div class="subsection">
     422<h4>Utility functions</h4>
     423<dl>
     424<dt class="definition"><strong>procedure:</strong> (sqlite3:with-transaction (db &lt;sqlite3:database&gt;) (thunk &lt;procedure-class&gt;) #!optional ((type &lt;symbol&gt;) 'deferred)) =&gt; &lt;void&gt;</dt>
     425<dd>
     426<p>Runs <tt>thunk</tt> within the scope of a transaction on the dataase <tt>db</tt>.</p>
     427<p>The transaction is committed upon exit from <tt>thunk</tt> if <tt>thunk</tt> returns a true value. If <tt>thunk</tt> returns a false value or throws an exception, the transaction is rolled back.</p>
     428<p>The <tt>type</tt> of the transaction can be specified as one of the symbols <tt>deferred</tt>, <tt>immediate</tt> or <tt>exclusive</tt>.</p></dd>
     429<dt class="definition"><strong>procedure:</strong> (sqlite3:complete? (sql &lt;string&gt;)) =&gt; &lt;boolean&gt;</dt>
     430<dd>
     431<p>Checks whether <tt>sql</tt> comprises at least one complete SQL statement.</p></dd>
     432<dt class="definition"><strong>procedure:</strong> (sqlite3:library-version) =&gt; &lt;string&gt;</dt>
     433<dd>
     434<p>Returns a string identifying the version of SQLite in use.</p></dd>
     435<dt class="definition"><strong>procedure:</strong> (sqlite3:null-value? &lt;object&gt;) =&gt; &lt;boolean&gt;</dt>
     436<dd>
     437<p>Is the <tt>&lt;object&gt;</tt> a &lt;sqlite3:null-value&gt;?</p>
     438<p>The &lt;sqlite3:null-value&gt; is compatible with the &quot;sql-null&quot; egg. The default &quot;sql-null&quot; egg function <code>(sql-null)</code> = the &lt;sqlite3:null-value&gt;. But to ensure equality - <code>(define sql-null sqlite3:null)</code>.</p></dd></dl></div></div>
     439<div class="section">
    158440<h3>Version</h3>
    159441<ul>
     442<li>2.0.3 Added <code>sqlite3:null-value</code>, <code>sqlite3:null-value?</code>, and <code>sqlite3:null</code>. [Kon Lovett]</li>
    160443<li>2.0.2 Use of extended <tt>define-foreign-enum</tt>. Removed deprecated <tt>pointer</tt> use. [Kon Lovett]</li>
    161444<li>2.0.1 Deprecated <tt>&lt;byte-vector&gt;</tt>, use <tt>&lt;blob&gt;</tt> [Kon Lovett]</li>
     
    185468<li>1.0.0 Initial release</li></ul></div>
    186469<div class="section">
    187 <h3>Usage</h3><tt>(require-extension sqlite3)</tt></div>
    188 <div class="section">
    189 <h3>Download</h3><a href="sqlite3.egg">sqlite3.egg</a></div>
    190 <div class="section">
    191 <h3>Requires</h3>
    192 <ul>
    193 <li>synch</li></ul></div>
    194 <div class="section">
    195 <h3>Documentation</h3>
    196 <p>The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.</p>
    197 <p>For in-depth information on the functionality of the routines and general information you should consult the <a href="http://www.sqlite.org/">SQLite documentation</a> as well as this manual.</p>
    198 <p>Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind <tt>(exn sqlite3)</tt> if something goes wrong. This exception will contain a <tt>status</tt> property indicating the return value of the operation that failed:
    199 <table>
    200 <tr>
    201 <th>Symbol</th>
    202 <th>Meaning</th></tr>
    203 <tr>
    204 <td><tt>error</tt></td>
    205 <td>SQL error or missing database </td></tr>
    206 <tr>
    207 <td><tt>internal</tt></td>
    208 <td>An internal logic error in SQLite </td></tr>
    209 <tr>
    210 <td><tt>permission</tt></td>
    211 <td>Access permission denied </td></tr>
    212 <tr>
    213 <td><tt>abort</tt></td>
    214 <td>Callback routine requested an abort </td></tr>
    215 <tr>
    216 <td><tt>busy</tt></td>
    217 <td>The database file is locked </td></tr>
    218 <tr>
    219 <td><tt>locked</tt></td>
    220 <td>A table in the database is locked </td></tr>
    221 <tr>
    222 <td><tt>no-memory</tt></td>
    223 <td>A malloc() failed </td></tr>
    224 <tr>
    225 <td><tt>read-only</tt></td>
    226 <td>Attempt to write a readonly database </td></tr>
    227 <tr>
    228 <td><tt>interrupt</tt></td>
    229 <td>Operation terminated by sqlite-interrupt() </td></tr>
    230 <tr>
    231 <td><tt>io-error</tt></td>
    232 <td>Some kind of disk I/O error occurred </td></tr>
    233 <tr>
    234 <td><tt>corrupt</tt></td>
    235 <td>The database disk image is malformed </td></tr>
    236 <tr>
    237 <td><tt>not-found</tt></td>
    238 <td>(Internal Only) Table or record not found </td></tr>
    239 <tr>
    240 <td><tt>full</tt></td>
    241 <td>Insertion failed because database is full </td></tr>
    242 <tr>
    243 <td><tt>cant-open</tt></td>
    244 <td>Unable to open the database file </td></tr>
    245 <tr>
    246 <td><tt>protocol</tt></td>
    247 <td>Database lock protocol error </td></tr>
    248 <tr>
    249 <td><tt>empty</tt></td>
    250 <td>(Internal Only) Database table is empty </td></tr>
    251 <tr>
    252 <td><tt>schema</tt></td>
    253 <td>The database schema changed </td></tr>
    254 <tr>
    255 <td><tt>too-big</tt></td>
    256 <td>Too much data for one row of a table </td></tr>
    257 <tr>
    258 <td><tt>constraint</tt></td>
    259 <td>Abort due to contraint violation </td></tr>
    260 <tr>
    261 <td><tt>mismatch</tt></td>
    262 <td>Data type mismatch </td></tr>
    263 <tr>
    264 <td><tt>misuse</tt></td>
    265 <td>Library used incorrectly </td></tr>
    266 <tr>
    267 <td><tt>no-lfs</tt></td>
    268 <td>Uses OS features not supported on host </td></tr>
    269 <tr>
    270 <td><tt>authorization</tt></td>
    271 <td> Authorization denied</td></tr>
    272 <tr>
    273 <td><tt>done</tt></td>
    274 <td><tt>sqlite3:step!</tt> has finished executing, so no further data is ready</td></tr></table></p>
    275 <div class="subsection">
    276 <h4>Classes</h4>
    277 <dl>
    278 <dt class="definition"><strong>class:</strong> &lt;sqlite3:database&gt;
    279 <br /><strong>class:</strong> &lt;sqlite3:statement&gt;</dt>
    280 <dd>
    281 <p>These classes are derived from <tt>&lt;c++-object&gt;</tt>. They hold a pointer to the underlying C-structure in their <tt>this</tt> slot.</p>
    282 <p><tt>&lt;sqlite3:statement&gt;</tt> also has a <tt>database</tt> slot pointing to the database object it belongs to.</p></dd></dl></div>
    283 <div class="subsection">
    284 <h4>Managing databases</h4>
    285 <dl>
    286 <dt class="definition"><strong>procedure:</strong> (sqlite3:open (path &lt;string&gt;)) =&gt; &lt;sqlite3:database&gt;</dt>
    287 <dd>
    288 <p>Opens the indicated database file and returns a <tt>&lt;sqlite3:database&gt;</tt> object for it.</p>
    289 <p>The given path is subject to the same special expansion as paths passed to
    290 <p>open-input-file</p> and similar procedures.</p></dd>
    291 <dt class="definition"><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;)) =&gt; &lt;void&gt;
    292 <br /><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;</dt>
    293 <dd>
    294 <p>If <tt>proc</tt> is given, registers a new collation sequence identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If no procedure is passed, the collation sequence with the given name is removed.</p>
    295 <p><tt>proc</tt> should have the signature <tt>(proc (a &lt;string&gt;) (b &lt;string&gt;)) =&gt; &lt;exact&gt;</tt>. It should return a negative number if <tt>a</tt> sorts before <tt>b</tt>, a positive number if <tt>b</tt> sorts before <tt>a</tt> and zero if <tt>a</tt> and <tt>b</tt> are equal.</p>
    296 <p>As <tt>proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a <tt>0</tt> return value and warning messages.</p></dd>
    297 <dt class="definition"><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;
    298 <br /><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (step-proc &lt;procedure-class&gt;) (seed &lt;top&gt;) #!optional ((final-proc &lt;procedure-class&gt;) identity)) =&gt; &lt;void&gt;</dt>
    299 <dd>
    300 <p>If <tt>proc</tt> is given, registers a new SQL function identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If <tt>step-proc</tt> and <tt>final-proc</tt> are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.</p>
    301 <p><tt>n</tt> is the number of parameters the new SQL function takes or <tt>-1</tt> to allow any number of arguments.</p>
    302 <p><tt>proc</tt> should have the signature <tt>(proc . params) =&gt; &lt;top&gt;</tt>. It is called with the <tt>n</tt> parameters given to the SQL function converted into Scheme objects like by <tt>sqlite3:column-data</tt>. The return value is converted into an SQLite3 data object like by <tt>sqlite3:bind!</tt>. A return value of <tt>(void)</tt> corresponds to <tt>NULL</tt> in SQLite3.</p>
    303 <p><tt>step-proc</tt> should have the signature <tt>(step-proc (seed &lt;top&gt;) . params) =&gt; &lt;top&gt;</tt>. It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to <tt>sqlite3:define-function</tt>; for subsequent calls it is the last value returned by <tt>step-proc</tt> and after completion of <tt>final-proc</tt> it will be the initial value again.</p>
    304 <p><tt>final-proc</tt> should have the signature <tt>(final-proc (seed &lt;top&gt;)) =&gt; &lt;top&gt;</tt> and transforms the last seed value into the value to be returned from the aggregate function.</p>
    305 <p>As <tt>proc</tt>, <tt>step-proc</tt> and <tt>final-proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in <tt>NULL</tt> return values and warning messages.</p></dd>
    306 <dt class="definition"><strong>procedure:</strong> (sqlite3:set-busy-timeout! (db &lt;sqlite3:database&gt;) #!optional ((ms &lt;exact&gt;) 0)) =&gt; &lt;void&gt;</dt>
    307 <dd>
    308 <p>Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If <tt>(&lt;= ms 0)</tt> though, all busy handlers for the database are uninstalled.</p></dd>
    309 <dt class="definition"><strong>procedure:</strong> (sqlite3:interrupt! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
    310 <dd>
    311 <p>Cancels any running database operation as soon as possible.</p>
    312 <p>This function is always successful and never throws an exception.</p></dd>
    313 <dt class="definition"><strong>procedure:</strong> (sqlite3:auto-committing? (db &lt;sqlite3:database&gt;)) =&gt; &lt;bool&gt;</dt>
    314 <dd>
    315 <p>Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.</p>
    316 <p>This function always returns a state and never throws an exception.</p></dd>
    317 <dt class="definition"><strong>procedure:</strong> (sqlite3:changes (db &lt;sqlite3:database&gt;) #!optional ((total &lt;bool&gt;) #f)) =&gt; &lt;number&gt;</dt>
    318 <dd>
    319 <p>Returns the number of rows changed by the last statement (if <tt>(not total)</tt>) or since the database was opened (if <tt>total</tt>).</p>
    320 <p>This function always returns a count and never throws an exception.</p></dd>
    321 <dt class="definition"><strong>procedure:</strong> (sqlite3:last-insert-rowid (db &lt;sqlite3:database&gt;)) =&gt; &lt;number&gt;</dt>
    322 <dd>
    323 <p>Returns the row ID of the last row inserted in <tt>db</tt>.</p>
    324 <p>This function always returns a number and never throws an exception.</p></dd>
    325 <dt class="definition"><strong>method:</strong> (sqlite3:finalize! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
    326 <dd>
    327 <p>Closes the given database.</p></dd></dl></div>
    328 <div class="subsection">
    329 <h4>Managing statements</h4>
    330 <dl>
    331 <dt class="definition"><strong>procedure:</strong> (sqlite3:prepare (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;)) =&gt; &lt;sqlite3:statement&gt;, &lt;string&gt;</dt>
    332 <dd>
    333 <p>Compiles the first SQL statement in <tt>sql</tt> and returns a <tt>&lt;sqlite3:statement&gt;</tt> and the rest of <tt>sql</tt>, which was not compiled (or an empty string).</p></dd>
    334 <dt class="definition"><strong>procedure:</strong> (sqlite3:repair! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    335 <dd>
    336 <p>Recompiles the SQL statement used to create <tt>stmt</tt>, transfers all existing bindings from the old statement handle to the new one and destructively modifies <tt>stmt</tt> to point to the new statement handle.</p>
    337 <p>If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.</p>
    338 <p>Usually you should not have to call this routine by hand. It is invoked by <tt>sqlite3:step!</tt> to automagically repair a stale statement handle after a database schema change.</p></dd>
    339 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
    340 <dd>
    341 <p>Can be applied to any statement and returns the number of columns it will return as results.</p>
    342 <p>This procedure always succeeds and never throws an exception.</p></dd>
    343 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    344 <dd>
    345 <p>Can be applied to any statement and returns the name of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no name.</p>
    346 <p>This procedure always succeeds and never throws an exception.</p></dd>
    347 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-declared-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    348 <dd>
    349 <p>Can be applied to any statement and returns the declared type (as given in the <tt>CREATE</tt> statement) of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no declared type.</p>
    350 <p>This procedure always succeeds and never throws an exception.</p></dd>
    351 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
    352 <dd>
    353 <p>Can be applied to any statement and returns the number of free parameters that can be bound in the statement.</p>
    354 <p>This procedure always succeeds and never throws an exception.</p></dd>
    355 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-index (stmt &lt;sqlite3:statement&gt;) (name &lt;string&gt;)) =&gt; &lt;exact&gt;</dt>
    356 <dd>
    357 <p>Can be applied to any statement and returns the index of the bindable parameter called <tt>name</tt> or <tt>#f</tt> if no such parameter exists.</p>
    358 <p>This procedure always succeeds and never throws an exception.</p></dd>
    359 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    360 <dd>
    361 <p>Can be applied to any statement and returns the name of the bindable parameter number <tt>i</tt> (counting from 0) or <tt>#f</tt> if no such parameter exists or the parameter has no name.</p>
    362 <p>This procedure always succeeds and never throws an exception.</p></dd>
    363 <dt class="definition"><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void&gt;
    364 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;void&gt;)) =&gt; &lt;void&gt;
    365 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;exact&gt;)) =&gt; &lt;void&gt;
    366 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;number&gt;)) =&gt; &lt;void&gt;
    367 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;string&gt;)) =&gt; &lt;void&gt;
    368 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;byte-vector&gt;)) =&gt; &lt;void&gt;</dt>
    369 <dd>
    370 <p>Can be applied to any statement to bind its free parameter number <tt>i</tt> (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:
    371 <table>
    372 <tr>
    373 <th>Scheme type</th>
    374 <th>SQLite type</th></tr>
    375 <tr>
    376 <td>none</td>
    377 <td><tt>null</tt></td></tr>
    378 <tr>
    379 <td><tt>&lt;void&gt;</tt></td>
    380 <td><tt>null</tt></td></tr>
    381 <tr>
    382 <td><tt>&lt;exact&gt;</tt></td>
    383 <td><tt>integer</tt></td></tr>
    384 <tr>
    385 <td><tt>&lt;number&gt;</tt></td>
    386 <td><tt>float</tt></td></tr>
    387 <tr>
    388 <td><tt>&lt;string&gt;</tt></td>
    389 <td><tt>text</tt></td></tr>
    390 <tr>
    391 <td><tt>&lt;byte-vector&gt;</tt></td>
    392 <td><tt>blob</tt></td></tr></table></p>
    393 <p>Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing.</p></dd>
    394 <dt class="definition"><strong>procedure:</strong> (sqlite3:step! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;boolean&gt;</dt>
    395 <dd>
    396 <p>Single-steps the execution of <tt>stmt</tt> and returns <tt>#t</tt> if a result row was produced, <tt>#f</tt> if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement.</p></dd>
    397 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;symbol&gt;</dt>
    398 <dd>
    399 <p>Can be applied to a statement that has just been stepped (otherwise it returns <tt>#f</tt>) and returns the SQLite type of the result column number <tt>i</tt> (counting from 0) as a symbol.</p>
    400 <p>The return value can be one of the symbols <tt>null</tt>, <tt>integer</tt>, <tt>float</tt>, <tt>text</tt> or <tt>blob</tt>.</p>
    401 <p>This procedure always succeeds and never throws an exception.</p></dd>
    402 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-data (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
    403 <dd>
    404 <p>Can be applied to a statement that has just been stepped. Consults <tt>sqlite3:column-type</tt> to determine the type of the indicated column and to return its data as an appropriate scheme object.</p>
    405 <p>See <tt>sqlite3:bind!</tt> for the mapping between Scheme and SQLite data types. Columns of type <tt>null</tt> are returned as <tt>(void)</tt>. Also keep in mind that CHICKEN's <tt>&lt;exact&gt;</tt> datatype can only hold a subset of the values an SQLite <tt>integer</tt> can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class <tt>&lt;integer&gt;</tt>.</p>
    406 <p>This procedure always succeeds and never throws an exception.</p></dd>
    407 <dt class="definition"><strong>procedure:</strong> (sqlite3:reset! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    408 <dd>
    409 <p>Can be applied to any statement and resets it such that execution using <tt>sqlite3:step!</tt> will perform all operations of the statement again.</p></dd>
    410 <dt class="definition"><strong>method:</strong> (sqlite3:finalize! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    411 <dd>
    412 <p>Must be applied to every statement to free its resources and discard it.</p>
    413 <p><tt>sqlite3:close</tt> will not be able to close a database that has associated unfinalized statements.</p></dd></dl></div>
    414 <div class="subsection">
    415 <h4>Simple statement interface</h4>
    416 <dl>
    417 <dt class="definition"><strong>procedure:</strong> (sqlite3:call-with-temporary-statements (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) . sqls) =&gt; &lt;top&gt;</dt>
    418 <dd>
    419 <p>Compiles the SQL sources in <tt>sqls</tt> into statements in the context of <tt>db</tt>, applies <tt>proc</tt> to these statements and returns <tt>proc</tt>'s result. The statements are created and finalized in <tt>dynamic-wind</tt> entry and exit blocks around the application of <tt>proc</tt>.</p></dd>
    420 <dt class="definition"><strong>method:</strong> (sqlite3:exec (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
    421 <br /><strong>method:</strong> (sqlite3:exec (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
    422 <dd>
    423 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it.</p></dd>
    424 <dt class="definition"><strong>method:</strong> (sqlite3:update (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;exact&gt;
    425 <br /><strong>method:</strong> (sqlite3:update (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;exact&gt;</dt>
    426 <dd>
    427 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying <tt>sqlite3:changes</tt> to the affected database after the execution of the statement instead.</p></dd>
    428 <dt class="definition"><strong>method:</strong> (sqlite3:first-result (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;
    429 <br /><strong>method:</strong> (sqlite3:first-result (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
    430 <dd>
    431 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.</p>
    432 <p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
    433 <dt class="definition"><strong>method:</strong> (sqlite3:first-row (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
    434 <br /><strong>method:</strong> (sqlite3:first-row (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
    435 <dd>
    436 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.</p>
    437 <p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
    438 <dt class="definition"><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
    439 <br /><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
    440 <dd>
    441 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of this application are discarded.</p></dd>
    442 <dt class="definition"><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
    443 <br /><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
    444 <dd>
    445 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of these applications are collected into a list.</p></dd></dl></div>
    446 <div class="subsection">
    447 <h4>Utility functions</h4>
    448 <dl>
    449 <dt class="definition"><strong>procedure:</strong> (sqlite3:with-transaction (db &lt;sqlite3:database&gt;) (thunk &lt;procedure-class&gt;) #!optional ((type &lt;symbol&gt;) 'deferred)) =&gt; &lt;void&gt;</dt>
    450 <dd>
    451 <p>Runs <tt>thunk</tt> within the scope of a transaction on the dataase <tt>db</tt>.</p>
    452 <p>The transaction is committed upon exit from <tt>thunk</tt> if <tt>thunk</tt> returns a true value. If <tt>thunk</tt> returns a false value or throws an exception, the transaction is rolled back.</p>
    453 <p>The <tt>type</tt> of the transaction can be specified as one of the symbols <tt>deferred</tt>, <tt>immediate</tt> or <tt>exclusive</tt>.</p></dd>
    454 <dt class="definition"><strong>procedure:</strong> (sqlite3:complete? (sql &lt;string&gt;)) =&gt; &lt;boolean&gt;</dt>
    455 <dd>
    456 <p>Checks whether <tt>sql</tt> comprises at least one complete SQL statement.</p></dd>
    457 <dt class="definition"><strong>procedure:</strong> (sqlite3:library-version) =&gt; &lt;string&gt;</dt>
    458 <dd>
    459 <p>Returns a string identifying the version of SQLite in use.</p></dd></dl></div></div>
    460 <div class="section">
    461470<h3>License</h3>
    462471<pre id="license">Copyright (c) 2005, Thomas Chust &lt;chust@web.de&gt;.  All rights reserved.
  • release/3/sqlite3/tags/2.0.3/sqlite3.scm

    r6115 r7981  
    1010(define-extension sqlite3
    1111  (export
     12    ;; classes
    1213    initialize
    13     <sqlite3:database> <sqlite3:statement>
     14    <sqlite3:database>
     15    <sqlite3:statement>
     16    ;; methods & procedures
    1417    sqlite3:open
    15     sqlite3:define-collation sqlite3:define-function
    16     sqlite3:set-busy-timeout! sqlite3:interrupt!
    17     sqlite3:auto-committing? sqlite3:changes sqlite3:last-insert-rowid
     18    sqlite3:define-collation
     19    sqlite3:define-function
     20    sqlite3:set-busy-timeout!
     21    sqlite3:interrupt!
     22    sqlite3:auto-committing?
     23    sqlite3:changes
     24    sqlite3:last-insert-rowid
    1825    sqlite3:finalize!
    19     sqlite3:prepare sqlite3:repair! sqlite3:reset!
     26    sqlite3:prepare
     27    sqlite3:repair!
     28    sqlite3:reset!
    2029    sqlite3:bind-parameter-count
    21     sqlite3:bind-parameter-index sqlite3:bind-parameter-name
    22     sqlite3:bind! sqlite3:step!
    23     sqlite3:column-count sqlite3:column-type
    24     sqlite3:column-declared-type sqlite3:column-name
     30    sqlite3:bind-parameter-index
     31    sqlite3:bind-parameter-name
     32    sqlite3:bind!
     33    sqlite3:step!
     34    sqlite3:column-count
     35    sqlite3:column-type
     36    sqlite3:column-declared-type
     37    sqlite3:column-name
    2538    sqlite3:column-data
    2639    sqlite3:call-with-temporary-statements
    27     sqlite3:exec sqlite3:update sqlite3:first-result sqlite3:first-row
    28     sqlite3:for-each-row sqlite3:map-row
     40    sqlite3:exec
     41    sqlite3:update
     42    sqlite3:first-result
     43    sqlite3:first-row
     44    sqlite3:for-each-row
     45    sqlite3:map-row
    2946    sqlite3:with-transaction
    30     sqlite3:complete? sqlite3:library-version))
     47    sqlite3:complete?
     48    sqlite3:library-version
     49    ;; null type
     50    sqlite3:null
     51    sqlite3:null-value?
     52    sqlite3:null-value) )
    3153
    3254(declare
     
    3456  (fixnum-arithmetic)
    3557  (no-procedure-checks-for-usual-bindings)
    36   (disable-warning redef) ; redefinition of imported variable `initialize' from `tinyclos'
    37   (unused                 ; global variable '...' is never used
     58  ; redefinition of imported variable `initialize' from `tinyclos'
     59  (disable-warning redef)
     60  (unused
     61    ; global variable '...' is never used
    3862    chicken_sqlite3_function_stub
    3963    chicken_sqlite3_collation_stub
    4064    chicken_sqlite3_final_stub
    41     chicken_sqlite3_step_stub) )
     65    chicken_sqlite3_step_stub )
     66  (import
     67    ##sys#expand-home-path
     68    #;##sys#pathname-resolution )
     69  (bound-to-procedure
     70    sqlite3:errmsg ) )
    4271
    4372#>#include <sqlite3.h><#
     
    4776 extras lolevel tinyclos synch)
    4877
    49 ;;; enum and constant definitions
    50 
    51 (cond-expand
    52   (has-extended-define-foreign-enum
    53     (define-foreign-enum (sqlite3:status int)
    54       (ok               SQLITE_OK   #f)       ; Successful result
    55       (error            SQLITE_ERROR)         ; SQL error or missing database
    56       (internal         SQLITE_INTERNAL)      ; NOT USED. Internal logic error in SQLite
    57       (permission       SQLITE_PERM)          ; Access permission denied
    58       (abort            SQLITE_ABORT)         ; Callback routine requested an abort
    59       (busy             SQLITE_BUSY)          ; The database file is locked
    60       (locked           SQLITE_LOCKED)        ; A table in the database is locked
    61       (no-memory        SQLITE_NOMEM)         ; A malloc() failed
    62       (read-only        SQLITE_READONLY)      ; Attempt to write a readonly database
    63       (interrupt        SQLITE_INTERRUPT)     ; Operation terminated by sqlite3_interrupt()
    64       (io-error         SQLITE_IOERR)         ; Some kind of disk I/O error occurred
    65       (corrupt          SQLITE_CORRUPT)       ; The database disk image is malformed
    66       (not-found        SQLITE_NOTFOUND)      ; NOT USED. Table or record not found
    67       (full             SQLITE_FULL)          ; Insertion failed because database is full
    68       (cant-open        SQLITE_CANTOPEN)      ; Unable to open the database file
    69       (protocol         SQLITE_PROTOCOL)      ; NOT USED. Database lock protocol error
    70       (empty            SQLITE_EMPTY)         ; Database is empty
    71       (schema           SQLITE_SCHEMA)        ; The database schema changed
    72       (too-big          SQLITE_TOOBIG)        ; String or BLOB exceeds size limit
    73       (constraint       SQLITE_CONSTRAINT)    ; Abort due to contraint violation
    74       (mismatch         SQLITE_MISMATCH)      ; Data type mismatch
    75       (misuse           SQLITE_MISUSE)        ; Library used incorrectly
    76       (no-lfs           SQLITE_NOLFS)         ; Uses OS features not supported on host
    77       (authorization    SQLITE_AUTH)          ; Authorization denied
    78       (format           SQLITE_FORMAT)        ; Auxiliary database format error
    79       (range            SQLITE_RANGE)         ; 2nd parameter to sqlite3_bind out of range
    80       (not-a-database   SQLITE_NOTADB)        ; File opened that is not a database file
    81       (row              SQLITE_ROW)           ; sqlite3_step() has another row ready
    82       (done             SQLITE_DONE)          ; sqlite3_step() has finished executing
    83     )
    84    
    85     (define-foreign-enum (sqlite3:type int)
    86       (integer  SQLITE_INTEGER)
    87       (float    SQLITE_FLOAT)
    88       (text     SQLITE_TEXT)
    89       (blob     SQLITE_BLOB)
    90       (null     SQLITE_NULL)
    91     ) )
    92   (else   
    93     (define-macro (define-enum-type name . vars)
    94       (let ((pairs
    95        (let loop ((vars vars) (i 0))
    96          (if (null? vars)
    97              '()
    98              (let ((v (car vars)))
    99          (if (pair? v)
    100              (cons v (loop (cdr vars) (add1 (cdr v))))
    101              (cons (cons v i) (loop (cdr vars) (add1 i)))))))))
    102         `(define-foreign-type ,name int
    103            (lambda (sym)
    104        (case sym
    105          ,@(map (lambda (p) `((,(car p)) ,(cdr p))) pairs)
    106          (else #f)))
    107            (lambda (int)
    108        (switch int
    109          ,@(map (lambda (p) `(,(cdr p) ',(car p))) pairs)
    110          (else #f))))))
    111    
    112     (define-enum-type sqlite3:status
    113       ;;(ok . 0) ; Successful result
    114       (error . 1) ; SQL error or missing database
    115       internal ; An internal logic error in SQLite
    116       permission ; Access permission denied
    117       abort ; Callback routine requested an abort
    118       busy ; The database file is locked
    119       locked ; A table in the database is locked
    120       no-memory ; A malloc() failed
    121       read-only ; Attempt to write a readonly database
    122       interrupt ; Operation terminated by sqlite-interrupt()
    123       io-error ; Some kind of disk I/O error occurred
    124       corrupt ; The database disk image is malformed
    125       not-found ; (Internal Only) Table or record not found
    126       full ; Insertion failed because database is full
    127       cant-open ; Unable to open the database file
    128       protocol ; Database lock protocol error
    129       empty ; (Internal Only) Database table is empty
    130       schema ; The database schema changed
    131       too-big ; Too much data for one row of a table
    132       constraint ; Abort due to contraint violation
    133       mismatch ; Data type mismatch
    134       misuse ; Library used incorrectly
    135       no-lfs ; Uses OS features not supported on host
    136       authorization ;  Authorization denied
    137       (row . 100) ; sqlite-step() has another row ready
    138       done) ; sqlite-step() has finished executing
    139    
    140     (define-enum-type sqlite3:type
    141       (integer . 1)
    142       float
    143       text
    144       blob
    145       null) ) )
    146 
    147 ;;; Utilities
    148 
    149 (define (make-hash-table/synch id . args)
    150   (make-object/synch (apply make-hash-table args) id) )
    151 
    152 ;;; classes for databases and statements
     78;;; Foreign types & values
     79
     80;; Enumeration and constant definitions
     81
     82(define-foreign-enum (sqlite3:status int)
     83  #f ; no aliases
     84  (ok               SQLITE_OK   #f)       ; Successful result
     85  (error            SQLITE_ERROR)         ; SQL error or missing database
     86  (internal         SQLITE_INTERNAL)      ; NOT USED. Internal logic error in SQLite
     87  (permission       SQLITE_PERM)          ; Access permission denied
     88  (abort            SQLITE_ABORT)         ; Callback routine requested an abort
     89  (busy             SQLITE_BUSY)          ; The database file is locked
     90  (locked           SQLITE_LOCKED)        ; A table in the database is locked
     91  (no-memory        SQLITE_NOMEM)         ; A malloc() failed
     92  (read-only        SQLITE_READONLY)      ; Attempt to write a readonly database
     93  (interrupt        SQLITE_INTERRUPT)     ; Operation terminated by sqlite3_interrupt()
     94  (io-error         SQLITE_IOERR)         ; Some kind of disk I/O error occurred
     95  (corrupt          SQLITE_CORRUPT)       ; The database disk image is malformed
     96  (not-found        SQLITE_NOTFOUND)      ; NOT USED. Table or record not found
     97  (full             SQLITE_FULL)          ; Insertion failed because database is full
     98  (cant-open        SQLITE_CANTOPEN)      ; Unable to open the database file
     99  (protocol         SQLITE_PROTOCOL)      ; NOT USED. Database lock protocol error
     100  (empty            SQLITE_EMPTY)         ; Database is empty
     101  (schema           SQLITE_SCHEMA)        ; The database schema changed
     102  (too-big          SQLITE_TOOBIG)        ; String or BLOB exceeds size limit
     103  (constraint       SQLITE_CONSTRAINT)    ; Abort due to contraint violation
     104  (mismatch         SQLITE_MISMATCH)      ; Data type mismatch
     105  (misuse           SQLITE_MISUSE)        ; Library used incorrectly
     106  (no-lfs           SQLITE_NOLFS)         ; Uses OS features not supported on host
     107  (authorization    SQLITE_AUTH)          ; Authorization denied
     108  (format           SQLITE_FORMAT)        ; Auxiliary database format error
     109  (range            SQLITE_RANGE)         ; 2nd parameter to sqlite3_bind out of range
     110  (not-a-database   SQLITE_NOTADB)        ; File opened that is not a database file
     111  (row              SQLITE_ROW)           ; sqlite3_step() has another row ready
     112  (done             SQLITE_DONE) )        ; sqlite3_step() has finished executing
     113
     114(define-foreign-enum (sqlite3:type int)
     115  #f ; no aliases
     116  (integer  SQLITE_INTEGER)
     117  (float    SQLITE_FLOAT)
     118  (text     SQLITE_TEXT)
     119  (blob     SQLITE_BLOB)
     120  (null     SQLITE_NULL) )
     121
     122;; Types
     123
     124(define-foreign-type sqlite3:context (c-pointer "sqlite3_context"))
     125
     126(define-foreign-type sqlite3:value (c-pointer "sqlite3_value"))
     127
     128(define sqlite3:null void)
     129
     130(define sqlite3:null-value (sqlite3:null))
     131
     132(define (sqlite3:null-value? obj)
     133  (eq? sqlite3:null-value obj) )
     134
     135;;; Classes for databases and statements
    153136
    154137(define-class <sqlite3:database> (<c++-object>) ())
     
    157140  (lambda (db)
    158141    (unless (slot-ref db 'this)
    159       (sqlite3:null-error 'sqlite3:database->c-pointer db))
     142      (signal-null-error 'sqlite3:database->c-pointer db))
    160143    db))
    161144
     
    165148  (lambda (stmt)
    166149    (unless (slot-ref stmt 'this)
    167       (sqlite3:null-error 'sqlite3:statement->c-pointer stmt))
     150      (signal-null-error 'sqlite3:statement->c-pointer stmt))
    168151    stmt))
    169152
     
    172155  (initialize-slots this initargs))
    173156
    174 (define-foreign-type sqlite3:context
    175   (c-pointer "sqlite3_context"))
    176 
    177 (define-foreign-type sqlite3:value
    178   (c-pointer "sqlite3_value"))
    179 
    180 ;;; helper functions
    181 
    182 (define sqlite3:errmsg
    183   (foreign-lambda c-string "sqlite3_errmsg" sqlite3:database))
    184 
    185 (define ((sqlite3:error loc db . args) s)
     157;;; Helpers
     158
     159;; Expand variables in pathname
     160(define sqlite3:resolve-pathname
     161  ##sys#expand-home-path
     162  #; ;not needed, yet
     163  (cut ##sys#pathname-resolution <> identity))
     164
     165;; Conditions
     166
     167(define (make-exn-condition loc msg . args)
     168  (make-property-condition 'exn 'location loc 'message msg 'arguments args) )
     169
     170(define (make-sqlite3-condition sta)
     171  (make-property-condition 'sqlite3 'status sta) )
     172
     173(define (make-sqlite3-error-condition loc msg sta . args)
     174   (make-composite-condition
     175    (apply make-exn-condition loc msg args)
     176    (make-sqlite3-condition sta)) )
     177
     178(define (make-no-data-condition stmt params)
     179  (make-sqlite3-error-condition 'sqlite3:first-result
     180                                "the statement returned no data"
     181                                'done
     182                                stmt params) )
     183
     184;; Errors
     185
     186(define ((signal-error loc db . args) sta)
    186187  (signal
    187    (make-composite-condition
    188     (make-property-condition
    189      'exn
    190      'location loc 'arguments args
    191      'message (if db (sqlite3:errmsg db) (symbol->string s)))
    192     (make-property-condition
    193      'sqlite3
    194      'status s))))
    195 
    196 (define (sqlite3:null-error loc obj)
     188   (apply make-sqlite3-error-condition loc
     189                                       (if db (sqlite3:errmsg db) (symbol->string sta))
     190                                       sta
     191                                       args)) )
     192
     193(define (signal-null-error loc obj)
    197194  (signal
    198    (make-composite-condition
    199     (make-property-condition
    200      'exn
    201      'location loc 'arguments (list obj)
    202      'message (sprintf
    203                "bad ~a object, contained pointer is #f"
    204                (class-name (class-of obj))))
    205     (make-property-condition
    206      'sqlite3
    207      'status 'error))))
     195   (make-sqlite3-error-condition loc
     196                                 (format #f "bad ~A object, contained pointer is #f"
     197                                            (class-name (class-of obj)))
     198                                 'error
     199                                 obj)) )
    208200
    209201(define (check-type loc obj class)
     
    211203    (abort
    212204     (make-composite-condition
    213       (make-property-condition
    214        'exn
    215        'location loc 'arguments (list obj)
    216        'message (sprintf
    217                  "bad argument type ~a, expected ~a"
    218                  (class-name (class-of obj)) (class-name class)))
    219       (make-property-condition 'type)))))
     205      (make-exn-condition loc
     206                          (format #f "bad argument type ~A, expected ~A"
     207                                     (class-name (class-of obj)) (class-name class))
     208                          obj)
     209      (make-property-condition 'type)))) )
     210
     211;; Tree dictionary
     212
     213(define (make-hash-table-tree/synch id . args)
     214  (make-object/synch (apply make-hash-table args) id) )
    220215
    221216(define (hash-table-tree-set! ht-tree keys value)
     
    244239                             (signal
    245240                              (make-composite-condition
    246                                (make-property-condition
    247                                 'exn
    248                                 'location 'hash-table-tree-ref
    249                                 'message "hash-table-tree does not contain path"
    250                                 'arguments (list ht-tree keys))
    251                                (make-property-condition
    252                                 'access))))))
     241                               (make-exn-condition 'hash-table-tree-ref
     242                                                   "hash-table-tree does not contain path"
     243                                                   ht-tree keys)
     244                               (make-property-condition 'access))))))
    253245  (call-with-current-continuation
    254246   (lambda (q)
     
    263255  (hash-table-tree-ref ht-tree keys (lambda () default)))
    264256
    265 ;;; database interface
    266 
    267 ;; open a database
    268 (define (sqlite3:open path)
    269   (check-type 'sqlite3:open path <string>)
    270   (let-location ((db c-pointer))
    271     (cond
    272      (((foreign-lambda
    273         sqlite3:status "sqlite3_open"
    274         nonnull-c-string (c-pointer sqlite3:database))
    275        (##sys#expand-home-path path) (location db))
    276       => (sqlite3:error 'sqlite3:open #f path))
    277      (else
    278       (make <sqlite3:database> 'this db)))))
    279 
    280 ;; define a new collation sequence or remove an existing one
    281 
    282 (define sqlite3:collations (make-hash-table/synch 'sqlite3:collations))
    283 
    284 (define-external (chicken_sqlite3_collation_stub (scheme-object qn)
    285                                                  (int la) (c-pointer da)
    286                                                  (int lb) (c-pointer db)) int
     257(define (hash-table-tree-clear! htt id elt-clear)
     258  (cond ((hash-table-ref/default htt id #f)
     259         => (cut hash-table-walk <> elt-clear)))
     260  (hash-table-delete! htt id) )
     261
     262;; SQL collation sequence interface
     263
     264(define *sqlite3:collations* (make-hash-table-tree/synch 'sqlite3:collations))
     265
     266(define-external (chicken_sqlite3_collation_stub (scheme-object qn) (int la)
     267                                                 (c-pointer da) (int lb)
     268                                                 (c-pointer db))
     269                 int
    287270  (call-with-current-continuation
    288271   (lambda (q)
    289272     (let ((r #f))
    290273       (dynamic-wind
    291            void
     274           noop
    292275           (lambda ()
    293276             (handle-exceptions exn
     
    299282                 (set! r
    300283                   ((vector-ref
    301                      (call-with/synch sqlite3:collations
     284                     (call-with/synch *sqlite3:collations*
    302285                       (cut hash-table-tree-ref <> qn))
    303286                     1)
     
    307290                 (q r)
    308291                 (begin
    309                    (fprintf
     292                   (format
    310293                    (current-error-port)
    311                     "Error in collation function: invalid return value: ~s~%"
     294                    "Error in collation function: invalid return value: ~S~%"
    312295                    r)
    313296                   (q 0)))))))))
    314297
    315298(define sqlite3_create_collation
    316   (foreign-lambda*
    317    sqlite3:status ((sqlite3:database db) (c-string name) (scheme-object qn))
    318    "if (qn == C_SCHEME_FALSE)\n"
    319    "  return(sqlite3_create_collation(db, name, SQLITE_UTF8, NULL, NULL));\n"
    320    "else\n"
    321    "  return(sqlite3_create_collation(db, name, SQLITE_UTF8,\n"
    322    "                                  (void *)qn,\n"
    323    "                                  (int (*)(void *,\n"
    324    "                                           int, const void *,\n"
    325    "                                           int, const void *))"
    326    "                                    &chicken_sqlite3_collation_stub));\n"))
     299  (foreign-lambda* sqlite3:status
     300                  ((sqlite3:database db) (c-string name) (scheme-object qn))
     301#<<END
     302  if (qn == C_SCHEME_FALSE)
     303    return(sqlite3_create_collation(db, name, SQLITE_UTF8, NULL, NULL));
     304  else
     305    return(sqlite3_create_collation(db, name, SQLITE_UTF8,
     306                                      (void *)qn,
     307                                      (int (*)(void *,
     308                                               int, const void *,
     309                                               int, const void *))
     310                                        &chicken_sqlite3_collation_stub));
     311END
     312  ))
    327313
    328314(define-generic sqlite3:define-collation)
     
    331317  (cond
    332318   ((sqlite3_create_collation db name #f)
    333     => (sqlite3:error 'sqlite3:define-collation db name))
     319    => (signal-error 'sqlite3:define-collation db name))
    334320   (else
    335321    (let ((qn (list (pointer->address (slot-ref db 'this)) name)))
    336       (call-with/synch sqlite3:collations
     322      (call-with/synch *sqlite3:collations*
    337323        (lambda (col)
    338324          (cond
     
    350336      => (lambda (s)
    351337           (object-release qn)
    352            ((sqlite3:error 'sqlite3:define-collation db name proc) s)))
     338           ((signal-error 'sqlite3:define-collation db name proc) s)))
    353339     (else
    354       (call-with/synch sqlite3:collations
     340      (call-with/synch *sqlite3:collations*
    355341        (cut hash-table-tree-set! <> qn (vector qn proc)))))))
    356342
    357 ;; define a new SQL function or remove an existing one
     343;;; SQL function interface
     344
     345(define *sqlite3:functions* (make-hash-table-tree/synch 'sqlite3:functions))
     346
     347(define *sqlite3:seeds* (make-hash-table-tree/synch 'sqlite3:seeds))
    358348
    359349(define (sqlite3:parameter-data n args)
     
    361351    (if (< i n)
    362352        (cons
    363          (case ((foreign-lambda*
    364                  sqlite3:type (((c-pointer sqlite3:value) args) (int i))
    365                  "return(sqlite3_value_type(args[i]));\n")
     353         (case ((foreign-lambda* sqlite3:type
     354                                (((c-pointer sqlite3:value) args) (int i))
     355                 "return(sqlite3_value_type(args[i]));")
    366356                args i)
    367357           ((integer)
    368             ((foreign-lambda*
    369               integer (((c-pointer sqlite3:value) args) (int i))
    370               "return(sqlite3_value_double(args[i]));\n")
     358            ((foreign-lambda* integer
     359                              (((c-pointer sqlite3:value) args) (int i))
     360              "return(sqlite3_value_double(args[i]));")
    371361             args i))
    372362           ((float)
    373             ((foreign-lambda*
    374               double (((c-pointer sqlite3:value) args) (int i))
    375               "return(sqlite3_value_double(args[i]));\n")
     363            ((foreign-lambda* double
     364                              (((c-pointer sqlite3:value) args) (int i))
     365              "return(sqlite3_value_double(args[i]));")
    376366             args i))
    377367           ((text)
    378             ((foreign-primitive
    379               scheme-object (((c-pointer sqlite3:value) args) (int i))
    380               "int n = sqlite3_value_bytes(args[i]);\n"
    381               "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    382               "return(C_string(&s, n, (char *)sqlite3_value_text(args[i])));\n")
     368            ((foreign-primitive scheme-object
     369                                (((c-pointer sqlite3:value) args) (int i))
     370              "int n = sqlite3_value_bytes(args[i]);"
     371              "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     372              "return(C_string(&s, n, (char *)sqlite3_value_text(args[i])));")
    383373             args i))
    384374           ((blob)
    385             ((foreign-primitive
    386               scheme-object (((c-pointer sqlite3:value) args) (int i))
    387               "int n = sqlite3_value_bytes(args[i]);\n"
    388               "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    389               "return(C_bytevector(&s, n, (char *)sqlite3_value_blob(args[i])));\n")
     375            ((foreign-primitive scheme-object
     376                                (((c-pointer sqlite3:value) args) (int i))
     377              "int n = sqlite3_value_bytes(args[i]);"
     378              "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     379              "return(C_bytevector(&s, n, (char *)sqlite3_value_blob(args[i])));")
    390380             args i))
    391381           (else
    392             (void)))
     382            sqlite3:null-value))
    393383         (loop (add1 i)))
    394384        '())))
     
    396386(define-generic sqlite3:set-result!)
    397387(define-method (sqlite3:set-result! (ctx <pointer>) (v <blob>))
    398   ((foreign-lambda*
    399     void
    400     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     388  ((foreign-lambda* void
     389                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    401390      "sqlite3_result_blob(ctx, v, n, SQLITE_TRANSIENT);")
    402391   ctx v (blob-size v)))
     
    404393; Deprecated
    405394(define-method (sqlite3:set-result! (ctx <pointer>) (v <byte-vector>))
    406   ((foreign-lambda*
    407     void
    408     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     395  ((foreign-lambda* void
     396                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    409397      "sqlite3_result_blob(ctx, v, n, SQLITE_TRANSIENT);")
    410398   ctx v (byte-vector-length v)))
    411  
     399
    412400(define-method (sqlite3:set-result! (ctx <pointer>) (v <exact>))
    413401  ((foreign-lambda void "sqlite3_result_int" sqlite3:context int)
     
    419407
    420408(define-method (sqlite3:set-result! (ctx <pointer>) (v <string>))
    421   ((foreign-lambda*
    422     void
    423     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     409  ((foreign-lambda* void
     410                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    424411    "sqlite3_result_text(ctx, v, n, SQLITE_TRANSIENT);")
    425412   ctx v (string-length v)))
     
    433420   ctx))
    434421
    435 (define sqlite3:functions (make-hash-table/synch 'sqlite3:functions))
    436 
    437422(define sqlite3_user_data
    438423  (foreign-lambda scheme-object "sqlite3_user_data" sqlite3:context))
    439424
    440 (define-external (chicken_sqlite3_function_stub (c-pointer ctx)
    441                                                 (int n) (c-pointer args)) void
     425(define-external (chicken_sqlite3_function_stub (c-pointer ctx) (int n) (c-pointer args)) void
    442426  (call-with-current-continuation
    443427   (lambda (q)
    444428     (dynamic-wind
    445          void
     429         noop
    446430         (lambda ()
    447431           (handle-exceptions exn
     
    452436              (apply
    453437               (vector-ref
    454                 (call-with/synch
    455                  sqlite3:functions
     438                (call-with/synch *sqlite3:functions*
    456439                 (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))
    457440                1)
     
    460443           (q (void)))))))
    461444
    462 (define sqlite3:seeds (make-hash-table/synch 'sqlite3:seeds))
    463 
    464445(define sqlite3_aggregate_context
    465   (foreign-lambda*
    466    integer ((sqlite3:context ctx))
    467    "return((int)sqlite3_aggregate_context(ctx, 1));\n"))
    468 
    469 (define-external (chicken_sqlite3_step_stub (c-pointer ctx)
    470                                             (int n) (c-pointer args)) void
     446  (foreign-lambda* integer ((sqlite3:context ctx))
     447   "return((int)sqlite3_aggregate_context(ctx, 1));"))
     448
     449(define-external (chicken_sqlite3_step_stub (c-pointer ctx) (int n) (c-pointer args)) void
    471450  (call-with-current-continuation
    472451   (lambda (q)
    473452     (dynamic-wind
    474          void
     453         noop
    475454         (lambda ()
    476455           (handle-exceptions exn
    477456               (print-error-message
    478457                exn (current-error-port) "Error in step of SQL function:")
    479              (let ((info (call-with/synch sqlite3:functions
    480                            (cut hash-table-tree-ref
    481                                 <> (sqlite3_user_data ctx)))))
    482                (call-with/synch sqlite3:seeds
     458             (let ((info (call-with/synch *sqlite3:functions*
     459                           (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))))
     460               (call-with/synch *sqlite3:seeds*
    483461                 (cut hash-table-update!/default
    484                       <> (sqlite3_aggregate_context ctx)
     462                      <>
     463                      (sqlite3_aggregate_context ctx)
    485464                      (lambda (seed)
    486465                        (apply
     
    497476     (let ((agc (sqlite3_aggregate_context ctx)))
    498477       (dynamic-wind
    499            void
     478           noop
    500479           (lambda ()
    501480             (handle-exceptions exn
    502                 (print-error-message
     481                (print-error-message
    503482                  exn (current-error-port) "Error in final of SQL function:")
    504                (let ((info (call-with/synch sqlite3:functions
    505                              (cut hash-table-tree-ref
    506                                   <> (sqlite3_user_data ctx)))))
     483               (let ((info (call-with/synch *sqlite3:functions*
     484                             (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))))
    507485                 (cond
    508486                  (((vector-ref info 3)
    509                     (call-with/synch sqlite3:seeds
     487                    (call-with/synch *sqlite3:seeds*
    510488                      (cut hash-table-ref/default <> agc (vector-ref info 2))))
    511489                   => (cut sqlite3:set-result! ctx <>))
     
    513491                   (sqlite3:set-result! ctx))))))
    514492           (lambda ()
    515              (call-with/synch sqlite3:seeds
     493             (call-with/synch *sqlite3:seeds*
    516494               (cut hash-table-delete! <> agc))
    517495             (q (void))))))))
     
    524502  (let ((qn (object-evict (list (pointer->address (slot-ref db 'this)) name))))
    525503    (cond
    526      (((foreign-lambda*
    527         sqlite3:status
    528         ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
    529         "return(sqlite3_create_function(db, name, n, SQLITE_UTF8,\n"
    530         "                               (void *)qn,\n"
    531         "                               (void (*)(sqlite3_context *,\n"
    532         "                                         int, sqlite3_value **))"
    533         "                                 &chicken_sqlite3_function_stub,\n"
    534         "                               NULL, NULL));\n")
     504     (((foreign-lambda* sqlite3:status
     505                        ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
     506#<<END
     507        return(sqlite3_create_function(db, name, n, SQLITE_UTF8,
     508                                       (void *)qn,
     509                                       (void (*)(sqlite3_context *, int,
     510                                                 sqlite3_value **))
     511                                       &chicken_sqlite3_function_stub,
     512                                       NULL,
     513                                       NULL));
     514END
     515       )
    535516       db name n qn)
    536517      => (lambda (s)
    537518           (object-release qn)
    538            ((sqlite3:error 'sqlite3:define-function db name n proc) s)))
     519           ((signal-error 'sqlite3:define-function db name n proc) s)))
    539520     (else
    540       (call-with/synch sqlite3:functions
    541         (cut hash-table-tree-set! <> qn (vector qn proc)))))))
     521      (call-with/synch *sqlite3:functions*
     522        (cut hash-table-tree-set! <> qn (vector qn proc)))))))
    542523
    543524(define-method (sqlite3:define-function (db <sqlite3:database>)
     
    550531  (let ((qn (object-evict (list (pointer->address (slot-ref db 'this)) name))))
    551532    (cond
    552      (((foreign-lambda*
    553         sqlite3:status
    554         ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
    555         "return(sqlite3_create_function(db, name, n, SQLITE_UTF8,\n"
    556         "                               (void *)qn,\n"
    557         "                               NULL,\n"
    558         "                               (void (*)(sqlite3_context *,\n"
    559         "                                         int, sqlite3_value **))"
    560         "                                 &chicken_sqlite3_step_stub,\n"
    561         "                               (void (*)(sqlite3_context *))\n"
    562         "                                 &chicken_sqlite3_final_stub));\n")
     533     (((foreign-lambda* sqlite3:status
     534                        ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
     535#<<END
     536        return(sqlite3_create_function(db, name, n, SQLITE_UTF8,
     537                                       (void *)qn,
     538                                       NULL,
     539                                       (void (*)(sqlite3_context *, int,
     540                                                 sqlite3_value **))
     541                                       &chicken_sqlite3_step_stub,
     542                                       ((void (*)(sqlite3_context *))
     543                                         &chicken_sqlite3_final_stub)));
     544END
     545       )
    563546       db name n qn)
    564547      => (lambda (s)
    565548           (object-release qn)
    566            ((sqlite3:error
     549           ((signal-error
    567550              'sqlite3:define-function db name n step-proc seed final-proc)
    568551            s)))
    569552     (else
    570       (call-with/synch sqlite3:functions
    571         (cut hash-table-tree-set!
    572              <> qn (vector qn step-proc seed final-proc)))))))
    573 
    574 ;; set a timeout until a busy error is thrown
     553      (call-with/synch *sqlite3:functions*
     554        (cut hash-table-tree-set! <> qn (vector qn step-proc seed final-proc)))))))
     555
     556;;; Database interface
     557
     558;; Get any error message
     559(define sqlite3:errmsg
     560  (foreign-lambda c-string "sqlite3_errmsg" sqlite3:database))
     561
     562;; Open a database
     563(define (sqlite3:open path)
     564  (check-type 'sqlite3:open path <string>)
     565  (let-location ((db c-pointer))
     566    (cond
     567     (((foreign-lambda sqlite3:status "sqlite3_open"
     568                                      nonnull-c-string (c-pointer sqlite3:database))
     569       (sqlite3:resolve-pathname path) (location db))
     570      => (signal-error 'sqlite3:open #f path))
     571     (else
     572      (make <sqlite3:database> 'this db)))))
     573
     574;; Set a timeout until a busy error is thrown
    575575(define (sqlite3:set-busy-timeout! db #!optional (ms 0))
    576576  (check-type 'sqlite3:set-busy-timeout! db <sqlite3:database>)
    577577  (cond
    578    (((foreign-lambda
    579       sqlite3:status "sqlite3_busy_timeout"
    580       sqlite3:database int)
    581      db ms)
    582     => (sqlite3:error 'sqlite3:set-busy-timeout! db db ms))))
    583 
    584 ;; cancel any running database operation as soon as possible
     578   (((foreign-lambda sqlite3:status "sqlite3_busy_timeout" sqlite3:database int) db ms)
     579    => (signal-error 'sqlite3:set-busy-timeout! db db ms))))
     580
     581;; Cancel any running database operation as soon as possible
    585582(define (sqlite3:interrupt! db)
    586583  (check-type 'sqlite3:interrupt! db <sqlite3:database>)
    587584  ((foreign-lambda void "sqlite3_interrupt" sqlite3:database) db))
    588585
    589 ;; check whether the database is in autocommit mode
     586;; Check whether the database is in autocommit mode
    590587(define (sqlite3:auto-committing? db)
    591588  (check-type 'sqlite3:auto-committing? db <sqlite3:database>)
    592589  ((foreign-lambda bool "sqlite3_get_autocommit" sqlite3:database) db))
    593590
    594 ;; get the number of changes made to the database
     591;; Get the number of changes made to the database
    595592(define (sqlite3:changes db #!optional (total #f))
    596593  (check-type 'sqlite3:changes db <sqlite3:database>)
     
    599596      ((foreign-lambda number "sqlite3_changes" sqlite3:database) db))
    600597
    601 ;; get the row ID of the last inserted row
     598;; Get the row ID of the last inserted row
    602599(define (sqlite3:last-insert-rowid db)
    603600  (check-type 'sqlite3:last-insert-rowid db <sqlite3:database>)
    604601  ((foreign-lambda number "sqlite3_last_insert_rowid" sqlite3:database) db))
    605602
    606 ;; close a database
     603;; Close a database
    607604(define-generic sqlite3:finalize!)
    608605(define-method (sqlite3:finalize! (db <sqlite3:database>))
     
    610607   ((not (slot-ref db 'this))
    611608    (void))
    612    (((foreign-lambda
    613       sqlite3:status "sqlite3_close"
    614       sqlite3:database)
    615      db)
    616     => (sqlite3:error 'sqlite3:finalize! db db))
     609   (((foreign-lambda sqlite3:status "sqlite3_close" sqlite3:database) db)
     610    => (signal-error 'sqlite3:finalize! db db))
    617611   (else
    618612    (let ((id (pointer->address (slot-ref db 'this)))
    619           (release-qns (lambda (_ info)
    620                          (object-release (vector-ref info 0)))))
    621       (call-with/synch sqlite3:collations
    622         (lambda (collations)
    623           (cond
    624            ((hash-table-ref/default collations id #f)
    625             => (cut hash-table-walk <> release-qns)))
    626           (hash-table-delete! collations id)))
    627       (call-with/synch sqlite3:functions
    628         (lambda (functions)
    629           (cond
    630            ((hash-table-ref/default functions id #f)
    631             => (cut hash-table-walk <> release-qns)))
    632           (hash-table-delete! functions id))))
    633     (slot-set! db 'this #f))))
    634 
    635 ;;; statement interface
    636 
    637 ;; create a new statement
     613          (release-qns (lambda (_ info) (object-release (vector-ref info 0)))))
     614      (call-with/synch *sqlite3:collations*
     615        (cut hash-table-tree-clear! <> id release-qns))
     616      (call-with/synch *sqlite3:functions*
     617        (cut hash-table-tree-clear! <> id release-qns)) )
     618    (slot-set! db 'this #f) ) ) )
     619
     620;;; Statement interface
     621
     622;; Create a new statement
    638623(define (sqlite3:prepare db sql)
    639624  (check-type 'sqlite3:prepare db <sqlite3:database>)
     
    641626  (let-location ((stmt c-pointer) (tail c-string))
    642627    (cond
    643      (((foreign-lambda
    644         sqlite3:status "sqlite3_prepare"
    645         sqlite3:database scheme-pointer int
    646         (c-pointer sqlite3:statement) (c-pointer (const c-string)))
     628     (((foreign-lambda sqlite3:status "sqlite3_prepare"
     629                                      sqlite3:database scheme-pointer int
     630                                      (c-pointer sqlite3:statement)
     631                                      (c-pointer (const c-string)))
    647632       db sql (string-length sql) (location stmt) (location tail))
    648       => (sqlite3:error 'sqlite3:prepare db db sql))
     633      => (signal-error 'sqlite3:prepare db db sql))
    649634     (else
    650635      (values
     
    652637       tail)))))
    653638
    654 ;; recompile an existing statement and transfer all bindings
     639;; Recompile an existing statement and transfer all bindings
    655640(define (sqlite3:repair! stmt)
    656641  (check-type 'sqlite3:repair! stmt <sqlite3:statement>)
     
    658643                (slot-ref stmt 'database) (slot-ref stmt 'sql))))
    659644    (dynamic-wind
    660         void
     645        noop
    661646        (lambda ()
    662647          (let ((old (slot-ref stmt 'this))
    663648                (new (slot-ref fresh 'this)))
    664649            (cond
    665              (((foreign-lambda
    666                 sqlite3:status "sqlite3_transfer_bindings"
    667                 c-pointer c-pointer)
     650             (((foreign-lambda sqlite3:status "sqlite3_transfer_bindings"
     651                                              c-pointer c-pointer)
    668652               old new)
    669               => (sqlite3:error
    670                   'sqlite3:repair! (slot-ref stmt 'database) stmt))
     653              => (signal-error 'sqlite3:repair! (slot-ref stmt 'database) stmt))
    671654             (else
    672655              (slot-set! stmt 'this new)
     
    675658          (sqlite3:finalize! fresh)))))
    676659
    677 ;; discard an existing statement
     660;; Discard an existing statement
    678661;; (define-generic sqlite3:finalize!)
    679662(define-method (sqlite3:finalize! (stmt <sqlite3:statement>))
     
    681664   ((not (slot-ref stmt 'this))
    682665    (void))
    683    (((foreign-lambda sqlite3:status "sqlite3_finalize" sqlite3:statement)
    684      stmt)
    685     => (sqlite3:error 'sqlite3:finalize! (slot-ref stmt 'database) stmt))
     666   (((foreign-lambda sqlite3:status "sqlite3_finalize" sqlite3:statement) stmt)
     667    => (signal-error 'sqlite3:finalize! (slot-ref stmt 'database) stmt))
    686668   (else
    687669    (slot-set! stmt 'this #f))))
    688670
    689 ;; reset an existing statement to process it again
     671;; Reset an existing statement to process it again
    690672(define sqlite3_reset
    691673  (foreign-lambda sqlite3:status "sqlite3_reset"sqlite3:statement))
     
    695677  (cond
    696678   ((sqlite3_reset stmt)
    697     => (sqlite3:error 'sqlite3:reset! (slot-ref stmt 'database) stmt))))
    698 
    699 ;; get number of bindable parameters
     679    => (signal-error 'sqlite3:reset! (slot-ref stmt 'database) stmt))))
     680
     681;; Get number of bindable parameters
    700682(define (sqlite3:bind-parameter-count stmt)
    701683  (check-type 'sqlite3:bind-parameter-count stmt <sqlite3:statement>)
    702   ((foreign-lambda
    703     int "sqlite3_bind_parameter_count"
    704     sqlite3:statement)
    705    stmt))
    706 
    707 ;; get index of a bindable parameter or #f if no parameter with the
     684  ((foreign-lambda int "sqlite3_bind_parameter_count" sqlite3:statement) stmt))
     685
     686;; Get index of a bindable parameter or #f if no parameter with the
    708687;; given name exists
    709688(define (sqlite3:bind-parameter-index stmt name)
    710689  (check-type 'sqlite3:bind-parameter-index stmt <sqlite3:statement>)
    711   (let ((i ((foreign-lambda
    712              int "sqlite3_bind_parameter_index"
    713              sqlite3:statement nonnull-c-string)
     690  (let ((i ((foreign-lambda int "sqlite3_bind_parameter_index"
     691                                sqlite3:statement nonnull-c-string)
    714692            stmt name)))
    715693    (if (zero? i) #f (sub1 i))))
    716694
    717 ;; get the name of a bindable parameter
     695;; Get the name of a bindable parameter
    718696(define (sqlite3:bind-parameter-name stmt i)
    719697  (check-type 'sqlite3:bind-parameter-name stmt <sqlite3:statement>)
    720   ((foreign-lambda
    721     c-string "sqlite3_bind_parameter_name"
    722     sqlite3:statement int)
    723    stmt (add1 i)))
    724 
    725 ;; bind data as parameters to an existing statement
     698  ((foreign-lambda c-string "sqlite3_bind_parameter_name" sqlite3:statement int) stmt (add1 i)))
     699
     700;; Bind data as parameters to an existing statement
     701
    726702(define-generic sqlite3:bind!)
    727703(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    728                               (v <blob>))
    729   (cond
    730    (((foreign-lambda*
    731       sqlite3:status
    732       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     704                              (v <blob>))
     705  (cond
     706   (((foreign-lambda* sqlite3:status
     707                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    733708      "return(sqlite3_bind_blob(stmt, i, v, n, SQLITE_TRANSIENT));")
    734709     stmt (add1 i) v (blob-size v))
    735     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     710    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    736711
    737712; Deprecated
    738713(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    739                               (v <byte-vector>))
    740   (cond
    741    (((foreign-lambda*
    742       sqlite3:status
    743       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     714                              (v <byte-vector>))
     715  (cond
     716   (((foreign-lambda* sqlite3:status
     717                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    744718      "return(sqlite3_bind_blob(stmt, i, v, n, SQLITE_TRANSIENT));")
    745719     stmt (add1 i) v (byte-vector-length v))
    746     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    747  
     720    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     721
    748722(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    749723                              (v <exact>))
    750724  (cond
    751    (((foreign-lambda
    752       sqlite3:status "sqlite3_bind_int"
    753       sqlite3:statement int int)
     725   (((foreign-lambda sqlite3:status "sqlite3_bind_int"
     726                                    sqlite3:statement int int)
    754727     stmt (add1 i) v)
    755     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     728    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    756729
    757730(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    758731                              (v <number>))
    759732  (cond
    760    (((foreign-lambda
    761       sqlite3:status "sqlite3_bind_double"
    762       sqlite3:statement int double)
     733   (((foreign-lambda sqlite3:status "sqlite3_bind_double"
     734                                    sqlite3:statement int double)
    763735     stmt (add1 i) v)
    764     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     736    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    765737
    766738(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    767739                              (v <string>))
    768740  (cond
    769    (((foreign-lambda*
    770       sqlite3:status
    771       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     741   (((foreign-lambda* sqlite3:status
     742                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    772743      "return(sqlite3_bind_text(stmt, i, v, n, SQLITE_TRANSIENT));")
    773744     stmt (add1 i) v (string-length v))
    774     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     745    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    775746
    776747(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    777748                              (v <void>))
    778749  (cond
    779    (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int)
    780      stmt (add1 i))
    781     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
     750   (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int) stmt (add1 i))
     751    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
    782752
    783753(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>))
    784754  (cond
    785    (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int)
    786      stmt (add1 i))
    787     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
    788 
    789 ;; single-step a prepared statement, return #t if data is available,
     755   (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int) stmt (add1 i))
     756    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
     757
     758;; Single-step a prepared statement, return #t if data is available,
    790759;; #f otherwise
    791760(define (sqlite3:step! stmt)
     
    805774              (retry))
    806775             (else
    807               ((sqlite3:error
     776              ((signal-error
    808777                'sqlite3:step! (slot-ref stmt 'database) stmt) s)))))
    809778        (else
    810          ((sqlite3:error 'sqlite3:step! (slot-ref stmt 'database) stmt) s))))))
    811 
    812 ;; retrieve information from a prepared/stepped statement
     779         ((signal-error 'sqlite3:step! (slot-ref stmt 'database) stmt) s))))))
     780
     781;; Retrieve information from a prepared/stepped statement
    813782(define (sqlite3:column-count stmt)
    814783  (check-type 'sqlite3:column-count stmt <sqlite3:statement>)
    815   ((foreign-lambda
    816     int "sqlite3_column_count"
    817     sqlite3:statement)
    818    stmt))
     784  ((foreign-lambda int "sqlite3_column_count" sqlite3:statement) stmt))
    819785
    820786(define (sqlite3:column-type stmt i)
    821787  (check-type 'sqlite3:column-type stmt <sqlite3:statement>)
    822   ((foreign-lambda
    823     sqlite3:type "sqlite3_column_type"
    824     sqlite3:statement int)
    825    stmt i))
     788  ((foreign-lambda sqlite3:type "sqlite3_column_type" sqlite3:statement int) stmt i))
    826789
    827790(define (sqlite3:column-declared-type stmt i)
    828791  (check-type 'sqlite3:column-declared-type stmt <sqlite3:statement>)
    829   ((foreign-lambda
    830     c-string "sqlite3_column_decltype"
    831     sqlite3:statement int)
    832    stmt i))
     792  ((foreign-lambda c-string "sqlite3_column_decltype" sqlite3:statement int) stmt i))
    833793
    834794(define (sqlite3:column-name stmt i)
    835795  (check-type 'sqlite3:column-name stmt <sqlite3:statement>)
    836   ((foreign-lambda
    837     c-string "sqlite3_column_name"
    838     sqlite3:statement int)
    839    stmt i))
    840 
    841 ;; retrieve data from a stepped statement
     796  ((foreign-lambda c-string "sqlite3_column_name" sqlite3:statement int) stmt i))
     797
     798;; Retrieve data from a stepped statement
    842799(define (sqlite3:column-data stmt i)
    843800  (case (sqlite3:column-type stmt i)
    844801    ((integer)
    845      ((foreign-lambda
    846        integer "sqlite3_column_double"
    847        sqlite3:statement int)
    848       stmt i))
     802     ((foreign-lambda integer "sqlite3_column_double" sqlite3:statement int) stmt i))
    849803    ((float)
    850      ((foreign-lambda
    851        double "sqlite3_column_double"
    852        sqlite3:statement int)
    853       stmt i))
     804     ((foreign-lambda double "sqlite3_column_double" sqlite3:statement int) stmt i))
    854805    ((text)
    855      ((foreign-primitive
    856        scheme-object ((sqlite3:statement stmt) (int i))
    857        "int n = sqlite3_column_bytes(stmt, i);\n"
    858        "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    859        "return(C_string(&s, n, (char *)sqlite3_column_text(stmt, i)));\n")
     806     ((foreign-primitive scheme-object ((sqlite3:statement stmt) (int i))
     807       "int n = sqlite3_column_bytes(stmt, i);"
     808       "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     809       "return(C_string(&s, n, (char *)sqlite3_column_text(stmt, i)));")
    860810      stmt i))
    861811    ((blob)
    862      ((foreign-primitive
    863        scheme-object ((sqlite3:statement stmt) (int i))
    864        "int n = sqlite3_column_bytes(stmt, i);\n"
    865        "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    866        "return(C_bytevector(&s, n, (char *)sqlite3_column_blob(stmt, i)));\n")
     812     ((foreign-primitive scheme-object ((sqlite3:statement stmt) (int i))
     813       "int n = sqlite3_column_bytes(stmt, i);"
     814       "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     815       "return(C_bytevector(&s, n, (char *)sqlite3_column_blob(stmt, i)));")
    867816      stmt i))
    868817    (else
    869      (void))))
    870 
    871 ;;; easy statement interface
    872 
    873 ;; compile a statement and call a procedure on it, then finalize the
     818     sqlite3:null-value)))
     819
     820;;; Easy statement interface
     821
     822;; Compile a statement and call a procedure on it, then finalize the
    874823;; statement in a dynamic-wind exit block if it hasn't been finalized yet.
    875824(define (sqlite3:call-with-temporary-statements proc db . sqls)
     
    887836            (set! stmts #f))))))
    888837
    889 ;; step through a statement and ignore possible results
     838;; Step through a statement and ignore possible results
    890839(define-generic sqlite3:exec)
    891840(define-method (sqlite3:exec (stmt <sqlite3:statement>) . params)
     
    894843   (cute sqlite3:bind! stmt <> <>)
    895844   (iota (sqlite3:bind-parameter-count stmt)) params)
    896   (do () ((not (sqlite3:step! stmt)) (void))))
     845  (do () ((not (sqlite3:step! stmt)) sqlite3:null-value)))
    897846
    898847(define-method (sqlite3:exec (db <sqlite3:database>) (sql <string>) . params)
     
    901850   db sql))
    902851
    903 ;; step through a statement, ignore possible results and return the
     852;; Step through a statement, ignore possible results and return the
    904853;; count of changes performed by this statement
    905854(define-generic sqlite3:update)
     
    913862  (sqlite3:changes db))
    914863
    915 ;; return only the first column of the first result row produced by this
     864;; Return only the first column of the first result row produced by this
    916865;; statement
     866
    917867(define-generic sqlite3:first-result)
    918868(define-method (sqlite3:first-result (stmt <sqlite3:statement>) . params)
     
    925875        (sqlite3:reset! stmt)
    926876        r)
    927       (signal
    928        (make-composite-condition
    929         (make-property-condition
    930          'exn
    931          'location 'sqlite3:first-result 'arguments (cons stmt params)
    932          'message "the statement returned no data")
    933         (make-property-condition
    934          'sqlite3
    935          'status 'done)))))
     877      (signal (make-no-data-condition stmt params)) ) )
    936878
    937879(define-method (sqlite3:first-result
     
    941883   db sql))
    942884
    943 ;; return only the first result row produced by this statement as a list
     885;; Return only the first result row produced by this statement as a list
     886
    944887(define-generic sqlite3:first-row)
    945888(define-method (sqlite3:first-row (stmt <sqlite3:statement>) . params)
     
    952895       (cute sqlite3:column-data stmt <>)
    953896       (iota (sqlite3:column-count stmt)))
    954       (signal
    955        (make-composite-condition
    956         (make-property-condition
    957          'exn
    958          'location 'sqlite3:first-row 'arguments (cons stmt params)
    959          'message "the statement returned no data")
    960         (make-property-condition
    961          'sqlite3
    962          'status 'done)))))
     897      (signal (make-no-data-condition stmt params)) ) )
    963898
    964899(define-method (sqlite3:first-row
     
    968903   db sql))
    969904
    970 ;; apply a procedure to the values of the result columns for each result row
     905;; Apply a procedure to the values of the result columns for each result row
    971906;; while executing the statement and discard the results
     907
    972908(define-generic sqlite3:for-each-row)
    973909(define-method (sqlite3:for-each-row
     
    978914   (iota (sqlite3:bind-parameter-count stmt)) params)
    979915  (do ((cl (iota (sqlite3:column-count stmt))))
    980       ((not (sqlite3:step! stmt)) (void))
     916      ((not (sqlite3:step! stmt)) sqlite3:null-value)
    981917    (apply proc (map (cute sqlite3:column-data stmt <>) cl))))
    982918
     
    988924   db sql))
    989925
    990 ;; apply a procedure to the values of the result columns for each result row
     926;; Apply a procedure to the values of the result columns for each result row
    991927;; while executing the statement and accumulate the results in a list
     928
    992929(define-generic sqlite3:map-row)
    993930(define-method (sqlite3:map-row
     
    1012949   db sql))
    1013950
    1014 ;;; utility procedures
    1015 
    1016 ;; run a thunk within a database transaction, commit if return value is
     951;;; Utility procedures
     952
     953;; Run a thunk within a database transaction, commit if return value is
    1017954;; true, rollback if return value is false or the thunk is interrupted by
    1018955;; an exception
     
    1023960    (abort
    1024961     (make-composite-condition
    1025       (make-property-condition
    1026        'exn
    1027        'location 'sqlite3:with-transaction 'arguments (list type)
    1028        'message (sprintf
    1029                  "bad argument ~a, expected deferred, immediate or exclusive"
    1030                  type))
     962      (make-exn-condition 'sqlite3:with-transaction
     963                          (format #f
     964                           "bad argument ~A, expected deferred, immediate or exclusive"
     965                           type)
     966                          type)
    1031967      (make-property-condition 'type))))
    1032968  (let ((success? #f))
    1033969    (dynamic-wind
    1034970        (lambda ()
    1035           (sqlite3:exec db (sprintf "BEGIN ~A TRANSACTION;" type)))
     971          (sqlite3:exec db (format #f "BEGIN ~a TRANSACTION;" type)))
    1036972        (lambda ()
    1037973          (set! success? (thunk)))
     
    1042978                  "ROLLBACK TRANSACTION;"))))))
    1043979
    1044 ;; check if the given string is a valid SQL statement
     980;; Check if the given string is a valid SQL statement
    1045981(define sqlite3:complete?
    1046982  (foreign-lambda bool "sqlite3_complete" nonnull-c-string))
    1047983
    1048 ;; return a descriptive version string
     984;; Return a descriptive version string
    1049985(define sqlite3:library-version
    1050986  (foreign-lambda c-string "sqlite3_libversion"))
  • release/3/sqlite3/tags/2.0.3/sqlite3.setup

    r6115 r7981  
    33(define so-file "sqlite3.so")
    44(compile
    5    ,@(if (string<? "2.636" (chicken-version)) '(-feature has-extended-define-foreign-enum) '())
    6   -O2 -d0 -X easyffi -X tinyclos -s "sqlite3.scm" -lsqlite3
     5  -O2 -d0 -X easyffi -X tinyclos -s sqlite3.scm -lsqlite3
    76  -o ,so-file
    87  -check-imports -emit-exports "sqlite3.exports")
     
    1110  `(,so-file
    1211    "sqlite3.html" "egg.jpg")
    13   '((version "2.0.1") (documentation "sqlite3.html")))
     12  '((version "2.0.3") (documentation "sqlite3.html")))
  • release/3/sqlite3/trunk/doc.scm

    r6115 r7981  
    66     (description (p "Bindings to version 3.x of the SQLite API."))
    77     (author (url "http://www.chust.org/" "Thomas Chust"))
     8     (usage)
     9     (download "sqlite3.egg")
     10     (requires "synch" "tinyclos" "easyffi")
     11
     12     (documentation
     13      (p "The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.")
     14      (p "For in-depth information on the functionality of the routines and general information you should consult the " (url "http://www.sqlite.org/" "SQLite documentation") " as well as this manual.")
     15
     16      (subsection
     17       "Exceptions"
     18       (p "Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind " (tt "(exn sqlite3)") " if something goes wrong. This exception will contain a " (tt "status") " property indicating the return value of the operation that failed:"
     19        (table
     20         (tr (th "Symbol") (th "Meaning"))
     21         #;(tr (td (tt "ok")) (td "Successful result"))
     22         (tr (td (tt "error")) (td "SQL error or missing database "))
     23         (tr (td (tt "internal")) (td "An internal logic error in SQLite "))
     24         (tr (td (tt "permission")) (td "Access permission denied "))
     25         (tr (td (tt "abort")) (td "Callback routine requested an abort "))
     26         (tr (td (tt "busy")) (td "The database file is locked "))
     27         (tr (td (tt "locked")) (td "A table in the database is locked "))
     28         (tr (td (tt "no-memory")) (td "A malloc() failed "))
     29         (tr (td (tt "read-only")) (td "Attempt to write a readonly database "))
     30         (tr (td (tt "interrupt")) (td "Operation terminated by sqlite-interrupt() "))
     31         (tr (td (tt "io-error")) (td "Some kind of disk I/O error occurred "))
     32         (tr (td (tt "corrupt")) (td "The database disk image is malformed "))
     33         (tr (td (tt "not-found")) (td "(Internal Only) Table or record not found "))
     34         (tr (td (tt "full")) (td "Insertion failed because database is full "))
     35         (tr (td (tt "cant-open")) (td "Unable to open the database file "))
     36         (tr (td (tt "protocol")) (td "Database lock protocol error "))
     37         (tr (td (tt "empty")) (td "(Internal Only) Database table is empty "))
     38         (tr (td (tt "schema")) (td "The database schema changed "))
     39         (tr (td (tt "too-big")) (td "Too much data for one row of a table "))
     40         (tr (td (tt "constraint")) (td "Abort due to contraint violation "))
     41         (tr (td (tt "mismatch")) (td "Data type mismatch "))
     42         (tr (td (tt "misuse")) (td "Library used incorrectly "))
     43         (tr (td (tt "no-lfs")) (td "Uses OS features not supported on host "))
     44         (tr (td (tt "authorization")) (td " Authorization denied"))
     45         #;(tr (td (tt "row")) (td (tt "sqlite3:step!") " has another row ready "))
     46         (tr (td (tt "done")) (td (tt "sqlite3:step!") " has finished executing, so no further data is ready")))))
     47
     48      (subsection
     49       "Classes"
     50       (group
     51        (definition
     52          (signatures
     53           (signature "class" "<sqlite3:database>")
     54           (signature "class" "<sqlite3:statement>"))
     55          (p "These classes are derived from " (tt "<c++-object>") ". They hold a pointer to the underlying C-structure in their " (tt "this") " slot.")
     56          (p (tt "<sqlite3:statement>") " also has a " (tt "database") " slot pointing to the database object it belongs to."))))
     57
     58      (subsection
     59       "Managing databases"
     60       (group
     61        (procedure
     62         "(sqlite3:open (path <string>)) => <sqlite3:database>"
     63         (p "Opens the indicated database file and returns a " (tt "<sqlite3:database>") " object for it.")
     64         (p "The given path is subject to the same special expansion as paths passed to " (p "open-input-file") " and similar procedures."))
     65        (definition
     66          (signatures
     67           (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>)) => <void>")
     68           (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>) (proc <procedure-class>)) => <void>"))
     69          (p "If " (tt "proc") " is given, registers a new collation sequence identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If no procedure is passed, the collation sequence with the given name is removed.")
     70          (p (tt "proc") " should have the signature " (tt "(proc (a <string>) (b <string>)) => <exact>") ". It should return a negative number if " (tt "a") " sorts before " (tt "b") ", a positive number if " (tt "b") " sorts before " (tt "a") " and zero if " (tt "a") " and " (tt "b") " are equal.")
     71          (p "As " (tt "proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a " (tt "0") " return value and warning messages."))
     72        (definition
     73          (signatures
     74           (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (proc <procedure-class>)) => <void>")
     75           (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (step-proc <procedure-class>) (seed <top>) #!optional ((final-proc <procedure-class>) identity)) => <void>"))
     76          (p "If " (tt "proc") " is given, registers a new SQL function identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If " (tt "step-proc") " and " (tt "final-proc") " are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.")
     77          (p (tt "n") " is the number of parameters the new SQL function takes or " (tt "-1") " to allow any number of arguments.")
     78          (p (tt "proc") " should have the signature " (tt "(proc . params) => <top>") ". It is called with the " (tt "n") " parameters given to the SQL function converted into Scheme objects like by " (tt "sqlite3:column-data") ". The return value is converted into an SQLite3 data object like by " (tt "sqlite3:bind!") ". A return value of " (tt "(void)") " corresponds to " (tt "NULL") " in SQLite3.")
     79          (p (tt "step-proc") " should have the signature " (tt "(step-proc (seed <top>) . params) => <top>") ". It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to " (tt "sqlite3:define-function") "; for subsequent calls it is the last value returned by " (tt "step-proc") " and after completion of " (tt "final-proc") " it will be the initial value again.")
     80          (p (tt "final-proc") " should have the signature " (tt "(final-proc (seed <top>)) => <top>") " and transforms the last seed value into the value to be returned from the aggregate function.")
     81          (p "As " (tt "proc") ", " (tt "step-proc") " and " (tt "final-proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in " (tt "NULL") " return values and warning messages."))
     82        (procedure
     83         "(sqlite3:set-busy-timeout! (db <sqlite3:database>) #!optional ((ms <exact>) 0)) => <void>"
     84         (p "Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If " (tt "(<= ms 0)") " though, all busy handlers for the database are uninstalled."))
     85        (procedure
     86         "(sqlite3:interrupt! (db <sqlite3:database>)) => <void>"
     87         (p "Cancels any running database operation as soon as possible.")
     88         (p "This function is always successful and never throws an exception."))
     89        (procedure
     90         "(sqlite3:auto-committing? (db <sqlite3:database>)) => <bool>"
     91         (p "Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.")
     92         (p "This function always returns a state and never throws an exception."))
     93        (procedure
     94         "(sqlite3:changes (db <sqlite3:database>) #!optional ((total <bool>) #f)) => <number>"
     95         (p "Returns the number of rows changed by the last statement (if " (tt "(not total)") ") or since the database was opened (if " (tt "total") ").")
     96         (p "This function always returns a count and never throws an exception."))
     97        (procedure
     98         "(sqlite3:last-insert-rowid (db <sqlite3:database>)) => <number>"
     99         (p "Returns the row ID of the last row inserted in " (tt "db") ".")
     100         (p "This function always returns a number and never throws an exception."))
     101        (method
     102         "(sqlite3:finalize! (db <sqlite3:database>)) => <void>"
     103         (p "Closes the given database."))))
     104
     105      (subsection
     106       "Managing statements"
     107       (group
     108        (procedure
     109         "(sqlite3:prepare (db <sqlite3:database>) (sql <string>)) => <sqlite3:statement>, <string>"
     110         (p "Compiles the first SQL statement in " (tt "sql") " and returns a " (tt "<sqlite3:statement>") " and the rest of " (tt "sql") ", which was not compiled (or an empty string)."))
     111        (procedure
     112         "(sqlite3:repair! (stmt <sqlite3:statement>)) => <void>"
     113         (p "Recompiles the SQL statement used to create " (tt "stmt") ", transfers all existing bindings from the old statement handle to the new one and destructively modifies " (tt "stmt") " to point to the new statement handle.")
     114         (p "If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.")
     115         (p "Usually you should not have to call this routine by hand. It is invoked by " (tt "sqlite3:step!") " to automagically repair a stale statement handle after a database schema change."))
     116        (procedure
     117         "(sqlite3:column-count (stmt <sqlite3:statement>)) => <exact>"
     118         (p "Can be applied to any statement and returns the number of columns it will return as results.")
     119         (p "This procedure always succeeds and never throws an exception."))
     120        (procedure
     121         "(sqlite3:column-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     122         (p "Can be applied to any statement and returns the name of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no name.")
     123         (p "This procedure always succeeds and never throws an exception."))
     124        (procedure
     125         "(sqlite3:column-declared-type (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     126         (p "Can be applied to any statement and returns the declared type (as given in the " (tt "CREATE") " statement) of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no declared type.")
     127         (p "This procedure always succeeds and never throws an exception."))
     128        (procedure
     129         "(sqlite3:bind-parameter-count (stmt <sqlite3:statement>)) => <exact>"
     130         (p "Can be applied to any statement and returns the number of free parameters that can be bound in the statement.")
     131         (p "This procedure always succeeds and never throws an exception."))
     132        (procedure
     133         "(sqlite3:bind-parameter-index (stmt <sqlite3:statement>) (name <string>)) => <exact>"
     134         (p "Can be applied to any statement and returns the index of the bindable parameter called " (tt "name") " or " (tt "#f") " if no such parameter exists.")
     135         (p "This procedure always succeeds and never throws an exception."))
     136        (procedure
     137         "(sqlite3:bind-parameter-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
     138         (p "Can be applied to any statement and returns the name of the bindable parameter number " (tt "i") " (counting from 0) or " (tt "#f") " if no such parameter exists or the parameter has no name.")
     139         (p "This procedure always succeeds and never throws an exception."))
     140        (definition
     141          (signatures
     142           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)) => <void>")
     143           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <void>)) => <void>")
     144           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <exact>)) => <void>")
     145           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <number>)) => <void>")
     146           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <string>)) => <void>")
     147           (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <byte-vector>)) => <void>"))
     148          (p "Can be applied to any statement to bind its free parameter number " (tt "i") " (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:"
     149             (table
     150              (tr (th "Scheme type") (th "SQLite type"))
     151              (tr (td "none") (td (tt "null")))
     152              (tr (td (tt "<sqlite3:null-value>")) (td (tt "null")))
     153              (tr (td (tt "<exact>")) (td (tt "integer")))
     154              (tr (td (tt "<number>")) (td (tt "float")))
     155              (tr (td (tt "<string>")) (td (tt "text")))
     156              (tr (td (tt "<byte-vector>")) (td (tt "blob")))))
     157          (p "Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing."))
     158        (procedure
     159         "(sqlite3:step! (stmt <sqlite3:statement>)) => <boolean>"
     160         (p "Single-steps the execution of " (tt "stmt") " and returns " (tt "#t") " if a result row was produced, " (tt "#f") " if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement."))
     161        (procedure
     162         "(sqlite3:column-type (stmt <sqlite3:statement>) (i <exact>)) => <symbol>"
     163         (p "Can be applied to a statement that has just been stepped (otherwise it returns " (tt "#f") ") and returns the SQLite type of the result column number " (tt "i") " (counting from 0) as a symbol.")
     164         (p "The return value can be one of the symbols " (tt "null") ", " (tt "integer") ", " (tt "float") ", " (tt "text") " or " (tt "blob") ".")
     165         (p "This procedure always succeeds and never throws an exception."))
     166        (procedure
     167         "(sqlite3:column-data (stmt <sqlite3:statement>) (i <exact>)) => <void | exact | number | string | byte-vector>"
     168         (p "Can be applied to a statement that has just been stepped. Consults " (tt "sqlite3:column-type") " to determine the type of the indicated column and to return its data as an appropriate scheme object.")
     169         (p "See " (tt "sqlite3:bind!") " for the mapping between Scheme and SQLite data types. Columns of type " (tt "null") " are returned as " (tt "<sqlite3:null-value>") ". Also keep in mind that CHICKEN's " (tt "<exact>") " datatype can only hold a subset of the values an SQLite " (tt "integer") " can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class " (tt "<integer>") ".")
     170         (p "This procedure always succeeds and never throws an exception."))
     171        (procedure
     172         "(sqlite3:reset! (stmt <sqlite3:statement>)) => <void>"
     173         (p "Can be applied to any statement and resets it such that execution using " (tt "sqlite3:step!") " will perform all operations of the statement again."))
     174        (method
     175         "(sqlite3:finalize! (stmt <sqlite3:statement>)) => <void>"
     176         (p "Must be applied to every statement to free its resources and discard it.")
     177         (p (tt "sqlite3:close") " will not be able to close a database that has associated unfinalized statements."))))
     178
     179      (subsection
     180       "Simple statement interface"
     181       (group
     182        (procedure
     183         "(sqlite3:call-with-temporary-statements (proc <procedure-class>) (db <sqlite3:database>) . sqls) => <top>"
     184         (p "Compiles the SQL sources in " (tt "sqls") " into statements in the context of " (tt "db") ", applies " (tt "proc") " to these statements and returns " (tt "proc") "'s result. The statements are created and finalized in " (tt "dynamic-wind") " entry and exit blocks around the application of " (tt "proc") "."))
     185        (definition
     186          (signatures
     187           (signature "method" "(sqlite3:exec (stmt <sqlite3:statement>) . params) => <void>")
     188           (signature "method" "(sqlite3:exec (db <sqlite3:database>) (sql <string>) . params) => <void>"))
     189          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it."))
     190        (definition
     191          (signatures
     192           (signature "method" "(sqlite3:update (stmt <sqlite3:statement>) . params) => <exact>")
     193           (signature "method" "(sqlite3:update (db <sqlite3:database>) (sql <string>) . params) => <exact>"))
     194          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying " (tt "sqlite3:changes") " to the affected database after the execution of the statement instead."))
     195        (definition
     196          (signatures
     197           (signature "method" "(sqlite3:first-result (stmt <sqlite3:statement>) . params) => <void | exact | number | string | byte-vector>")
     198           (signature "method" "(sqlite3:first-result (db <sqlite3:database>) (sql <string>) . params) => <void | exact | number | string | byte-vector>"))
     199          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.")
     200          (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
     201        (definition
     202          (signatures
     203           (signature "method" "(sqlite3:first-row (stmt <sqlite3:statement>) . params) => <list>")
     204           (signature "method" "(sqlite3:first-row (db <sqlite3:database>) (sql <string>) . params) => <list>"))
     205          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.")
     206          (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
     207        (definition
     208          (signatures
     209           (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <void>")
     210           (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <void>"))
     211          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of this application are discarded."))
     212        (definition
     213          (signatures
     214           (signature "method" "(sqlite3:map-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <list>")
     215           (signature "method" "(sqlite3:map-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <list>"))
     216          (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of these applications are collected into a list."))))
     217
     218      (subsection
     219       "Utility functions"
     220       (group
     221        (procedure
     222         "(sqlite3:with-transaction (db <sqlite3:database>) (thunk <procedure-class>) #!optional ((type <symbol>) 'deferred)) => <void>"
     223         (p "Runs " (tt "thunk") " within the scope of a transaction on the dataase " (tt "db") ".")
     224         (p "The transaction is committed upon exit from " (tt "thunk") " if " (tt "thunk") " returns a true value. If " (tt "thunk") " returns a false value or throws an exception, the transaction is rolled back.")
     225         (p "The " (tt "type") " of the transaction can be specified as one of the symbols " (tt "deferred") ", " (tt "immediate") " or " (tt "exclusive") "."))
     226        (procedure
     227         "(sqlite3:complete? (sql <string>)) => <boolean>"
     228         (p "Checks whether " (tt "sql") " comprises at least one complete SQL statement."))
     229        (procedure
     230         "(sqlite3:library-version) => <string>"
     231         (p "Returns a string identifying the version of SQLite in use."))
     232        (procedure
     233         "(sqlite3:null-value? <object>) => <boolean>"
     234         (p "Is the " (tt "<object>") " a <sqlite3:null-value>?")
     235         (p "The <sqlite3:null-value> is compatible with the \"sql-null\" egg. "
     236            "The default \"sql-null\" egg function " (code "(sql-null)") " "
     237            "= the <sqlite3:null-value>. "
     238            "But to ensure equality - " (code "(define sql-null sqlite3:null)") ".")))))
     239
    8240     (history
     241      (version "2.0.3" "Added " (code "sqlite3:null-value") ", " (code "sqlite3:null-value?") ", and " (code "sqlite3:null") ". [Kon Lovett]")
    9242      (version "2.0.2" "Use of extended " (tt "define-foreign-enum") ". Removed deprecated " (tt "pointer") " use. [Kon Lovett]")
    10243      (version "2.0.1" "Deprecated " (tt "<byte-vector>") ", use " (tt "<blob>") " [Kon Lovett]")
     
    33266      (version "1.0.1" "Fixed type mistakes in the source")
    34267      (version "1.0.0" "Initial release"))
    35      
    36      (usage)
    37      (download "sqlite3.egg")
    38      (requires "synch")
    39      
    40      (documentation
    41       (p "The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.")
    42       (p "For in-depth information on the functionality of the routines and general information you should consult the " (url "http://www.sqlite.org/" "SQLite documentation") " as well as this manual.")
    43       (p "Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind " (tt "(exn sqlite3)") " if something goes wrong. This exception will contain a " (tt "status") " property indicating the return value of the operation that failed:"
    44          (table
    45           (tr (th "Symbol") (th "Meaning"))
    46           ;; (tr (td (tt "ok")) (td "Successful result"))
    47           (tr (td (tt "error")) (td "SQL error or missing database "))
    48           (tr (td (tt "internal")) (td "An internal logic error in SQLite "))
    49           (tr (td (tt "permission")) (td "Access permission denied "))
    50           (tr (td (tt "abort")) (td "Callback routine requested an abort "))
    51           (tr (td (tt "busy")) (td "The database file is locked "))
    52           (tr (td (tt "locked")) (td "A table in the database is locked "))
    53           (tr (td (tt "no-memory")) (td "A malloc() failed "))
    54           (tr (td (tt "read-only")) (td "Attempt to write a readonly database "))
    55           (tr (td (tt "interrupt")) (td "Operation terminated by sqlite-interrupt() "))
    56           (tr (td (tt "io-error")) (td "Some kind of disk I/O error occurred "))
    57           (tr (td (tt "corrupt")) (td "The database disk image is malformed "))
    58           (tr (td (tt "not-found")) (td "(Internal Only) Table or record not found "))
    59           (tr (td (tt "full")) (td "Insertion failed because database is full "))
    60           (tr (td (tt "cant-open")) (td "Unable to open the database file "))
    61           (tr (td (tt "protocol")) (td "Database lock protocol error "))
    62           (tr (td (tt "empty")) (td "(Internal Only) Database table is empty "))
    63           (tr (td (tt "schema")) (td "The database schema changed "))
    64           (tr (td (tt "too-big")) (td "Too much data for one row of a table "))
    65           (tr (td (tt "constraint")) (td "Abort due to contraint violation "))
    66           (tr (td (tt "mismatch")) (td "Data type mismatch "))
    67           (tr (td (tt "misuse")) (td "Library used incorrectly "))
    68           (tr (td (tt "no-lfs")) (td "Uses OS features not supported on host "))
    69           (tr (td (tt "authorization")) (td " Authorization denied"))
    70           ;;(tr (td (tt "row")) (td (tt "sqlite3:step!") " has another row ready "))
    71           (tr (td (tt "done")) (td (tt "sqlite3:step!") " has finished executing, so no further data is ready"))
    72           ))
    73          
    74       (subsection
    75        "Classes"
    76        (group
    77         (definition
    78           (signatures
    79            (signature "class" "<sqlite3:database>")
    80            (signature "class" "<sqlite3:statement>"))
    81           (p "These classes are derived from " (tt "<c++-object>") ". They hold a pointer to the underlying C-structure in their " (tt "this") " slot.")
    82           (p (tt "<sqlite3:statement>") " also has a " (tt "database") " slot pointing to the database object it belongs to."))))
    83      
    84       (subsection
    85        "Managing databases"
    86        (group
    87         (procedure
    88          "(sqlite3:open (path <string>)) => <sqlite3:database>"
    89          (p "Opens the indicated database file and returns a " (tt "<sqlite3:database>") " object for it.")
    90          (p "The given path is subject to the same special expansion as paths passed to " (p "open-input-file") " and similar procedures."))
    91         (definition
    92           (signatures
    93            (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>)) => <void>")
    94            (signature "method" "(sqlite3:define-collation (db <sqlite3:database>) (name <string>) (proc <procedure-class>)) => <void>"))
    95           (p "If " (tt "proc") " is given, registers a new collation sequence identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If no procedure is passed, the collation sequence with the given name is removed.")
    96           (p (tt "proc") " should have the signature " (tt "(proc (a <string>) (b <string>)) => <exact>") ". It should return a negative number if " (tt "a") " sorts before " (tt "b") ", a positive number if " (tt "b") " sorts before " (tt "a") " and zero if " (tt "a") " and " (tt "b") " are equal.")
    97           (p "As " (tt "proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a " (tt "0") " return value and warning messages."))
    98         (definition
    99           (signatures
    100            (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (proc <procedure-class>)) => <void>")
    101            (signature "method" "(sqlite3:define-function (db <sqlite3:database>) (name <string>) (n <exact>) (step-proc <procedure-class>) (seed <top>) #!optional ((final-proc <procedure-class>) identity)) => <void>"))
    102           (p "If " (tt "proc") " is given, registers a new SQL function identified by " (tt "name") " for use in the context of database handle " (tt "db") ". If " (tt "step-proc") " and " (tt "final-proc") " are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.")
    103           (p (tt "n") " is the number of parameters the new SQL function takes or " (tt "-1") " to allow any number of arguments.")
    104           (p (tt "proc") " should have the signature " (tt "(proc . params) => <top>") ". It is called with the " (tt "n") " parameters given to the SQL function converted into Scheme objects like by " (tt "sqlite3:column-data") ". The return value is converted into an SQLite3 data object like by " (tt "sqlite3:bind!") ". A return value of " (tt "(void)") " corresponds to " (tt "NULL") " in SQLite3.")
    105           (p (tt "step-proc") " should have the signature " (tt "(step-proc (seed <top>) . params) => <top>") ". It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to " (tt "sqlite3:define-function") "; for subsequent calls it is the last value returned by " (tt "step-proc") " and after completion of " (tt "final-proc") " it will be the initial value again.")
    106           (p (tt "final-proc") " should have the signature " (tt "(final-proc (seed <top>)) => <top>") " and transforms the last seed value into the value to be returned from the aggregate function.")
    107           (p "As " (tt "proc") ", " (tt "step-proc") " and " (tt "final-proc") " will be called in a callback context from within " (tt "sqlite3:step!") ", safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in " (tt "NULL") " return values and warning messages."))
    108         (procedure
    109          "(sqlite3:set-busy-timeout! (db <sqlite3:database>) #!optional ((ms <exact>) 0)) => <void>"
    110          (p "Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If " (tt "(<= ms 0)") " though, all busy handlers for the database are uninstalled."))
    111         (procedure
    112          "(sqlite3:interrupt! (db <sqlite3:database>)) => <void>"
    113          (p "Cancels any running database operation as soon as possible.")
    114          (p "This function is always successful and never throws an exception."))
    115         (procedure
    116          "(sqlite3:auto-committing? (db <sqlite3:database>)) => <bool>"
    117          (p "Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.")
    118          (p "This function always returns a state and never throws an exception."))
    119         (procedure
    120          "(sqlite3:changes (db <sqlite3:database>) #!optional ((total <bool>) #f)) => <number>"
    121          (p "Returns the number of rows changed by the last statement (if " (tt "(not total)") ") or since the database was opened (if " (tt "total") ").")
    122          (p "This function always returns a count and never throws an exception."))
    123         (procedure
    124          "(sqlite3:last-insert-rowid (db <sqlite3:database>)) => <number>"
    125          (p "Returns the row ID of the last row inserted in " (tt "db") ".")
    126          (p "This function always returns a number and never throws an exception."))
    127         (method
    128          "(sqlite3:finalize! (db <sqlite3:database>)) => <void>"
    129          (p "Closes the given database."))))
    130      
    131       (subsection
    132        "Managing statements"
    133        (group
    134         (procedure
    135          "(sqlite3:prepare (db <sqlite3:database>) (sql <string>)) => <sqlite3:statement>, <string>"
    136          (p "Compiles the first SQL statement in " (tt "sql") " and returns a " (tt "<sqlite3:statement>") " and the rest of " (tt "sql") ", which was not compiled (or an empty string)."))
    137         (procedure
    138          "(sqlite3:repair! (stmt <sqlite3:statement>)) => <void>"
    139          (p "Recompiles the SQL statement used to create " (tt "stmt") ", transfers all existing bindings from the old statement handle to the new one and destructively modifies " (tt "stmt") " to point to the new statement handle.")
    140          (p "If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.")
    141          (p "Usually you should not have to call this routine by hand. It is invoked by " (tt "sqlite3:step!") " to automagically repair a stale statement handle after a database schema change."))
    142         (procedure
    143          "(sqlite3:column-count (stmt <sqlite3:statement>)) => <exact>"
    144          (p "Can be applied to any statement and returns the number of columns it will return as results.")
    145          (p "This procedure always succeeds and never throws an exception."))
    146         (procedure
    147          "(sqlite3:column-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    148          (p "Can be applied to any statement and returns the name of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no name.")
    149          (p "This procedure always succeeds and never throws an exception."))
    150         (procedure
    151          "(sqlite3:column-declared-type (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    152          (p "Can be applied to any statement and returns the declared type (as given in the " (tt "CREATE") " statement) of the column number " (tt "i") " (counting from 0) as a string or " (tt "#f") " if the column has no declared type.")
    153          (p "This procedure always succeeds and never throws an exception."))
    154         (procedure
    155          "(sqlite3:bind-parameter-count (stmt <sqlite3:statement>)) => <exact>"
    156          (p "Can be applied to any statement and returns the number of free parameters that can be bound in the statement.")
    157          (p "This procedure always succeeds and never throws an exception."))
    158         (procedure
    159          "(sqlite3:bind-parameter-index (stmt <sqlite3:statement>) (name <string>)) => <exact>"
    160          (p "Can be applied to any statement and returns the index of the bindable parameter called " (tt "name") " or " (tt "#f") " if no such parameter exists.")
    161          (p "This procedure always succeeds and never throws an exception."))
    162         (procedure
    163          "(sqlite3:bind-parameter-name (stmt <sqlite3:statement>) (i <exact>)) => <string>"
    164          (p "Can be applied to any statement and returns the name of the bindable parameter number " (tt "i") " (counting from 0) or " (tt "#f") " if no such parameter exists or the parameter has no name.")
    165          (p "This procedure always succeeds and never throws an exception."))
    166         (definition
    167           (signatures
    168            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)) => <void>")
    169            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <void>)) => <void>")
    170            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <exact>)) => <void>")
    171            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <number>)) => <void>")
    172            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <string>)) => <void>")
    173            (signature "method" "(sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>) (v <byte-vector>)) => <void>"))
    174           (p "Can be applied to any statement to bind its free parameter number " (tt "i") " (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:"
    175              (table
    176               (tr (th "Scheme type") (th "SQLite type"))
    177               (tr (td "none") (td (tt "null")))
    178               (tr (td (tt "<void>")) (td (tt "null")))
    179               (tr (td (tt "<exact>")) (td (tt "integer")))
    180               (tr (td (tt "<number>")) (td (tt "float")))
    181               (tr (td (tt "<string>")) (td (tt "text")))
    182               (tr (td (tt "<byte-vector>")) (td (tt "blob")))))
    183           (p "Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing."))
    184         (procedure
    185          "(sqlite3:step! (stmt <sqlite3:statement>)) => <boolean>"
    186          (p "Single-steps the execution of " (tt "stmt") " and returns " (tt "#t") " if a result row was produced, " (tt "#f") " if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement."))
    187         (procedure
    188          "(sqlite3:column-type (stmt <sqlite3:statement>) (i <exact>)) => <symbol>"
    189          (p "Can be applied to a statement that has just been stepped (otherwise it returns " (tt "#f") ") and returns the SQLite type of the result column number " (tt "i") " (counting from 0) as a symbol.")
    190          (p "The return value can be one of the symbols " (tt "null") ", " (tt "integer") ", " (tt "float") ", " (tt "text") " or " (tt "blob") ".")
    191          (p "This procedure always succeeds and never throws an exception."))
    192         (procedure
    193          "(sqlite3:column-data (stmt <sqlite3:statement>) (i <exact>)) => <void | exact | number | string | byte-vector>"
    194          (p "Can be applied to a statement that has just been stepped. Consults " (tt "sqlite3:column-type") " to determine the type of the indicated column and to return its data as an appropriate scheme object.")
    195          (p "See " (tt "sqlite3:bind!") " for the mapping between Scheme and SQLite data types. Columns of type " (tt "null") " are returned as " (tt "(void)") ". Also keep in mind that CHICKEN's " (tt "<exact>") " datatype can only hold a subset of the values an SQLite " (tt "integer") " can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class " (tt "<integer>") ".")
    196          (p "This procedure always succeeds and never throws an exception."))
    197         (procedure
    198          "(sqlite3:reset! (stmt <sqlite3:statement>)) => <void>"
    199          (p "Can be applied to any statement and resets it such that execution using " (tt "sqlite3:step!") " will perform all operations of the statement again."))
    200         (method
    201          "(sqlite3:finalize! (stmt <sqlite3:statement>)) => <void>"
    202          (p "Must be applied to every statement to free its resources and discard it.")
    203          (p (tt "sqlite3:close") " will not be able to close a database that has associated unfinalized statements."))))
    204 
    205       (subsection
    206        "Simple statement interface"
    207        (group
    208         (procedure
    209          "(sqlite3:call-with-temporary-statements (proc <procedure-class>) (db <sqlite3:database>) . sqls) => <top>"
    210          (p "Compiles the SQL sources in " (tt "sqls") " into statements in the context of " (tt "db") ", applies " (tt "proc") " to these statements and returns " (tt "proc") "'s result. The statements are created and finalized in " (tt "dynamic-wind") " entry and exit blocks around the application of " (tt "proc") "."))
    211         (definition
    212           (signatures
    213            (signature "method" "(sqlite3:exec (stmt <sqlite3:statement>) . params) => <void>")
    214            (signature "method" "(sqlite3:exec (db <sqlite3:database>) (sql <string>) . params) => <void>"))
    215           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it."))
    216         (definition
    217           (signatures
    218            (signature "method" "(sqlite3:update (stmt <sqlite3:statement>) . params) => <exact>")
    219            (signature "method" "(sqlite3:update (db <sqlite3:database>) (sql <string>) . params) => <exact>"))
    220           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying " (tt "sqlite3:changes") " to the affected database after the execution of the statement instead."))
    221         (definition
    222           (signatures
    223            (signature "method" "(sqlite3:first-result (stmt <sqlite3:statement>) . params) => <void | exact | number | string | byte-vector>")
    224            (signature "method" "(sqlite3:first-result (db <sqlite3:database>) (sql <string>) . params) => <void | exact | number | string | byte-vector>"))
    225           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.")
    226           (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
    227         (definition
    228           (signatures
    229            (signature "method" "(sqlite3:first-row (stmt <sqlite3:statement>) . params) => <list>")
    230            (signature "method" "(sqlite3:first-row (db <sqlite3:database>) (sql <string>) . params) => <list>"))
    231           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.")
    232           (p "If the given statement does not yield any results, an " (tt "(exn sqlite3)") " is thrown with the " (tt "status") "-property set to " (tt "done") "."))
    233         (definition
    234           (signatures
    235            (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <void>")
    236            (signature "method" "(sqlite3:for-each-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <void>"))
    237           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of this application are discarded."))
    238         (definition
    239           (signatures
    240            (signature "method" "(sqlite3:map-row (proc <procedure-class>) (stmt <sqlite3:statement>) . params) => <list>")
    241            (signature "method" "(sqlite3:map-row (proc <procedure-class>) (db <sqlite3:database>) (sql <string>) . params) => <list>"))
    242           (p "(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and " (tt "proc") " is applied to them. The results of these applications are collected into a list."))))
    243 
    244       (subsection
    245        "Utility functions"
    246        (group
    247         (procedure
    248          "(sqlite3:with-transaction (db <sqlite3:database>) (thunk <procedure-class>) #!optional ((type <symbol>) 'deferred)) => <void>"
    249          (p "Runs " (tt "thunk") " within the scope of a transaction on the dataase " (tt "db") ".")
    250          (p "The transaction is committed upon exit from " (tt "thunk") " if " (tt "thunk") " returns a true value. If " (tt "thunk") " returns a false value or throws an exception, the transaction is rolled back.")
    251          (p "The " (tt "type") " of the transaction can be specified as one of the symbols " (tt "deferred") ", " (tt "immediate") " or " (tt "exclusive") "."))
    252         (procedure
    253          "(sqlite3:complete? (sql <string>)) => <boolean>"
    254          (p "Checks whether " (tt "sql") " comprises at least one complete SQL statement."))
    255         (procedure
    256          "(sqlite3:library-version) => <string>"
    257          (p "Returns a string identifying the version of SQLite in use.")))))
    258      
     268
    259269      (license
    260270       "Copyright (c) 2005, Thomas Chust <chust@web.de>.  All rights reserved.
  • release/3/sqlite3/trunk/sqlite3.html

    r6115 r7981  
    156156<h3>Author</h3><a href="http://www.chust.org/">Thomas Chust</a></div>
    157157<div class="section">
     158<h3>Usage</h3><tt>(require-extension sqlite3)</tt></div>
     159<div class="section">
     160<h3>Download</h3><a href="sqlite3.egg">sqlite3.egg</a></div>
     161<div class="section">
     162<h3>Requires</h3>
     163<ul>
     164<li>synch</li>
     165<li>tinyclos</li>
     166<li>easyffi</li></ul></div>
     167<div class="section">
     168<h3>Documentation</h3>
     169<p>The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.</p>
     170<p>For in-depth information on the functionality of the routines and general information you should consult the <a href="http://www.sqlite.org/">SQLite documentation</a> as well as this manual.</p>
     171<div class="subsection">
     172<h4>Exceptions</h4>
     173<p>Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind <tt>(exn sqlite3)</tt> if something goes wrong. This exception will contain a <tt>status</tt> property indicating the return value of the operation that failed:
     174<table>
     175<tr>
     176<th>Symbol</th>
     177<th>Meaning</th></tr>
     178<tr>
     179<td><tt>error</tt></td>
     180<td>SQL error or missing database </td></tr>
     181<tr>
     182<td><tt>internal</tt></td>
     183<td>An internal logic error in SQLite </td></tr>
     184<tr>
     185<td><tt>permission</tt></td>
     186<td>Access permission denied </td></tr>
     187<tr>
     188<td><tt>abort</tt></td>
     189<td>Callback routine requested an abort </td></tr>
     190<tr>
     191<td><tt>busy</tt></td>
     192<td>The database file is locked </td></tr>
     193<tr>
     194<td><tt>locked</tt></td>
     195<td>A table in the database is locked </td></tr>
     196<tr>
     197<td><tt>no-memory</tt></td>
     198<td>A malloc() failed </td></tr>
     199<tr>
     200<td><tt>read-only</tt></td>
     201<td>Attempt to write a readonly database </td></tr>
     202<tr>
     203<td><tt>interrupt</tt></td>
     204<td>Operation terminated by sqlite-interrupt() </td></tr>
     205<tr>
     206<td><tt>io-error</tt></td>
     207<td>Some kind of disk I/O error occurred </td></tr>
     208<tr>
     209<td><tt>corrupt</tt></td>
     210<td>The database disk image is malformed </td></tr>
     211<tr>
     212<td><tt>not-found</tt></td>
     213<td>(Internal Only) Table or record not found </td></tr>
     214<tr>
     215<td><tt>full</tt></td>
     216<td>Insertion failed because database is full </td></tr>
     217<tr>
     218<td><tt>cant-open</tt></td>
     219<td>Unable to open the database file </td></tr>
     220<tr>
     221<td><tt>protocol</tt></td>
     222<td>Database lock protocol error </td></tr>
     223<tr>
     224<td><tt>empty</tt></td>
     225<td>(Internal Only) Database table is empty </td></tr>
     226<tr>
     227<td><tt>schema</tt></td>
     228<td>The database schema changed </td></tr>
     229<tr>
     230<td><tt>too-big</tt></td>
     231<td>Too much data for one row of a table </td></tr>
     232<tr>
     233<td><tt>constraint</tt></td>
     234<td>Abort due to contraint violation </td></tr>
     235<tr>
     236<td><tt>mismatch</tt></td>
     237<td>Data type mismatch </td></tr>
     238<tr>
     239<td><tt>misuse</tt></td>
     240<td>Library used incorrectly </td></tr>
     241<tr>
     242<td><tt>no-lfs</tt></td>
     243<td>Uses OS features not supported on host </td></tr>
     244<tr>
     245<td><tt>authorization</tt></td>
     246<td> Authorization denied</td></tr>
     247<tr>
     248<td><tt>done</tt></td>
     249<td><tt>sqlite3:step!</tt> has finished executing, so no further data is ready</td></tr></table></p></div>
     250<div class="subsection">
     251<h4>Classes</h4>
     252<dl>
     253<dt class="definition"><strong>class:</strong> &lt;sqlite3:database&gt;
     254<br /><strong>class:</strong> &lt;sqlite3:statement&gt;</dt>
     255<dd>
     256<p>These classes are derived from <tt>&lt;c++-object&gt;</tt>. They hold a pointer to the underlying C-structure in their <tt>this</tt> slot.</p>
     257<p><tt>&lt;sqlite3:statement&gt;</tt> also has a <tt>database</tt> slot pointing to the database object it belongs to.</p></dd></dl></div>
     258<div class="subsection">
     259<h4>Managing databases</h4>
     260<dl>
     261<dt class="definition"><strong>procedure:</strong> (sqlite3:open (path &lt;string&gt;)) =&gt; &lt;sqlite3:database&gt;</dt>
     262<dd>
     263<p>Opens the indicated database file and returns a <tt>&lt;sqlite3:database&gt;</tt> object for it.</p>
     264<p>The given path is subject to the same special expansion as paths passed to
     265<p>open-input-file</p> and similar procedures.</p></dd>
     266<dt class="definition"><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;)) =&gt; &lt;void&gt;
     267<br /><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;</dt>
     268<dd>
     269<p>If <tt>proc</tt> is given, registers a new collation sequence identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If no procedure is passed, the collation sequence with the given name is removed.</p>
     270<p><tt>proc</tt> should have the signature <tt>(proc (a &lt;string&gt;) (b &lt;string&gt;)) =&gt; &lt;exact&gt;</tt>. It should return a negative number if <tt>a</tt> sorts before <tt>b</tt>, a positive number if <tt>b</tt> sorts before <tt>a</tt> and zero if <tt>a</tt> and <tt>b</tt> are equal.</p>
     271<p>As <tt>proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a <tt>0</tt> return value and warning messages.</p></dd>
     272<dt class="definition"><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;
     273<br /><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (step-proc &lt;procedure-class&gt;) (seed &lt;top&gt;) #!optional ((final-proc &lt;procedure-class&gt;) identity)) =&gt; &lt;void&gt;</dt>
     274<dd>
     275<p>If <tt>proc</tt> is given, registers a new SQL function identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If <tt>step-proc</tt> and <tt>final-proc</tt> are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.</p>
     276<p><tt>n</tt> is the number of parameters the new SQL function takes or <tt>-1</tt> to allow any number of arguments.</p>
     277<p><tt>proc</tt> should have the signature <tt>(proc . params) =&gt; &lt;top&gt;</tt>. It is called with the <tt>n</tt> parameters given to the SQL function converted into Scheme objects like by <tt>sqlite3:column-data</tt>. The return value is converted into an SQLite3 data object like by <tt>sqlite3:bind!</tt>. A return value of <tt>(void)</tt> corresponds to <tt>NULL</tt> in SQLite3.</p>
     278<p><tt>step-proc</tt> should have the signature <tt>(step-proc (seed &lt;top&gt;) . params) =&gt; &lt;top&gt;</tt>. It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to <tt>sqlite3:define-function</tt>; for subsequent calls it is the last value returned by <tt>step-proc</tt> and after completion of <tt>final-proc</tt> it will be the initial value again.</p>
     279<p><tt>final-proc</tt> should have the signature <tt>(final-proc (seed &lt;top&gt;)) =&gt; &lt;top&gt;</tt> and transforms the last seed value into the value to be returned from the aggregate function.</p>
     280<p>As <tt>proc</tt>, <tt>step-proc</tt> and <tt>final-proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in <tt>NULL</tt> return values and warning messages.</p></dd>
     281<dt class="definition"><strong>procedure:</strong> (sqlite3:set-busy-timeout! (db &lt;sqlite3:database&gt;) #!optional ((ms &lt;exact&gt;) 0)) =&gt; &lt;void&gt;</dt>
     282<dd>
     283<p>Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If <tt>(&lt;= ms 0)</tt> though, all busy handlers for the database are uninstalled.</p></dd>
     284<dt class="definition"><strong>procedure:</strong> (sqlite3:interrupt! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
     285<dd>
     286<p>Cancels any running database operation as soon as possible.</p>
     287<p>This function is always successful and never throws an exception.</p></dd>
     288<dt class="definition"><strong>procedure:</strong> (sqlite3:auto-committing? (db &lt;sqlite3:database&gt;)) =&gt; &lt;bool&gt;</dt>
     289<dd>
     290<p>Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.</p>
     291<p>This function always returns a state and never throws an exception.</p></dd>
     292<dt class="definition"><strong>procedure:</strong> (sqlite3:changes (db &lt;sqlite3:database&gt;) #!optional ((total &lt;bool&gt;) #f)) =&gt; &lt;number&gt;</dt>
     293<dd>
     294<p>Returns the number of rows changed by the last statement (if <tt>(not total)</tt>) or since the database was opened (if <tt>total</tt>).</p>
     295<p>This function always returns a count and never throws an exception.</p></dd>
     296<dt class="definition"><strong>procedure:</strong> (sqlite3:last-insert-rowid (db &lt;sqlite3:database&gt;)) =&gt; &lt;number&gt;</dt>
     297<dd>
     298<p>Returns the row ID of the last row inserted in <tt>db</tt>.</p>
     299<p>This function always returns a number and never throws an exception.</p></dd>
     300<dt class="definition"><strong>method:</strong> (sqlite3:finalize! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
     301<dd>
     302<p>Closes the given database.</p></dd></dl></div>
     303<div class="subsection">
     304<h4>Managing statements</h4>
     305<dl>
     306<dt class="definition"><strong>procedure:</strong> (sqlite3:prepare (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;)) =&gt; &lt;sqlite3:statement&gt;, &lt;string&gt;</dt>
     307<dd>
     308<p>Compiles the first SQL statement in <tt>sql</tt> and returns a <tt>&lt;sqlite3:statement&gt;</tt> and the rest of <tt>sql</tt>, which was not compiled (or an empty string).</p></dd>
     309<dt class="definition"><strong>procedure:</strong> (sqlite3:repair! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     310<dd>
     311<p>Recompiles the SQL statement used to create <tt>stmt</tt>, transfers all existing bindings from the old statement handle to the new one and destructively modifies <tt>stmt</tt> to point to the new statement handle.</p>
     312<p>If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.</p>
     313<p>Usually you should not have to call this routine by hand. It is invoked by <tt>sqlite3:step!</tt> to automagically repair a stale statement handle after a database schema change.</p></dd>
     314<dt class="definition"><strong>procedure:</strong> (sqlite3:column-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
     315<dd>
     316<p>Can be applied to any statement and returns the number of columns it will return as results.</p>
     317<p>This procedure always succeeds and never throws an exception.</p></dd>
     318<dt class="definition"><strong>procedure:</strong> (sqlite3:column-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     319<dd>
     320<p>Can be applied to any statement and returns the name of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no name.</p>
     321<p>This procedure always succeeds and never throws an exception.</p></dd>
     322<dt class="definition"><strong>procedure:</strong> (sqlite3:column-declared-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     323<dd>
     324<p>Can be applied to any statement and returns the declared type (as given in the <tt>CREATE</tt> statement) of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no declared type.</p>
     325<p>This procedure always succeeds and never throws an exception.</p></dd>
     326<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
     327<dd>
     328<p>Can be applied to any statement and returns the number of free parameters that can be bound in the statement.</p>
     329<p>This procedure always succeeds and never throws an exception.</p></dd>
     330<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-index (stmt &lt;sqlite3:statement&gt;) (name &lt;string&gt;)) =&gt; &lt;exact&gt;</dt>
     331<dd>
     332<p>Can be applied to any statement and returns the index of the bindable parameter called <tt>name</tt> or <tt>#f</tt> if no such parameter exists.</p>
     333<p>This procedure always succeeds and never throws an exception.</p></dd>
     334<dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
     335<dd>
     336<p>Can be applied to any statement and returns the name of the bindable parameter number <tt>i</tt> (counting from 0) or <tt>#f</tt> if no such parameter exists or the parameter has no name.</p>
     337<p>This procedure always succeeds and never throws an exception.</p></dd>
     338<dt class="definition"><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void&gt;
     339<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;void&gt;)) =&gt; &lt;void&gt;
     340<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;exact&gt;)) =&gt; &lt;void&gt;
     341<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;number&gt;)) =&gt; &lt;void&gt;
     342<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;string&gt;)) =&gt; &lt;void&gt;
     343<br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;byte-vector&gt;)) =&gt; &lt;void&gt;</dt>
     344<dd>
     345<p>Can be applied to any statement to bind its free parameter number <tt>i</tt> (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:
     346<table>
     347<tr>
     348<th>Scheme type</th>
     349<th>SQLite type</th></tr>
     350<tr>
     351<td>none</td>
     352<td><tt>null</tt></td></tr>
     353<tr>
     354<td><tt>&lt;sqlite3:null-value&gt;</tt></td>
     355<td><tt>null</tt></td></tr>
     356<tr>
     357<td><tt>&lt;exact&gt;</tt></td>
     358<td><tt>integer</tt></td></tr>
     359<tr>
     360<td><tt>&lt;number&gt;</tt></td>
     361<td><tt>float</tt></td></tr>
     362<tr>
     363<td><tt>&lt;string&gt;</tt></td>
     364<td><tt>text</tt></td></tr>
     365<tr>
     366<td><tt>&lt;byte-vector&gt;</tt></td>
     367<td><tt>blob</tt></td></tr></table></p>
     368<p>Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing.</p></dd>
     369<dt class="definition"><strong>procedure:</strong> (sqlite3:step! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;boolean&gt;</dt>
     370<dd>
     371<p>Single-steps the execution of <tt>stmt</tt> and returns <tt>#t</tt> if a result row was produced, <tt>#f</tt> if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement.</p></dd>
     372<dt class="definition"><strong>procedure:</strong> (sqlite3:column-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;symbol&gt;</dt>
     373<dd>
     374<p>Can be applied to a statement that has just been stepped (otherwise it returns <tt>#f</tt>) and returns the SQLite type of the result column number <tt>i</tt> (counting from 0) as a symbol.</p>
     375<p>The return value can be one of the symbols <tt>null</tt>, <tt>integer</tt>, <tt>float</tt>, <tt>text</tt> or <tt>blob</tt>.</p>
     376<p>This procedure always succeeds and never throws an exception.</p></dd>
     377<dt class="definition"><strong>procedure:</strong> (sqlite3:column-data (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
     378<dd>
     379<p>Can be applied to a statement that has just been stepped. Consults <tt>sqlite3:column-type</tt> to determine the type of the indicated column and to return its data as an appropriate scheme object.</p>
     380<p>See <tt>sqlite3:bind!</tt> for the mapping between Scheme and SQLite data types. Columns of type <tt>null</tt> are returned as <tt>&lt;sqlite3:null-value&gt;</tt>. Also keep in mind that CHICKEN's <tt>&lt;exact&gt;</tt> datatype can only hold a subset of the values an SQLite <tt>integer</tt> can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class <tt>&lt;integer&gt;</tt>.</p>
     381<p>This procedure always succeeds and never throws an exception.</p></dd>
     382<dt class="definition"><strong>procedure:</strong> (sqlite3:reset! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     383<dd>
     384<p>Can be applied to any statement and resets it such that execution using <tt>sqlite3:step!</tt> will perform all operations of the statement again.</p></dd>
     385<dt class="definition"><strong>method:</strong> (sqlite3:finalize! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
     386<dd>
     387<p>Must be applied to every statement to free its resources and discard it.</p>
     388<p><tt>sqlite3:close</tt> will not be able to close a database that has associated unfinalized statements.</p></dd></dl></div>
     389<div class="subsection">
     390<h4>Simple statement interface</h4>
     391<dl>
     392<dt class="definition"><strong>procedure:</strong> (sqlite3:call-with-temporary-statements (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) . sqls) =&gt; &lt;top&gt;</dt>
     393<dd>
     394<p>Compiles the SQL sources in <tt>sqls</tt> into statements in the context of <tt>db</tt>, applies <tt>proc</tt> to these statements and returns <tt>proc</tt>'s result. The statements are created and finalized in <tt>dynamic-wind</tt> entry and exit blocks around the application of <tt>proc</tt>.</p></dd>
     395<dt class="definition"><strong>method:</strong> (sqlite3:exec (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
     396<br /><strong>method:</strong> (sqlite3:exec (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
     397<dd>
     398<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it.</p></dd>
     399<dt class="definition"><strong>method:</strong> (sqlite3:update (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;exact&gt;
     400<br /><strong>method:</strong> (sqlite3:update (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;exact&gt;</dt>
     401<dd>
     402<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying <tt>sqlite3:changes</tt> to the affected database after the execution of the statement instead.</p></dd>
     403<dt class="definition"><strong>method:</strong> (sqlite3:first-result (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;
     404<br /><strong>method:</strong> (sqlite3:first-result (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
     405<dd>
     406<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.</p>
     407<p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
     408<dt class="definition"><strong>method:</strong> (sqlite3:first-row (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
     409<br /><strong>method:</strong> (sqlite3:first-row (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
     410<dd>
     411<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.</p>
     412<p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
     413<dt class="definition"><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
     414<br /><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
     415<dd>
     416<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of this application are discarded.</p></dd>
     417<dt class="definition"><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
     418<br /><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
     419<dd>
     420<p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of these applications are collected into a list.</p></dd></dl></div>
     421<div class="subsection">
     422<h4>Utility functions</h4>
     423<dl>
     424<dt class="definition"><strong>procedure:</strong> (sqlite3:with-transaction (db &lt;sqlite3:database&gt;) (thunk &lt;procedure-class&gt;) #!optional ((type &lt;symbol&gt;) 'deferred)) =&gt; &lt;void&gt;</dt>
     425<dd>
     426<p>Runs <tt>thunk</tt> within the scope of a transaction on the dataase <tt>db</tt>.</p>
     427<p>The transaction is committed upon exit from <tt>thunk</tt> if <tt>thunk</tt> returns a true value. If <tt>thunk</tt> returns a false value or throws an exception, the transaction is rolled back.</p>
     428<p>The <tt>type</tt> of the transaction can be specified as one of the symbols <tt>deferred</tt>, <tt>immediate</tt> or <tt>exclusive</tt>.</p></dd>
     429<dt class="definition"><strong>procedure:</strong> (sqlite3:complete? (sql &lt;string&gt;)) =&gt; &lt;boolean&gt;</dt>
     430<dd>
     431<p>Checks whether <tt>sql</tt> comprises at least one complete SQL statement.</p></dd>
     432<dt class="definition"><strong>procedure:</strong> (sqlite3:library-version) =&gt; &lt;string&gt;</dt>
     433<dd>
     434<p>Returns a string identifying the version of SQLite in use.</p></dd>
     435<dt class="definition"><strong>procedure:</strong> (sqlite3:null-value? &lt;object&gt;) =&gt; &lt;boolean&gt;</dt>
     436<dd>
     437<p>Is the <tt>&lt;object&gt;</tt> a &lt;sqlite3:null-value&gt;?</p>
     438<p>The &lt;sqlite3:null-value&gt; is compatible with the &quot;sql-null&quot; egg. The default &quot;sql-null&quot; egg function <code>(sql-null)</code> = the &lt;sqlite3:null-value&gt;. But to ensure equality - <code>(define sql-null sqlite3:null)</code>.</p></dd></dl></div></div>
     439<div class="section">
    158440<h3>Version</h3>
    159441<ul>
     442<li>2.0.3 Added <code>sqlite3:null-value</code>, <code>sqlite3:null-value?</code>, and <code>sqlite3:null</code>. [Kon Lovett]</li>
    160443<li>2.0.2 Use of extended <tt>define-foreign-enum</tt>. Removed deprecated <tt>pointer</tt> use. [Kon Lovett]</li>
    161444<li>2.0.1 Deprecated <tt>&lt;byte-vector&gt;</tt>, use <tt>&lt;blob&gt;</tt> [Kon Lovett]</li>
     
    185468<li>1.0.0 Initial release</li></ul></div>
    186469<div class="section">
    187 <h3>Usage</h3><tt>(require-extension sqlite3)</tt></div>
    188 <div class="section">
    189 <h3>Download</h3><a href="sqlite3.egg">sqlite3.egg</a></div>
    190 <div class="section">
    191 <h3>Requires</h3>
    192 <ul>
    193 <li>synch</li></ul></div>
    194 <div class="section">
    195 <h3>Documentation</h3>
    196 <p>The API of SQLite changed significantly from version 2.x to 3.x. These are new bindings to the modified API, which are reasonably complete -- most procedures that take callback arguments are missing, though.</p>
    197 <p>For in-depth information on the functionality of the routines and general information you should consult the <a href="http://www.sqlite.org/">SQLite documentation</a> as well as this manual.</p>
    198 <p>Unless otherwise indicated, all procedures and methods in this egg may throw an exception of the kind <tt>(exn sqlite3)</tt> if something goes wrong. This exception will contain a <tt>status</tt> property indicating the return value of the operation that failed:
    199 <table>
    200 <tr>
    201 <th>Symbol</th>
    202 <th>Meaning</th></tr>
    203 <tr>
    204 <td><tt>error</tt></td>
    205 <td>SQL error or missing database </td></tr>
    206 <tr>
    207 <td><tt>internal</tt></td>
    208 <td>An internal logic error in SQLite </td></tr>
    209 <tr>
    210 <td><tt>permission</tt></td>
    211 <td>Access permission denied </td></tr>
    212 <tr>
    213 <td><tt>abort</tt></td>
    214 <td>Callback routine requested an abort </td></tr>
    215 <tr>
    216 <td><tt>busy</tt></td>
    217 <td>The database file is locked </td></tr>
    218 <tr>
    219 <td><tt>locked</tt></td>
    220 <td>A table in the database is locked </td></tr>
    221 <tr>
    222 <td><tt>no-memory</tt></td>
    223 <td>A malloc() failed </td></tr>
    224 <tr>
    225 <td><tt>read-only</tt></td>
    226 <td>Attempt to write a readonly database </td></tr>
    227 <tr>
    228 <td><tt>interrupt</tt></td>
    229 <td>Operation terminated by sqlite-interrupt() </td></tr>
    230 <tr>
    231 <td><tt>io-error</tt></td>
    232 <td>Some kind of disk I/O error occurred </td></tr>
    233 <tr>
    234 <td><tt>corrupt</tt></td>
    235 <td>The database disk image is malformed </td></tr>
    236 <tr>
    237 <td><tt>not-found</tt></td>
    238 <td>(Internal Only) Table or record not found </td></tr>
    239 <tr>
    240 <td><tt>full</tt></td>
    241 <td>Insertion failed because database is full </td></tr>
    242 <tr>
    243 <td><tt>cant-open</tt></td>
    244 <td>Unable to open the database file </td></tr>
    245 <tr>
    246 <td><tt>protocol</tt></td>
    247 <td>Database lock protocol error </td></tr>
    248 <tr>
    249 <td><tt>empty</tt></td>
    250 <td>(Internal Only) Database table is empty </td></tr>
    251 <tr>
    252 <td><tt>schema</tt></td>
    253 <td>The database schema changed </td></tr>
    254 <tr>
    255 <td><tt>too-big</tt></td>
    256 <td>Too much data for one row of a table </td></tr>
    257 <tr>
    258 <td><tt>constraint</tt></td>
    259 <td>Abort due to contraint violation </td></tr>
    260 <tr>
    261 <td><tt>mismatch</tt></td>
    262 <td>Data type mismatch </td></tr>
    263 <tr>
    264 <td><tt>misuse</tt></td>
    265 <td>Library used incorrectly </td></tr>
    266 <tr>
    267 <td><tt>no-lfs</tt></td>
    268 <td>Uses OS features not supported on host </td></tr>
    269 <tr>
    270 <td><tt>authorization</tt></td>
    271 <td> Authorization denied</td></tr>
    272 <tr>
    273 <td><tt>done</tt></td>
    274 <td><tt>sqlite3:step!</tt> has finished executing, so no further data is ready</td></tr></table></p>
    275 <div class="subsection">
    276 <h4>Classes</h4>
    277 <dl>
    278 <dt class="definition"><strong>class:</strong> &lt;sqlite3:database&gt;
    279 <br /><strong>class:</strong> &lt;sqlite3:statement&gt;</dt>
    280 <dd>
    281 <p>These classes are derived from <tt>&lt;c++-object&gt;</tt>. They hold a pointer to the underlying C-structure in their <tt>this</tt> slot.</p>
    282 <p><tt>&lt;sqlite3:statement&gt;</tt> also has a <tt>database</tt> slot pointing to the database object it belongs to.</p></dd></dl></div>
    283 <div class="subsection">
    284 <h4>Managing databases</h4>
    285 <dl>
    286 <dt class="definition"><strong>procedure:</strong> (sqlite3:open (path &lt;string&gt;)) =&gt; &lt;sqlite3:database&gt;</dt>
    287 <dd>
    288 <p>Opens the indicated database file and returns a <tt>&lt;sqlite3:database&gt;</tt> object for it.</p>
    289 <p>The given path is subject to the same special expansion as paths passed to
    290 <p>open-input-file</p> and similar procedures.</p></dd>
    291 <dt class="definition"><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;)) =&gt; &lt;void&gt;
    292 <br /><strong>method:</strong> (sqlite3:define-collation (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;</dt>
    293 <dd>
    294 <p>If <tt>proc</tt> is given, registers a new collation sequence identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If no procedure is passed, the collation sequence with the given name is removed.</p>
    295 <p><tt>proc</tt> should have the signature <tt>(proc (a &lt;string&gt;) (b &lt;string&gt;)) =&gt; &lt;exact&gt;</tt>. It should return a negative number if <tt>a</tt> sorts before <tt>b</tt>, a positive number if <tt>b</tt> sorts before <tt>a</tt> and zero if <tt>a</tt> and <tt>b</tt> are equal.</p>
    296 <p>As <tt>proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from it. Attempts to do so will result in a <tt>0</tt> return value and warning messages.</p></dd>
    297 <dt class="definition"><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (proc &lt;procedure-class&gt;)) =&gt; &lt;void&gt;
    298 <br /><strong>method:</strong> (sqlite3:define-function (db &lt;sqlite3:database&gt;) (name &lt;string&gt;) (n &lt;exact&gt;) (step-proc &lt;procedure-class&gt;) (seed &lt;top&gt;) #!optional ((final-proc &lt;procedure-class&gt;) identity)) =&gt; &lt;void&gt;</dt>
    299 <dd>
    300 <p>If <tt>proc</tt> is given, registers a new SQL function identified by <tt>name</tt> for use in the context of database handle <tt>db</tt>. If <tt>step-proc</tt> and <tt>final-proc</tt> are given, the new function becomes an aggregate function. Once registered, functions cannot be deleted.</p>
    301 <p><tt>n</tt> is the number of parameters the new SQL function takes or <tt>-1</tt> to allow any number of arguments.</p>
    302 <p><tt>proc</tt> should have the signature <tt>(proc . params) =&gt; &lt;top&gt;</tt>. It is called with the <tt>n</tt> parameters given to the SQL function converted into Scheme objects like by <tt>sqlite3:column-data</tt>. The return value is converted into an SQLite3 data object like by <tt>sqlite3:bind!</tt>. A return value of <tt>(void)</tt> corresponds to <tt>NULL</tt> in SQLite3.</p>
    303 <p><tt>step-proc</tt> should have the signature <tt>(step-proc (seed &lt;top&gt;) . params) =&gt; &lt;top&gt;</tt>. It is called with the parameters given to the SQL function for every row being processed. The seed value passed is initially the one given as an argument to <tt>sqlite3:define-function</tt>; for subsequent calls it is the last value returned by <tt>step-proc</tt> and after completion of <tt>final-proc</tt> it will be the initial value again.</p>
    304 <p><tt>final-proc</tt> should have the signature <tt>(final-proc (seed &lt;top&gt;)) =&gt; &lt;top&gt;</tt> and transforms the last seed value into the value to be returned from the aggregate function.</p>
    305 <p>As <tt>proc</tt>, <tt>step-proc</tt> and <tt>final-proc</tt> will be called in a callback context from within <tt>sqlite3:step!</tt>, safety measures are installed to avoid throwing any exceptions, invoking continuations or returning invalid values from them. Attempts to do such things will result in <tt>NULL</tt> return values and warning messages.</p></dd>
    306 <dt class="definition"><strong>procedure:</strong> (sqlite3:set-busy-timeout! (db &lt;sqlite3:database&gt;) #!optional ((ms &lt;exact&gt;) 0)) =&gt; &lt;void&gt;</dt>
    307 <dd>
    308 <p>Installs a busy handler that waits at least the specified amount of milliseconds for locks on the given database. If <tt>(&lt;= ms 0)</tt> though, all busy handlers for the database are uninstalled.</p></dd>
    309 <dt class="definition"><strong>procedure:</strong> (sqlite3:interrupt! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
    310 <dd>
    311 <p>Cancels any running database operation as soon as possible.</p>
    312 <p>This function is always successful and never throws an exception.</p></dd>
    313 <dt class="definition"><strong>procedure:</strong> (sqlite3:auto-committing? (db &lt;sqlite3:database&gt;)) =&gt; &lt;bool&gt;</dt>
    314 <dd>
    315 <p>Checks whether the database is currently in auto committing mode, i.e. no transaction is currently active.</p>
    316 <p>This function always returns a state and never throws an exception.</p></dd>
    317 <dt class="definition"><strong>procedure:</strong> (sqlite3:changes (db &lt;sqlite3:database&gt;) #!optional ((total &lt;bool&gt;) #f)) =&gt; &lt;number&gt;</dt>
    318 <dd>
    319 <p>Returns the number of rows changed by the last statement (if <tt>(not total)</tt>) or since the database was opened (if <tt>total</tt>).</p>
    320 <p>This function always returns a count and never throws an exception.</p></dd>
    321 <dt class="definition"><strong>procedure:</strong> (sqlite3:last-insert-rowid (db &lt;sqlite3:database&gt;)) =&gt; &lt;number&gt;</dt>
    322 <dd>
    323 <p>Returns the row ID of the last row inserted in <tt>db</tt>.</p>
    324 <p>This function always returns a number and never throws an exception.</p></dd>
    325 <dt class="definition"><strong>method:</strong> (sqlite3:finalize! (db &lt;sqlite3:database&gt;)) =&gt; &lt;void&gt;</dt>
    326 <dd>
    327 <p>Closes the given database.</p></dd></dl></div>
    328 <div class="subsection">
    329 <h4>Managing statements</h4>
    330 <dl>
    331 <dt class="definition"><strong>procedure:</strong> (sqlite3:prepare (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;)) =&gt; &lt;sqlite3:statement&gt;, &lt;string&gt;</dt>
    332 <dd>
    333 <p>Compiles the first SQL statement in <tt>sql</tt> and returns a <tt>&lt;sqlite3:statement&gt;</tt> and the rest of <tt>sql</tt>, which was not compiled (or an empty string).</p></dd>
    334 <dt class="definition"><strong>procedure:</strong> (sqlite3:repair! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    335 <dd>
    336 <p>Recompiles the SQL statement used to create <tt>stmt</tt>, transfers all existing bindings from the old statement handle to the new one and destructively modifies <tt>stmt</tt> to point to the new statement handle.</p>
    337 <p>If the operation is successful, the old handle is finalized, in case of error, the new handle is finalized and the old one stays untouched.</p>
    338 <p>Usually you should not have to call this routine by hand. It is invoked by <tt>sqlite3:step!</tt> to automagically repair a stale statement handle after a database schema change.</p></dd>
    339 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
    340 <dd>
    341 <p>Can be applied to any statement and returns the number of columns it will return as results.</p>
    342 <p>This procedure always succeeds and never throws an exception.</p></dd>
    343 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    344 <dd>
    345 <p>Can be applied to any statement and returns the name of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no name.</p>
    346 <p>This procedure always succeeds and never throws an exception.</p></dd>
    347 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-declared-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    348 <dd>
    349 <p>Can be applied to any statement and returns the declared type (as given in the <tt>CREATE</tt> statement) of the column number <tt>i</tt> (counting from 0) as a string or <tt>#f</tt> if the column has no declared type.</p>
    350 <p>This procedure always succeeds and never throws an exception.</p></dd>
    351 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-count (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;exact&gt;</dt>
    352 <dd>
    353 <p>Can be applied to any statement and returns the number of free parameters that can be bound in the statement.</p>
    354 <p>This procedure always succeeds and never throws an exception.</p></dd>
    355 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-index (stmt &lt;sqlite3:statement&gt;) (name &lt;string&gt;)) =&gt; &lt;exact&gt;</dt>
    356 <dd>
    357 <p>Can be applied to any statement and returns the index of the bindable parameter called <tt>name</tt> or <tt>#f</tt> if no such parameter exists.</p>
    358 <p>This procedure always succeeds and never throws an exception.</p></dd>
    359 <dt class="definition"><strong>procedure:</strong> (sqlite3:bind-parameter-name (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;string&gt;</dt>
    360 <dd>
    361 <p>Can be applied to any statement and returns the name of the bindable parameter number <tt>i</tt> (counting from 0) or <tt>#f</tt> if no such parameter exists or the parameter has no name.</p>
    362 <p>This procedure always succeeds and never throws an exception.</p></dd>
    363 <dt class="definition"><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void&gt;
    364 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;void&gt;)) =&gt; &lt;void&gt;
    365 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;exact&gt;)) =&gt; &lt;void&gt;
    366 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;number&gt;)) =&gt; &lt;void&gt;
    367 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;string&gt;)) =&gt; &lt;void&gt;
    368 <br /><strong>method:</strong> (sqlite3:bind! (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;) (v &lt;byte-vector&gt;)) =&gt; &lt;void&gt;</dt>
    369 <dd>
    370 <p>Can be applied to any statement to bind its free parameter number <tt>i</tt> (counting from 0) to the given value. Scheme types of the value map to SQLite types as follows:
    371 <table>
    372 <tr>
    373 <th>Scheme type</th>
    374 <th>SQLite type</th></tr>
    375 <tr>
    376 <td>none</td>
    377 <td><tt>null</tt></td></tr>
    378 <tr>
    379 <td><tt>&lt;void&gt;</tt></td>
    380 <td><tt>null</tt></td></tr>
    381 <tr>
    382 <td><tt>&lt;exact&gt;</tt></td>
    383 <td><tt>integer</tt></td></tr>
    384 <tr>
    385 <td><tt>&lt;number&gt;</tt></td>
    386 <td><tt>float</tt></td></tr>
    387 <tr>
    388 <td><tt>&lt;string&gt;</tt></td>
    389 <td><tt>text</tt></td></tr>
    390 <tr>
    391 <td><tt>&lt;byte-vector&gt;</tt></td>
    392 <td><tt>blob</tt></td></tr></table></p>
    393 <p>Unless there is internal trouble in SQLite3, this method should always succeeds and never throw an exception. For invalid parameter indices the method just silently does nothing.</p></dd>
    394 <dt class="definition"><strong>procedure:</strong> (sqlite3:step! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;boolean&gt;</dt>
    395 <dd>
    396 <p>Single-steps the execution of <tt>stmt</tt> and returns <tt>#t</tt> if a result row was produced, <tt>#f</tt> if no further results are available as the statement has been stepped through. This procedure must be called at least once before any results can be retrieved from the statement.</p></dd>
    397 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-type (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;symbol&gt;</dt>
    398 <dd>
    399 <p>Can be applied to a statement that has just been stepped (otherwise it returns <tt>#f</tt>) and returns the SQLite type of the result column number <tt>i</tt> (counting from 0) as a symbol.</p>
    400 <p>The return value can be one of the symbols <tt>null</tt>, <tt>integer</tt>, <tt>float</tt>, <tt>text</tt> or <tt>blob</tt>.</p>
    401 <p>This procedure always succeeds and never throws an exception.</p></dd>
    402 <dt class="definition"><strong>procedure:</strong> (sqlite3:column-data (stmt &lt;sqlite3:statement&gt;) (i &lt;exact&gt;)) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
    403 <dd>
    404 <p>Can be applied to a statement that has just been stepped. Consults <tt>sqlite3:column-type</tt> to determine the type of the indicated column and to return its data as an appropriate scheme object.</p>
    405 <p>See <tt>sqlite3:bind!</tt> for the mapping between Scheme and SQLite data types. Columns of type <tt>null</tt> are returned as <tt>(void)</tt>. Also keep in mind that CHICKEN's <tt>&lt;exact&gt;</tt> datatype can only hold a subset of the values an SQLite <tt>integer</tt> can store. Large integer values may therefore be returned as floating point numbers from the database, but they will still be of class <tt>&lt;integer&gt;</tt>.</p>
    406 <p>This procedure always succeeds and never throws an exception.</p></dd>
    407 <dt class="definition"><strong>procedure:</strong> (sqlite3:reset! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    408 <dd>
    409 <p>Can be applied to any statement and resets it such that execution using <tt>sqlite3:step!</tt> will perform all operations of the statement again.</p></dd>
    410 <dt class="definition"><strong>method:</strong> (sqlite3:finalize! (stmt &lt;sqlite3:statement&gt;)) =&gt; &lt;void&gt;</dt>
    411 <dd>
    412 <p>Must be applied to every statement to free its resources and discard it.</p>
    413 <p><tt>sqlite3:close</tt> will not be able to close a database that has associated unfinalized statements.</p></dd></dl></div>
    414 <div class="subsection">
    415 <h4>Simple statement interface</h4>
    416 <dl>
    417 <dt class="definition"><strong>procedure:</strong> (sqlite3:call-with-temporary-statements (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) . sqls) =&gt; &lt;top&gt;</dt>
    418 <dd>
    419 <p>Compiles the SQL sources in <tt>sqls</tt> into statements in the context of <tt>db</tt>, applies <tt>proc</tt> to these statements and returns <tt>proc</tt>'s result. The statements are created and finalized in <tt>dynamic-wind</tt> entry and exit blocks around the application of <tt>proc</tt>.</p></dd>
    420 <dt class="definition"><strong>method:</strong> (sqlite3:exec (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
    421 <br /><strong>method:</strong> (sqlite3:exec (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
    422 <dd>
    423 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the statement ignoring possible results from it.</p></dd>
    424 <dt class="definition"><strong>method:</strong> (sqlite3:update (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;exact&gt;
    425 <br /><strong>method:</strong> (sqlite3:update (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;exact&gt;</dt>
    426 <dd>
    427 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes the specified statement ignoring possible results from it, returning the result of applying <tt>sqlite3:changes</tt> to the affected database after the execution of the statement instead.</p></dd>
    428 <dt class="definition"><strong>method:</strong> (sqlite3:first-result (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;
    429 <br /><strong>method:</strong> (sqlite3:first-result (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void | exact | number | string | byte-vector&gt;</dt>
    430 <dd>
    431 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning the value of the first column in the first result row. Resets the statement again just before returning.</p>
    432 <p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
    433 <dt class="definition"><strong>method:</strong> (sqlite3:first-row (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
    434 <br /><strong>method:</strong> (sqlite3:first-row (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
    435 <dd>
    436 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and single-steps the statement once returning all columns in the first result row as a list.</p>
    437 <p>If the given statement does not yield any results, an <tt>(exn sqlite3)</tt> is thrown with the <tt>status</tt>-property set to <tt>done</tt>.</p></dd>
    438 <dt class="definition"><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;void&gt;
    439 <br /><strong>method:</strong> (sqlite3:for-each-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;void&gt;</dt>
    440 <dd>
    441 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of this application are discarded.</p></dd>
    442 <dt class="definition"><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (stmt &lt;sqlite3:statement&gt;) . params) =&gt; &lt;list&gt;
    443 <br /><strong>method:</strong> (sqlite3:map-row (proc &lt;procedure-class&gt;) (db &lt;sqlite3:database&gt;) (sql &lt;string&gt;) . params) =&gt; &lt;list&gt;</dt>
    444 <dd>
    445 <p>(Compiles the given SQL), resets the statement, binds the statement's free parameters and executes it step by step. After each step, the column values of the current result row are retrieved and <tt>proc</tt> is applied to them. The results of these applications are collected into a list.</p></dd></dl></div>
    446 <div class="subsection">
    447 <h4>Utility functions</h4>
    448 <dl>
    449 <dt class="definition"><strong>procedure:</strong> (sqlite3:with-transaction (db &lt;sqlite3:database&gt;) (thunk &lt;procedure-class&gt;) #!optional ((type &lt;symbol&gt;) 'deferred)) =&gt; &lt;void&gt;</dt>
    450 <dd>
    451 <p>Runs <tt>thunk</tt> within the scope of a transaction on the dataase <tt>db</tt>.</p>
    452 <p>The transaction is committed upon exit from <tt>thunk</tt> if <tt>thunk</tt> returns a true value. If <tt>thunk</tt> returns a false value or throws an exception, the transaction is rolled back.</p>
    453 <p>The <tt>type</tt> of the transaction can be specified as one of the symbols <tt>deferred</tt>, <tt>immediate</tt> or <tt>exclusive</tt>.</p></dd>
    454 <dt class="definition"><strong>procedure:</strong> (sqlite3:complete? (sql &lt;string&gt;)) =&gt; &lt;boolean&gt;</dt>
    455 <dd>
    456 <p>Checks whether <tt>sql</tt> comprises at least one complete SQL statement.</p></dd>
    457 <dt class="definition"><strong>procedure:</strong> (sqlite3:library-version) =&gt; &lt;string&gt;</dt>
    458 <dd>
    459 <p>Returns a string identifying the version of SQLite in use.</p></dd></dl></div></div>
    460 <div class="section">
    461470<h3>License</h3>
    462471<pre id="license">Copyright (c) 2005, Thomas Chust &lt;chust@web.de&gt;.  All rights reserved.
  • release/3/sqlite3/trunk/sqlite3.scm

    r6115 r7981  
    1010(define-extension sqlite3
    1111  (export
     12    ;; classes
    1213    initialize
    13     <sqlite3:database> <sqlite3:statement>
     14    <sqlite3:database>
     15    <sqlite3:statement>
     16    ;; methods & procedures
    1417    sqlite3:open
    15     sqlite3:define-collation sqlite3:define-function
    16     sqlite3:set-busy-timeout! sqlite3:interrupt!
    17     sqlite3:auto-committing? sqlite3:changes sqlite3:last-insert-rowid
     18    sqlite3:define-collation
     19    sqlite3:define-function
     20    sqlite3:set-busy-timeout!
     21    sqlite3:interrupt!
     22    sqlite3:auto-committing?
     23    sqlite3:changes
     24    sqlite3:last-insert-rowid
    1825    sqlite3:finalize!
    19     sqlite3:prepare sqlite3:repair! sqlite3:reset!
     26    sqlite3:prepare
     27    sqlite3:repair!
     28    sqlite3:reset!
    2029    sqlite3:bind-parameter-count
    21     sqlite3:bind-parameter-index sqlite3:bind-parameter-name
    22     sqlite3:bind! sqlite3:step!
    23     sqlite3:column-count sqlite3:column-type
    24     sqlite3:column-declared-type sqlite3:column-name
     30    sqlite3:bind-parameter-index
     31    sqlite3:bind-parameter-name
     32    sqlite3:bind!
     33    sqlite3:step!
     34    sqlite3:column-count
     35    sqlite3:column-type
     36    sqlite3:column-declared-type
     37    sqlite3:column-name
    2538    sqlite3:column-data
    2639    sqlite3:call-with-temporary-statements
    27     sqlite3:exec sqlite3:update sqlite3:first-result sqlite3:first-row
    28     sqlite3:for-each-row sqlite3:map-row
     40    sqlite3:exec
     41    sqlite3:update
     42    sqlite3:first-result
     43    sqlite3:first-row
     44    sqlite3:for-each-row
     45    sqlite3:map-row
    2946    sqlite3:with-transaction
    30     sqlite3:complete? sqlite3:library-version))
     47    sqlite3:complete?
     48    sqlite3:library-version
     49    ;; null type
     50    sqlite3:null
     51    sqlite3:null-value?
     52    sqlite3:null-value) )
    3153
    3254(declare
     
    3456  (fixnum-arithmetic)
    3557  (no-procedure-checks-for-usual-bindings)
    36   (disable-warning redef) ; redefinition of imported variable `initialize' from `tinyclos'
    37   (unused                 ; global variable '...' is never used
     58  ; redefinition of imported variable `initialize' from `tinyclos'
     59  (disable-warning redef)
     60  (unused
     61    ; global variable '...' is never used
    3862    chicken_sqlite3_function_stub
    3963    chicken_sqlite3_collation_stub
    4064    chicken_sqlite3_final_stub
    41     chicken_sqlite3_step_stub) )
     65    chicken_sqlite3_step_stub )
     66  (import
     67    ##sys#expand-home-path
     68    #;##sys#pathname-resolution )
     69  (bound-to-procedure
     70    sqlite3:errmsg ) )
    4271
    4372#>#include <sqlite3.h><#
     
    4776 extras lolevel tinyclos synch)
    4877
    49 ;;; enum and constant definitions
    50 
    51 (cond-expand
    52   (has-extended-define-foreign-enum
    53     (define-foreign-enum (sqlite3:status int)
    54       (ok               SQLITE_OK   #f)       ; Successful result
    55       (error            SQLITE_ERROR)         ; SQL error or missing database
    56       (internal         SQLITE_INTERNAL)      ; NOT USED. Internal logic error in SQLite
    57       (permission       SQLITE_PERM)          ; Access permission denied
    58       (abort            SQLITE_ABORT)         ; Callback routine requested an abort
    59       (busy             SQLITE_BUSY)          ; The database file is locked
    60       (locked           SQLITE_LOCKED)        ; A table in the database is locked
    61       (no-memory        SQLITE_NOMEM)         ; A malloc() failed
    62       (read-only        SQLITE_READONLY)      ; Attempt to write a readonly database
    63       (interrupt        SQLITE_INTERRUPT)     ; Operation terminated by sqlite3_interrupt()
    64       (io-error         SQLITE_IOERR)         ; Some kind of disk I/O error occurred
    65       (corrupt          SQLITE_CORRUPT)       ; The database disk image is malformed
    66       (not-found        SQLITE_NOTFOUND)      ; NOT USED. Table or record not found
    67       (full             SQLITE_FULL)          ; Insertion failed because database is full
    68       (cant-open        SQLITE_CANTOPEN)      ; Unable to open the database file
    69       (protocol         SQLITE_PROTOCOL)      ; NOT USED. Database lock protocol error
    70       (empty            SQLITE_EMPTY)         ; Database is empty
    71       (schema           SQLITE_SCHEMA)        ; The database schema changed
    72       (too-big          SQLITE_TOOBIG)        ; String or BLOB exceeds size limit
    73       (constraint       SQLITE_CONSTRAINT)    ; Abort due to contraint violation
    74       (mismatch         SQLITE_MISMATCH)      ; Data type mismatch
    75       (misuse           SQLITE_MISUSE)        ; Library used incorrectly
    76       (no-lfs           SQLITE_NOLFS)         ; Uses OS features not supported on host
    77       (authorization    SQLITE_AUTH)          ; Authorization denied
    78       (format           SQLITE_FORMAT)        ; Auxiliary database format error
    79       (range            SQLITE_RANGE)         ; 2nd parameter to sqlite3_bind out of range
    80       (not-a-database   SQLITE_NOTADB)        ; File opened that is not a database file
    81       (row              SQLITE_ROW)           ; sqlite3_step() has another row ready
    82       (done             SQLITE_DONE)          ; sqlite3_step() has finished executing
    83     )
    84    
    85     (define-foreign-enum (sqlite3:type int)
    86       (integer  SQLITE_INTEGER)
    87       (float    SQLITE_FLOAT)
    88       (text     SQLITE_TEXT)
    89       (blob     SQLITE_BLOB)
    90       (null     SQLITE_NULL)
    91     ) )
    92   (else   
    93     (define-macro (define-enum-type name . vars)
    94       (let ((pairs
    95        (let loop ((vars vars) (i 0))
    96          (if (null? vars)
    97              '()
    98              (let ((v (car vars)))
    99          (if (pair? v)
    100              (cons v (loop (cdr vars) (add1 (cdr v))))
    101              (cons (cons v i) (loop (cdr vars) (add1 i)))))))))
    102         `(define-foreign-type ,name int
    103            (lambda (sym)
    104        (case sym
    105          ,@(map (lambda (p) `((,(car p)) ,(cdr p))) pairs)
    106          (else #f)))
    107            (lambda (int)
    108        (switch int
    109          ,@(map (lambda (p) `(,(cdr p) ',(car p))) pairs)
    110          (else #f))))))
    111    
    112     (define-enum-type sqlite3:status
    113       ;;(ok . 0) ; Successful result
    114       (error . 1) ; SQL error or missing database
    115       internal ; An internal logic error in SQLite
    116       permission ; Access permission denied
    117       abort ; Callback routine requested an abort
    118       busy ; The database file is locked
    119       locked ; A table in the database is locked
    120       no-memory ; A malloc() failed
    121       read-only ; Attempt to write a readonly database
    122       interrupt ; Operation terminated by sqlite-interrupt()
    123       io-error ; Some kind of disk I/O error occurred
    124       corrupt ; The database disk image is malformed
    125       not-found ; (Internal Only) Table or record not found
    126       full ; Insertion failed because database is full
    127       cant-open ; Unable to open the database file
    128       protocol ; Database lock protocol error
    129       empty ; (Internal Only) Database table is empty
    130       schema ; The database schema changed
    131       too-big ; Too much data for one row of a table
    132       constraint ; Abort due to contraint violation
    133       mismatch ; Data type mismatch
    134       misuse ; Library used incorrectly
    135       no-lfs ; Uses OS features not supported on host
    136       authorization ;  Authorization denied
    137       (row . 100) ; sqlite-step() has another row ready
    138       done) ; sqlite-step() has finished executing
    139    
    140     (define-enum-type sqlite3:type
    141       (integer . 1)
    142       float
    143       text
    144       blob
    145       null) ) )
    146 
    147 ;;; Utilities
    148 
    149 (define (make-hash-table/synch id . args)
    150   (make-object/synch (apply make-hash-table args) id) )
    151 
    152 ;;; classes for databases and statements
     78;;; Foreign types & values
     79
     80;; Enumeration and constant definitions
     81
     82(define-foreign-enum (sqlite3:status int)
     83  #f ; no aliases
     84  (ok               SQLITE_OK   #f)       ; Successful result
     85  (error            SQLITE_ERROR)         ; SQL error or missing database
     86  (internal         SQLITE_INTERNAL)      ; NOT USED. Internal logic error in SQLite
     87  (permission       SQLITE_PERM)          ; Access permission denied
     88  (abort            SQLITE_ABORT)         ; Callback routine requested an abort
     89  (busy             SQLITE_BUSY)          ; The database file is locked
     90  (locked           SQLITE_LOCKED)        ; A table in the database is locked
     91  (no-memory        SQLITE_NOMEM)         ; A malloc() failed
     92  (read-only        SQLITE_READONLY)      ; Attempt to write a readonly database
     93  (interrupt        SQLITE_INTERRUPT)     ; Operation terminated by sqlite3_interrupt()
     94  (io-error         SQLITE_IOERR)         ; Some kind of disk I/O error occurred
     95  (corrupt          SQLITE_CORRUPT)       ; The database disk image is malformed
     96  (not-found        SQLITE_NOTFOUND)      ; NOT USED. Table or record not found
     97  (full             SQLITE_FULL)          ; Insertion failed because database is full
     98  (cant-open        SQLITE_CANTOPEN)      ; Unable to open the database file
     99  (protocol         SQLITE_PROTOCOL)      ; NOT USED. Database lock protocol error
     100  (empty            SQLITE_EMPTY)         ; Database is empty
     101  (schema           SQLITE_SCHEMA)        ; The database schema changed
     102  (too-big          SQLITE_TOOBIG)        ; String or BLOB exceeds size limit
     103  (constraint       SQLITE_CONSTRAINT)    ; Abort due to contraint violation
     104  (mismatch         SQLITE_MISMATCH)      ; Data type mismatch
     105  (misuse           SQLITE_MISUSE)        ; Library used incorrectly
     106  (no-lfs           SQLITE_NOLFS)         ; Uses OS features not supported on host
     107  (authorization    SQLITE_AUTH)          ; Authorization denied
     108  (format           SQLITE_FORMAT)        ; Auxiliary database format error
     109  (range            SQLITE_RANGE)         ; 2nd parameter to sqlite3_bind out of range
     110  (not-a-database   SQLITE_NOTADB)        ; File opened that is not a database file
     111  (row              SQLITE_ROW)           ; sqlite3_step() has another row ready
     112  (done             SQLITE_DONE) )        ; sqlite3_step() has finished executing
     113
     114(define-foreign-enum (sqlite3:type int)
     115  #f ; no aliases
     116  (integer  SQLITE_INTEGER)
     117  (float    SQLITE_FLOAT)
     118  (text     SQLITE_TEXT)
     119  (blob     SQLITE_BLOB)
     120  (null     SQLITE_NULL) )
     121
     122;; Types
     123
     124(define-foreign-type sqlite3:context (c-pointer "sqlite3_context"))
     125
     126(define-foreign-type sqlite3:value (c-pointer "sqlite3_value"))
     127
     128(define sqlite3:null void)
     129
     130(define sqlite3:null-value (sqlite3:null))
     131
     132(define (sqlite3:null-value? obj)
     133  (eq? sqlite3:null-value obj) )
     134
     135;;; Classes for databases and statements
    153136
    154137(define-class <sqlite3:database> (<c++-object>) ())
     
    157140  (lambda (db)
    158141    (unless (slot-ref db 'this)
    159       (sqlite3:null-error 'sqlite3:database->c-pointer db))
     142      (signal-null-error 'sqlite3:database->c-pointer db))
    160143    db))
    161144
     
    165148  (lambda (stmt)
    166149    (unless (slot-ref stmt 'this)
    167       (sqlite3:null-error 'sqlite3:statement->c-pointer stmt))
     150      (signal-null-error 'sqlite3:statement->c-pointer stmt))
    168151    stmt))
    169152
     
    172155  (initialize-slots this initargs))
    173156
    174 (define-foreign-type sqlite3:context
    175   (c-pointer "sqlite3_context"))
    176 
    177 (define-foreign-type sqlite3:value
    178   (c-pointer "sqlite3_value"))
    179 
    180 ;;; helper functions
    181 
    182 (define sqlite3:errmsg
    183   (foreign-lambda c-string "sqlite3_errmsg" sqlite3:database))
    184 
    185 (define ((sqlite3:error loc db . args) s)
     157;;; Helpers
     158
     159;; Expand variables in pathname
     160(define sqlite3:resolve-pathname
     161  ##sys#expand-home-path
     162  #; ;not needed, yet
     163  (cut ##sys#pathname-resolution <> identity))
     164
     165;; Conditions
     166
     167(define (make-exn-condition loc msg . args)
     168  (make-property-condition 'exn 'location loc 'message msg 'arguments args) )
     169
     170(define (make-sqlite3-condition sta)
     171  (make-property-condition 'sqlite3 'status sta) )
     172
     173(define (make-sqlite3-error-condition loc msg sta . args)
     174   (make-composite-condition
     175    (apply make-exn-condition loc msg args)
     176    (make-sqlite3-condition sta)) )
     177
     178(define (make-no-data-condition stmt params)
     179  (make-sqlite3-error-condition 'sqlite3:first-result
     180                                "the statement returned no data"
     181                                'done
     182                                stmt params) )
     183
     184;; Errors
     185
     186(define ((signal-error loc db . args) sta)
    186187  (signal
    187    (make-composite-condition
    188     (make-property-condition
    189      'exn
    190      'location loc 'arguments args
    191      'message (if db (sqlite3:errmsg db) (symbol->string s)))
    192     (make-property-condition
    193      'sqlite3
    194      'status s))))
    195 
    196 (define (sqlite3:null-error loc obj)
     188   (apply make-sqlite3-error-condition loc
     189                                       (if db (sqlite3:errmsg db) (symbol->string sta))
     190                                       sta
     191                                       args)) )
     192
     193(define (signal-null-error loc obj)
    197194  (signal
    198    (make-composite-condition
    199     (make-property-condition
    200      'exn
    201      'location loc 'arguments (list obj)
    202      'message (sprintf
    203                "bad ~a object, contained pointer is #f"
    204                (class-name (class-of obj))))
    205     (make-property-condition
    206      'sqlite3
    207      'status 'error))))
     195   (make-sqlite3-error-condition loc
     196                                 (format #f "bad ~A object, contained pointer is #f"
     197                                            (class-name (class-of obj)))
     198                                 'error
     199                                 obj)) )
    208200
    209201(define (check-type loc obj class)
     
    211203    (abort
    212204     (make-composite-condition
    213       (make-property-condition
    214        'exn
    215        'location loc 'arguments (list obj)
    216        'message (sprintf
    217                  "bad argument type ~a, expected ~a"
    218                  (class-name (class-of obj)) (class-name class)))
    219       (make-property-condition 'type)))))
     205      (make-exn-condition loc
     206                          (format #f "bad argument type ~A, expected ~A"
     207                                     (class-name (class-of obj)) (class-name class))
     208                          obj)
     209      (make-property-condition 'type)))) )
     210
     211;; Tree dictionary
     212
     213(define (make-hash-table-tree/synch id . args)
     214  (make-object/synch (apply make-hash-table args) id) )
    220215
    221216(define (hash-table-tree-set! ht-tree keys value)
     
    244239                             (signal
    245240                              (make-composite-condition
    246                                (make-property-condition
    247                                 'exn
    248                                 'location 'hash-table-tree-ref
    249                                 'message "hash-table-tree does not contain path"
    250                                 'arguments (list ht-tree keys))
    251                                (make-property-condition
    252                                 'access))))))
     241                               (make-exn-condition 'hash-table-tree-ref
     242                                                   "hash-table-tree does not contain path"
     243                                                   ht-tree keys)
     244                               (make-property-condition 'access))))))
    253245  (call-with-current-continuation
    254246   (lambda (q)
     
    263255  (hash-table-tree-ref ht-tree keys (lambda () default)))
    264256
    265 ;;; database interface
    266 
    267 ;; open a database
    268 (define (sqlite3:open path)
    269   (check-type 'sqlite3:open path <string>)
    270   (let-location ((db c-pointer))
    271     (cond
    272      (((foreign-lambda
    273         sqlite3:status "sqlite3_open"
    274         nonnull-c-string (c-pointer sqlite3:database))
    275        (##sys#expand-home-path path) (location db))
    276       => (sqlite3:error 'sqlite3:open #f path))
    277      (else
    278       (make <sqlite3:database> 'this db)))))
    279 
    280 ;; define a new collation sequence or remove an existing one
    281 
    282 (define sqlite3:collations (make-hash-table/synch 'sqlite3:collations))
    283 
    284 (define-external (chicken_sqlite3_collation_stub (scheme-object qn)
    285                                                  (int la) (c-pointer da)
    286                                                  (int lb) (c-pointer db)) int
     257(define (hash-table-tree-clear! htt id elt-clear)
     258  (cond ((hash-table-ref/default htt id #f)
     259         => (cut hash-table-walk <> elt-clear)))
     260  (hash-table-delete! htt id) )
     261
     262;; SQL collation sequence interface
     263
     264(define *sqlite3:collations* (make-hash-table-tree/synch 'sqlite3:collations))
     265
     266(define-external (chicken_sqlite3_collation_stub (scheme-object qn) (int la)
     267                                                 (c-pointer da) (int lb)
     268                                                 (c-pointer db))
     269                 int
    287270  (call-with-current-continuation
    288271   (lambda (q)
    289272     (let ((r #f))
    290273       (dynamic-wind
    291            void
     274           noop
    292275           (lambda ()
    293276             (handle-exceptions exn
     
    299282                 (set! r
    300283                   ((vector-ref
    301                      (call-with/synch sqlite3:collations
     284                     (call-with/synch *sqlite3:collations*
    302285                       (cut hash-table-tree-ref <> qn))
    303286                     1)
     
    307290                 (q r)
    308291                 (begin
    309                    (fprintf
     292                   (format
    310293                    (current-error-port)
    311                     "Error in collation function: invalid return value: ~s~%"
     294                    "Error in collation function: invalid return value: ~S~%"
    312295                    r)
    313296                   (q 0)))))))))
    314297
    315298(define sqlite3_create_collation
    316   (foreign-lambda*
    317    sqlite3:status ((sqlite3:database db) (c-string name) (scheme-object qn))
    318    "if (qn == C_SCHEME_FALSE)\n"
    319    "  return(sqlite3_create_collation(db, name, SQLITE_UTF8, NULL, NULL));\n"
    320    "else\n"
    321    "  return(sqlite3_create_collation(db, name, SQLITE_UTF8,\n"
    322    "                                  (void *)qn,\n"
    323    "                                  (int (*)(void *,\n"
    324    "                                           int, const void *,\n"
    325    "                                           int, const void *))"
    326    "                                    &chicken_sqlite3_collation_stub));\n"))
     299  (foreign-lambda* sqlite3:status
     300                  ((sqlite3:database db) (c-string name) (scheme-object qn))
     301#<<END
     302  if (qn == C_SCHEME_FALSE)
     303    return(sqlite3_create_collation(db, name, SQLITE_UTF8, NULL, NULL));
     304  else
     305    return(sqlite3_create_collation(db, name, SQLITE_UTF8,
     306                                      (void *)qn,
     307                                      (int (*)(void *,
     308                                               int, const void *,
     309                                               int, const void *))
     310                                        &chicken_sqlite3_collation_stub));
     311END
     312  ))
    327313
    328314(define-generic sqlite3:define-collation)
     
    331317  (cond
    332318   ((sqlite3_create_collation db name #f)
    333     => (sqlite3:error 'sqlite3:define-collation db name))
     319    => (signal-error 'sqlite3:define-collation db name))
    334320   (else
    335321    (let ((qn (list (pointer->address (slot-ref db 'this)) name)))
    336       (call-with/synch sqlite3:collations
     322      (call-with/synch *sqlite3:collations*
    337323        (lambda (col)
    338324          (cond
     
    350336      => (lambda (s)
    351337           (object-release qn)
    352            ((sqlite3:error 'sqlite3:define-collation db name proc) s)))
     338           ((signal-error 'sqlite3:define-collation db name proc) s)))
    353339     (else
    354       (call-with/synch sqlite3:collations
     340      (call-with/synch *sqlite3:collations*
    355341        (cut hash-table-tree-set! <> qn (vector qn proc)))))))
    356342
    357 ;; define a new SQL function or remove an existing one
     343;;; SQL function interface
     344
     345(define *sqlite3:functions* (make-hash-table-tree/synch 'sqlite3:functions))
     346
     347(define *sqlite3:seeds* (make-hash-table-tree/synch 'sqlite3:seeds))
    358348
    359349(define (sqlite3:parameter-data n args)
     
    361351    (if (< i n)
    362352        (cons
    363          (case ((foreign-lambda*
    364                  sqlite3:type (((c-pointer sqlite3:value) args) (int i))
    365                  "return(sqlite3_value_type(args[i]));\n")
     353         (case ((foreign-lambda* sqlite3:type
     354                                (((c-pointer sqlite3:value) args) (int i))
     355                 "return(sqlite3_value_type(args[i]));")
    366356                args i)
    367357           ((integer)
    368             ((foreign-lambda*
    369               integer (((c-pointer sqlite3:value) args) (int i))
    370               "return(sqlite3_value_double(args[i]));\n")
     358            ((foreign-lambda* integer
     359                              (((c-pointer sqlite3:value) args) (int i))
     360              "return(sqlite3_value_double(args[i]));")
    371361             args i))
    372362           ((float)
    373             ((foreign-lambda*
    374               double (((c-pointer sqlite3:value) args) (int i))
    375               "return(sqlite3_value_double(args[i]));\n")
     363            ((foreign-lambda* double
     364                              (((c-pointer sqlite3:value) args) (int i))
     365              "return(sqlite3_value_double(args[i]));")
    376366             args i))
    377367           ((text)
    378             ((foreign-primitive
    379               scheme-object (((c-pointer sqlite3:value) args) (int i))
    380               "int n = sqlite3_value_bytes(args[i]);\n"
    381               "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    382               "return(C_string(&s, n, (char *)sqlite3_value_text(args[i])));\n")
     368            ((foreign-primitive scheme-object
     369                                (((c-pointer sqlite3:value) args) (int i))
     370              "int n = sqlite3_value_bytes(args[i]);"
     371              "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     372              "return(C_string(&s, n, (char *)sqlite3_value_text(args[i])));")
    383373             args i))
    384374           ((blob)
    385             ((foreign-primitive
    386               scheme-object (((c-pointer sqlite3:value) args) (int i))
    387               "int n = sqlite3_value_bytes(args[i]);\n"
    388               "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    389               "return(C_bytevector(&s, n, (char *)sqlite3_value_blob(args[i])));\n")
     375            ((foreign-primitive scheme-object
     376                                (((c-pointer sqlite3:value) args) (int i))
     377              "int n = sqlite3_value_bytes(args[i]);"
     378              "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     379              "return(C_bytevector(&s, n, (char *)sqlite3_value_blob(args[i])));")
    390380             args i))
    391381           (else
    392             (void)))
     382            sqlite3:null-value))
    393383         (loop (add1 i)))
    394384        '())))
     
    396386(define-generic sqlite3:set-result!)
    397387(define-method (sqlite3:set-result! (ctx <pointer>) (v <blob>))
    398   ((foreign-lambda*
    399     void
    400     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     388  ((foreign-lambda* void
     389                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    401390      "sqlite3_result_blob(ctx, v, n, SQLITE_TRANSIENT);")
    402391   ctx v (blob-size v)))
     
    404393; Deprecated
    405394(define-method (sqlite3:set-result! (ctx <pointer>) (v <byte-vector>))
    406   ((foreign-lambda*
    407     void
    408     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     395  ((foreign-lambda* void
     396                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    409397      "sqlite3_result_blob(ctx, v, n, SQLITE_TRANSIENT);")
    410398   ctx v (byte-vector-length v)))
    411  
     399
    412400(define-method (sqlite3:set-result! (ctx <pointer>) (v <exact>))
    413401  ((foreign-lambda void "sqlite3_result_int" sqlite3:context int)
     
    419407
    420408(define-method (sqlite3:set-result! (ctx <pointer>) (v <string>))
    421   ((foreign-lambda*
    422     void
    423     ((sqlite3:context ctx) (scheme-pointer v) (int n))
     409  ((foreign-lambda* void
     410                    ((sqlite3:context ctx) (scheme-pointer v) (int n))
    424411    "sqlite3_result_text(ctx, v, n, SQLITE_TRANSIENT);")
    425412   ctx v (string-length v)))
     
    433420   ctx))
    434421
    435 (define sqlite3:functions (make-hash-table/synch 'sqlite3:functions))
    436 
    437422(define sqlite3_user_data
    438423  (foreign-lambda scheme-object "sqlite3_user_data" sqlite3:context))
    439424
    440 (define-external (chicken_sqlite3_function_stub (c-pointer ctx)
    441                                                 (int n) (c-pointer args)) void
     425(define-external (chicken_sqlite3_function_stub (c-pointer ctx) (int n) (c-pointer args)) void
    442426  (call-with-current-continuation
    443427   (lambda (q)
    444428     (dynamic-wind
    445          void
     429         noop
    446430         (lambda ()
    447431           (handle-exceptions exn
     
    452436              (apply
    453437               (vector-ref
    454                 (call-with/synch
    455                  sqlite3:functions
     438                (call-with/synch *sqlite3:functions*
    456439                 (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))
    457440                1)
     
    460443           (q (void)))))))
    461444
    462 (define sqlite3:seeds (make-hash-table/synch 'sqlite3:seeds))
    463 
    464445(define sqlite3_aggregate_context
    465   (foreign-lambda*
    466    integer ((sqlite3:context ctx))
    467    "return((int)sqlite3_aggregate_context(ctx, 1));\n"))
    468 
    469 (define-external (chicken_sqlite3_step_stub (c-pointer ctx)
    470                                             (int n) (c-pointer args)) void
     446  (foreign-lambda* integer ((sqlite3:context ctx))
     447   "return((int)sqlite3_aggregate_context(ctx, 1));"))
     448
     449(define-external (chicken_sqlite3_step_stub (c-pointer ctx) (int n) (c-pointer args)) void
    471450  (call-with-current-continuation
    472451   (lambda (q)
    473452     (dynamic-wind
    474          void
     453         noop
    475454         (lambda ()
    476455           (handle-exceptions exn
    477456               (print-error-message
    478457                exn (current-error-port) "Error in step of SQL function:")
    479              (let ((info (call-with/synch sqlite3:functions
    480                            (cut hash-table-tree-ref
    481                                 <> (sqlite3_user_data ctx)))))
    482                (call-with/synch sqlite3:seeds
     458             (let ((info (call-with/synch *sqlite3:functions*
     459                           (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))))
     460               (call-with/synch *sqlite3:seeds*
    483461                 (cut hash-table-update!/default
    484                       <> (sqlite3_aggregate_context ctx)
     462                      <>
     463                      (sqlite3_aggregate_context ctx)
    485464                      (lambda (seed)
    486465                        (apply
     
    497476     (let ((agc (sqlite3_aggregate_context ctx)))
    498477       (dynamic-wind
    499            void
     478           noop
    500479           (lambda ()
    501480             (handle-exceptions exn
    502                 (print-error-message
     481                (print-error-message
    503482                  exn (current-error-port) "Error in final of SQL function:")
    504                (let ((info (call-with/synch sqlite3:functions
    505                              (cut hash-table-tree-ref
    506                                   <> (sqlite3_user_data ctx)))))
     483               (let ((info (call-with/synch *sqlite3:functions*
     484                             (cut hash-table-tree-ref <> (sqlite3_user_data ctx)))))
    507485                 (cond
    508486                  (((vector-ref info 3)
    509                     (call-with/synch sqlite3:seeds
     487                    (call-with/synch *sqlite3:seeds*
    510488                      (cut hash-table-ref/default <> agc (vector-ref info 2))))
    511489                   => (cut sqlite3:set-result! ctx <>))
     
    513491                   (sqlite3:set-result! ctx))))))
    514492           (lambda ()
    515              (call-with/synch sqlite3:seeds
     493             (call-with/synch *sqlite3:seeds*
    516494               (cut hash-table-delete! <> agc))
    517495             (q (void))))))))
     
    524502  (let ((qn (object-evict (list (pointer->address (slot-ref db 'this)) name))))
    525503    (cond
    526      (((foreign-lambda*
    527         sqlite3:status
    528         ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
    529         "return(sqlite3_create_function(db, name, n, SQLITE_UTF8,\n"
    530         "                               (void *)qn,\n"
    531         "                               (void (*)(sqlite3_context *,\n"
    532         "                                         int, sqlite3_value **))"
    533         "                                 &chicken_sqlite3_function_stub,\n"
    534         "                               NULL, NULL));\n")
     504     (((foreign-lambda* sqlite3:status
     505                        ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
     506#<<END
     507        return(sqlite3_create_function(db, name, n, SQLITE_UTF8,
     508                                       (void *)qn,
     509                                       (void (*)(sqlite3_context *, int,
     510                                                 sqlite3_value **))
     511                                       &chicken_sqlite3_function_stub,
     512                                       NULL,
     513                                       NULL));
     514END
     515       )
    535516       db name n qn)
    536517      => (lambda (s)
    537518           (object-release qn)
    538            ((sqlite3:error 'sqlite3:define-function db name n proc) s)))
     519           ((signal-error 'sqlite3:define-function db name n proc) s)))
    539520     (else
    540       (call-with/synch sqlite3:functions
    541         (cut hash-table-tree-set! <> qn (vector qn proc)))))))
     521      (call-with/synch *sqlite3:functions*
     522        (cut hash-table-tree-set! <> qn (vector qn proc)))))))
    542523
    543524(define-method (sqlite3:define-function (db <sqlite3:database>)
     
    550531  (let ((qn (object-evict (list (pointer->address (slot-ref db 'this)) name))))
    551532    (cond
    552      (((foreign-lambda*
    553         sqlite3:status
    554         ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
    555         "return(sqlite3_create_function(db, name, n, SQLITE_UTF8,\n"
    556         "                               (void *)qn,\n"
    557         "                               NULL,\n"
    558         "                               (void (*)(sqlite3_context *,\n"
    559         "                                         int, sqlite3_value **))"
    560         "                                 &chicken_sqlite3_step_stub,\n"
    561         "                               (void (*)(sqlite3_context *))\n"
    562         "                                 &chicken_sqlite3_final_stub));\n")
     533     (((foreign-lambda* sqlite3:status
     534                        ((sqlite3:database db) (c-string name) (int n) (scheme-object qn))
     535#<<END
     536        return(sqlite3_create_function(db, name, n, SQLITE_UTF8,
     537                                       (void *)qn,
     538                                       NULL,
     539                                       (void (*)(sqlite3_context *, int,
     540                                                 sqlite3_value **))
     541                                       &chicken_sqlite3_step_stub,
     542                                       ((void (*)(sqlite3_context *))
     543                                         &chicken_sqlite3_final_stub)));
     544END
     545       )
    563546       db name n qn)
    564547      => (lambda (s)
    565548           (object-release qn)
    566            ((sqlite3:error
     549           ((signal-error
    567550              'sqlite3:define-function db name n step-proc seed final-proc)
    568551            s)))
    569552     (else
    570       (call-with/synch sqlite3:functions
    571         (cut hash-table-tree-set!
    572              <> qn (vector qn step-proc seed final-proc)))))))
    573 
    574 ;; set a timeout until a busy error is thrown
     553      (call-with/synch *sqlite3:functions*
     554        (cut hash-table-tree-set! <> qn (vector qn step-proc seed final-proc)))))))
     555
     556;;; Database interface
     557
     558;; Get any error message
     559(define sqlite3:errmsg
     560  (foreign-lambda c-string "sqlite3_errmsg" sqlite3:database))
     561
     562;; Open a database
     563(define (sqlite3:open path)
     564  (check-type 'sqlite3:open path <string>)
     565  (let-location ((db c-pointer))
     566    (cond
     567     (((foreign-lambda sqlite3:status "sqlite3_open"
     568                                      nonnull-c-string (c-pointer sqlite3:database))
     569       (sqlite3:resolve-pathname path) (location db))
     570      => (signal-error 'sqlite3:open #f path))
     571     (else
     572      (make <sqlite3:database> 'this db)))))
     573
     574;; Set a timeout until a busy error is thrown
    575575(define (sqlite3:set-busy-timeout! db #!optional (ms 0))
    576576  (check-type 'sqlite3:set-busy-timeout! db <sqlite3:database>)
    577577  (cond
    578    (((foreign-lambda
    579       sqlite3:status "sqlite3_busy_timeout"
    580       sqlite3:database int)
    581      db ms)
    582     => (sqlite3:error 'sqlite3:set-busy-timeout! db db ms))))
    583 
    584 ;; cancel any running database operation as soon as possible
     578   (((foreign-lambda sqlite3:status "sqlite3_busy_timeout" sqlite3:database int) db ms)
     579    => (signal-error 'sqlite3:set-busy-timeout! db db ms))))
     580
     581;; Cancel any running database operation as soon as possible
    585582(define (sqlite3:interrupt! db)
    586583  (check-type 'sqlite3:interrupt! db <sqlite3:database>)
    587584  ((foreign-lambda void "sqlite3_interrupt" sqlite3:database) db))
    588585
    589 ;; check whether the database is in autocommit mode
     586;; Check whether the database is in autocommit mode
    590587(define (sqlite3:auto-committing? db)
    591588  (check-type 'sqlite3:auto-committing? db <sqlite3:database>)
    592589  ((foreign-lambda bool "sqlite3_get_autocommit" sqlite3:database) db))
    593590
    594 ;; get the number of changes made to the database
     591;; Get the number of changes made to the database
    595592(define (sqlite3:changes db #!optional (total #f))
    596593  (check-type 'sqlite3:changes db <sqlite3:database>)
     
    599596      ((foreign-lambda number "sqlite3_changes" sqlite3:database) db))
    600597
    601 ;; get the row ID of the last inserted row
     598;; Get the row ID of the last inserted row
    602599(define (sqlite3:last-insert-rowid db)
    603600  (check-type 'sqlite3:last-insert-rowid db <sqlite3:database>)
    604601  ((foreign-lambda number "sqlite3_last_insert_rowid" sqlite3:database) db))
    605602
    606 ;; close a database
     603;; Close a database
    607604(define-generic sqlite3:finalize!)
    608605(define-method (sqlite3:finalize! (db <sqlite3:database>))
     
    610607   ((not (slot-ref db 'this))
    611608    (void))
    612    (((foreign-lambda
    613       sqlite3:status "sqlite3_close"
    614       sqlite3:database)
    615      db)
    616     => (sqlite3:error 'sqlite3:finalize! db db))
     609   (((foreign-lambda sqlite3:status "sqlite3_close" sqlite3:database) db)
     610    => (signal-error 'sqlite3:finalize! db db))
    617611   (else
    618612    (let ((id (pointer->address (slot-ref db 'this)))
    619           (release-qns (lambda (_ info)
    620                          (object-release (vector-ref info 0)))))
    621       (call-with/synch sqlite3:collations
    622         (lambda (collations)
    623           (cond
    624            ((hash-table-ref/default collations id #f)
    625             => (cut hash-table-walk <> release-qns)))
    626           (hash-table-delete! collations id)))
    627       (call-with/synch sqlite3:functions
    628         (lambda (functions)
    629           (cond
    630            ((hash-table-ref/default functions id #f)
    631             => (cut hash-table-walk <> release-qns)))
    632           (hash-table-delete! functions id))))
    633     (slot-set! db 'this #f))))
    634 
    635 ;;; statement interface
    636 
    637 ;; create a new statement
     613          (release-qns (lambda (_ info) (object-release (vector-ref info 0)))))
     614      (call-with/synch *sqlite3:collations*
     615        (cut hash-table-tree-clear! <> id release-qns))
     616      (call-with/synch *sqlite3:functions*
     617        (cut hash-table-tree-clear! <> id release-qns)) )
     618    (slot-set! db 'this #f) ) ) )
     619
     620;;; Statement interface
     621
     622;; Create a new statement
    638623(define (sqlite3:prepare db sql)
    639624  (check-type 'sqlite3:prepare db <sqlite3:database>)
     
    641626  (let-location ((stmt c-pointer) (tail c-string))
    642627    (cond
    643      (((foreign-lambda
    644         sqlite3:status "sqlite3_prepare"
    645         sqlite3:database scheme-pointer int
    646         (c-pointer sqlite3:statement) (c-pointer (const c-string)))
     628     (((foreign-lambda sqlite3:status "sqlite3_prepare"
     629                                      sqlite3:database scheme-pointer int
     630                                      (c-pointer sqlite3:statement)
     631                                      (c-pointer (const c-string)))
    647632       db sql (string-length sql) (location stmt) (location tail))
    648       => (sqlite3:error 'sqlite3:prepare db db sql))
     633      => (signal-error 'sqlite3:prepare db db sql))
    649634     (else
    650635      (values
     
    652637       tail)))))
    653638
    654 ;; recompile an existing statement and transfer all bindings
     639;; Recompile an existing statement and transfer all bindings
    655640(define (sqlite3:repair! stmt)
    656641  (check-type 'sqlite3:repair! stmt <sqlite3:statement>)
     
    658643                (slot-ref stmt 'database) (slot-ref stmt 'sql))))
    659644    (dynamic-wind
    660         void
     645        noop
    661646        (lambda ()
    662647          (let ((old (slot-ref stmt 'this))
    663648                (new (slot-ref fresh 'this)))
    664649            (cond
    665              (((foreign-lambda
    666                 sqlite3:status "sqlite3_transfer_bindings"
    667                 c-pointer c-pointer)
     650             (((foreign-lambda sqlite3:status "sqlite3_transfer_bindings"
     651                                              c-pointer c-pointer)
    668652               old new)
    669               => (sqlite3:error
    670                   'sqlite3:repair! (slot-ref stmt 'database) stmt))
     653              => (signal-error 'sqlite3:repair! (slot-ref stmt 'database) stmt))
    671654             (else
    672655              (slot-set! stmt 'this new)
     
    675658          (sqlite3:finalize! fresh)))))
    676659
    677 ;; discard an existing statement
     660;; Discard an existing statement
    678661;; (define-generic sqlite3:finalize!)
    679662(define-method (sqlite3:finalize! (stmt <sqlite3:statement>))
     
    681664   ((not (slot-ref stmt 'this))
    682665    (void))
    683    (((foreign-lambda sqlite3:status "sqlite3_finalize" sqlite3:statement)
    684      stmt)
    685     => (sqlite3:error 'sqlite3:finalize! (slot-ref stmt 'database) stmt))
     666   (((foreign-lambda sqlite3:status "sqlite3_finalize" sqlite3:statement) stmt)
     667    => (signal-error 'sqlite3:finalize! (slot-ref stmt 'database) stmt))
    686668   (else
    687669    (slot-set! stmt 'this #f))))
    688670
    689 ;; reset an existing statement to process it again
     671;; Reset an existing statement to process it again
    690672(define sqlite3_reset
    691673  (foreign-lambda sqlite3:status "sqlite3_reset"sqlite3:statement))
     
    695677  (cond
    696678   ((sqlite3_reset stmt)
    697     => (sqlite3:error 'sqlite3:reset! (slot-ref stmt 'database) stmt))))
    698 
    699 ;; get number of bindable parameters
     679    => (signal-error 'sqlite3:reset! (slot-ref stmt 'database) stmt))))
     680
     681;; Get number of bindable parameters
    700682(define (sqlite3:bind-parameter-count stmt)
    701683  (check-type 'sqlite3:bind-parameter-count stmt <sqlite3:statement>)
    702   ((foreign-lambda
    703     int "sqlite3_bind_parameter_count"
    704     sqlite3:statement)
    705    stmt))
    706 
    707 ;; get index of a bindable parameter or #f if no parameter with the
     684  ((foreign-lambda int "sqlite3_bind_parameter_count" sqlite3:statement) stmt))
     685
     686;; Get index of a bindable parameter or #f if no parameter with the
    708687;; given name exists
    709688(define (sqlite3:bind-parameter-index stmt name)
    710689  (check-type 'sqlite3:bind-parameter-index stmt <sqlite3:statement>)
    711   (let ((i ((foreign-lambda
    712              int "sqlite3_bind_parameter_index"
    713              sqlite3:statement nonnull-c-string)
     690  (let ((i ((foreign-lambda int "sqlite3_bind_parameter_index"
     691                                sqlite3:statement nonnull-c-string)
    714692            stmt name)))
    715693    (if (zero? i) #f (sub1 i))))
    716694
    717 ;; get the name of a bindable parameter
     695;; Get the name of a bindable parameter
    718696(define (sqlite3:bind-parameter-name stmt i)
    719697  (check-type 'sqlite3:bind-parameter-name stmt <sqlite3:statement>)
    720   ((foreign-lambda
    721     c-string "sqlite3_bind_parameter_name"
    722     sqlite3:statement int)
    723    stmt (add1 i)))
    724 
    725 ;; bind data as parameters to an existing statement
     698  ((foreign-lambda c-string "sqlite3_bind_parameter_name" sqlite3:statement int) stmt (add1 i)))
     699
     700;; Bind data as parameters to an existing statement
     701
    726702(define-generic sqlite3:bind!)
    727703(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    728                               (v <blob>))
    729   (cond
    730    (((foreign-lambda*
    731       sqlite3:status
    732       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     704                              (v <blob>))
     705  (cond
     706   (((foreign-lambda* sqlite3:status
     707                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    733708      "return(sqlite3_bind_blob(stmt, i, v, n, SQLITE_TRANSIENT));")
    734709     stmt (add1 i) v (blob-size v))
    735     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     710    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    736711
    737712; Deprecated
    738713(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    739                               (v <byte-vector>))
    740   (cond
    741    (((foreign-lambda*
    742       sqlite3:status
    743       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     714                              (v <byte-vector>))
     715  (cond
     716   (((foreign-lambda* sqlite3:status
     717                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    744718      "return(sqlite3_bind_blob(stmt, i, v, n, SQLITE_TRANSIENT));")
    745719     stmt (add1 i) v (byte-vector-length v))
    746     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    747  
     720    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     721
    748722(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    749723                              (v <exact>))
    750724  (cond
    751    (((foreign-lambda
    752       sqlite3:status "sqlite3_bind_int"
    753       sqlite3:statement int int)
     725   (((foreign-lambda sqlite3:status "sqlite3_bind_int"
     726                                    sqlite3:statement int int)
    754727     stmt (add1 i) v)
    755     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     728    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    756729
    757730(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    758731                              (v <number>))
    759732  (cond
    760    (((foreign-lambda
    761       sqlite3:status "sqlite3_bind_double"
    762       sqlite3:statement int double)
     733   (((foreign-lambda sqlite3:status "sqlite3_bind_double"
     734                                    sqlite3:statement int double)
    763735     stmt (add1 i) v)
    764     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     736    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    765737
    766738(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    767739                              (v <string>))
    768740  (cond
    769    (((foreign-lambda*
    770       sqlite3:status
    771       ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
     741   (((foreign-lambda* sqlite3:status
     742                      ((sqlite3:statement stmt) (int i) (scheme-pointer v) (int n))
    772743      "return(sqlite3_bind_text(stmt, i, v, n, SQLITE_TRANSIENT));")
    773744     stmt (add1 i) v (string-length v))
    774     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
     745    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i v))))
    775746
    776747(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>)
    777748                              (v <void>))
    778749  (cond
    779    (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int)
    780      stmt (add1 i))
    781     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
     750   (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int) stmt (add1 i))
     751    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
    782752
    783753(define-method (sqlite3:bind! (stmt <sqlite3:statement>) (i <exact>))
    784754  (cond
    785    (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int)
    786      stmt (add1 i))
    787     => (sqlite3:error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
    788 
    789 ;; single-step a prepared statement, return #t if data is available,
     755   (((foreign-lambda sqlite3:status "sqlite3_bind_null" sqlite3:statement int) stmt (add1 i))
     756    => (signal-error 'sqlite3:bind! (slot-ref stmt 'database) stmt i))))
     757
     758;; Single-step a prepared statement, return #t if data is available,
    790759;; #f otherwise
    791760(define (sqlite3:step! stmt)
     
    805774              (retry))
    806775             (else
    807               ((sqlite3:error
     776              ((signal-error
    808777                'sqlite3:step! (slot-ref stmt 'database) stmt) s)))))
    809778        (else
    810          ((sqlite3:error 'sqlite3:step! (slot-ref stmt 'database) stmt) s))))))
    811 
    812 ;; retrieve information from a prepared/stepped statement
     779         ((signal-error 'sqlite3:step! (slot-ref stmt 'database) stmt) s))))))
     780
     781;; Retrieve information from a prepared/stepped statement
    813782(define (sqlite3:column-count stmt)
    814783  (check-type 'sqlite3:column-count stmt <sqlite3:statement>)
    815   ((foreign-lambda
    816     int "sqlite3_column_count"
    817     sqlite3:statement)
    818    stmt))
     784  ((foreign-lambda int "sqlite3_column_count" sqlite3:statement) stmt))
    819785
    820786(define (sqlite3:column-type stmt i)
    821787  (check-type 'sqlite3:column-type stmt <sqlite3:statement>)
    822   ((foreign-lambda
    823     sqlite3:type "sqlite3_column_type"
    824     sqlite3:statement int)
    825    stmt i))
     788  ((foreign-lambda sqlite3:type "sqlite3_column_type" sqlite3:statement int) stmt i))
    826789
    827790(define (sqlite3:column-declared-type stmt i)
    828791  (check-type 'sqlite3:column-declared-type stmt <sqlite3:statement>)
    829   ((foreign-lambda
    830     c-string "sqlite3_column_decltype"
    831     sqlite3:statement int)
    832    stmt i))
     792  ((foreign-lambda c-string "sqlite3_column_decltype" sqlite3:statement int) stmt i))
    833793
    834794(define (sqlite3:column-name stmt i)
    835795  (check-type 'sqlite3:column-name stmt <sqlite3:statement>)
    836   ((foreign-lambda
    837     c-string "sqlite3_column_name"
    838     sqlite3:statement int)
    839    stmt i))
    840 
    841 ;; retrieve data from a stepped statement
     796  ((foreign-lambda c-string "sqlite3_column_name" sqlite3:statement int) stmt i))
     797
     798;; Retrieve data from a stepped statement
    842799(define (sqlite3:column-data stmt i)
    843800  (case (sqlite3:column-type stmt i)
    844801    ((integer)
    845      ((foreign-lambda
    846        integer "sqlite3_column_double"
    847        sqlite3:statement int)
    848       stmt i))
     802     ((foreign-lambda integer "sqlite3_column_double" sqlite3:statement int) stmt i))
    849803    ((float)
    850      ((foreign-lambda
    851        double "sqlite3_column_double"
    852        sqlite3:statement int)
    853       stmt i))
     804     ((foreign-lambda double "sqlite3_column_double" sqlite3:statement int) stmt i))
    854805    ((text)
    855      ((foreign-primitive
    856        scheme-object ((sqlite3:statement stmt) (int i))
    857        "int n = sqlite3_column_bytes(stmt, i);\n"
    858        "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    859        "return(C_string(&s, n, (char *)sqlite3_column_text(stmt, i)));\n")
     806     ((foreign-primitive scheme-object ((sqlite3:statement stmt) (int i))
     807       "int n = sqlite3_column_bytes(stmt, i);"
     808       "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     809       "return(C_string(&s, n, (char *)sqlite3_column_text(stmt, i)));")
    860810      stmt i))
    861811    ((blob)
    862      ((foreign-primitive
    863        scheme-object ((sqlite3:statement stmt) (int i))
    864        "int n = sqlite3_column_bytes(stmt, i);\n"
    865        "C_word *s = C_alloc(C_SIZEOF_STRING(n));\n"
    866        "return(C_bytevector(&s, n, (char *)sqlite3_column_blob(stmt, i)));\n")
     812     ((foreign-primitive scheme-object ((sqlite3:statement stmt) (int i))
     813       "int n = sqlite3_column_bytes(stmt, i);"
     814       "C_word *s = C_alloc(C_SIZEOF_STRING(n));"
     815       "return(C_bytevector(&s, n, (char *)sqlite3_column_blob(stmt, i)));")
    867816      stmt i))
    868817    (else
    869      (void))))
    870 
    871 ;;; easy statement interface
    872 
    873 ;; compile a statement and call a procedure on it, then finalize the
     818     sqlite3:null-value)))
     819
     820;;; Easy statement interface
     821
     822;; Compile a statement and call a procedure on it, then finalize the
    874823;; statement in a dynamic-wind exit block if it hasn't been finalized yet.
    875824(define (sqlite3:call-with-temporary-statements proc db . sqls)
     
    887836            (set! stmts #f))))))
    888837
    889 ;; step through a statement and ignore possible results
     838;; Step through a statement and ignore possible results
    890839(define-generic sqlite3:exec)
    891840(define-method (sqlite3:exec (stmt <sqlite3:statement>) . params)
     
    894843   (cute sqlite3:bind! stmt <> <>)
    895844   (iota (sqlite3:bind-parameter-count stmt)) params)
    896   (do () ((not (sqlite3:step! stmt)) (void))))
     845  (do () ((not (sqlite3:step! stmt)) sqlite3:null-value)))
    897846
    898847(define-method (sqlite3:exec (db <sqlite3:database>) (sql <string>) . params)
     
    901850   db sql))
    902851
    903 ;; step through a statement, ignore possible results and return the
     852;; Step through a statement, ignore possible results and return the
    904853;; count of changes performed by this statement
    905854(define-generic sqlite3:update)
     
    913862  (sqlite3:changes db))
    914863
    915 ;; return only the first column of the first result row produced by this
     864;; Return only the first column of the first result row produced by this
    916865;; statement
     866
    917867(define-generic sqlite3:first-result)
    918868(define-method (sqlite3:first-result (stmt <sqlite3:statement>) . params)
     
    925875        (sqlite3:reset! stmt)
    926876        r)
    927       (signal
    928        (make-composite-condition
    929         (make-property-condition
    930          'exn
    931          'location 'sqlite3:first-result 'arguments (cons stmt params)
    932          'message "the statement returned no data")
    933         (make-property-condition
    934          'sqlite3
    935          'status 'done)))))
     877      (signal (make-no-data-condition stmt params)) ) )
    936878
    937879(define-method (sqlite3:first-result
     
    941883   db sql))
    942884
    943 ;; return only the first result row produced by this statement as a list
     885;; Return only the first result row produced by this statement as a list
     886
    944887(define-generic sqlite3:first-row)
    945888(define-method (sqlite3:first-row (stmt <sqlite3:statement>) . params)
     
    952895       (cute sqlite3:column-data stmt <>)
    953896       (iota (sqlite3:column-count stmt)))
    954       (signal
    955        (make-composite-condition
    956         (make-property-condition
    957          'exn
    958          'location 'sqlite3:first-row 'arguments (cons stmt params)
    959          'message "the statement returned no data")
    960         (make-property-condition
    961          'sqlite3
    962          'status 'done)))))
     897      (signal (make-no-data-condition stmt params)) ) )
    963898
    964899(define-method (sqlite3:first-row
     
    968903   db sql))
    969904
    970 ;; apply a procedure to the values of the result columns for each result row
     905;; Apply a procedure to the values of the result columns for each result row
    971906;; while executing the statement and discard the results
     907
    972908(define-generic sqlite3:for-each-row)
    973909(define-method (sqlite3:for-each-row
     
    978914   (iota (sqlite3:bind-parameter-count stmt)) params)
    979915  (do ((cl (iota (sqlite3:column-count stmt))))
    980       ((not (sqlite3:step! stmt)) (void))
     916      ((not (sqlite3:step! stmt)) sqlite3:null-value)
    981917    (apply proc (map (cute sqlite3:column-data stmt <>) cl))))
    982918
     
    988924   db sql))
    989925
    990 ;; apply a procedure to the values of the result columns for each result row
     926;; Apply a procedure to the values of the result columns for each result row
    991927;; while executing the statement and accumulate the results in a list
     928
    992929(define-generic sqlite3:map-row)
    993930(define-method (sqlite3:map-row
     
    1012949   db sql))
    1013950
    1014 ;;; utility procedures
    1015 
    1016 ;; run a thunk within a database transaction, commit if return value is
     951;;; Utility procedures
     952
     953;; Run a thunk within a database transaction, commit if return value is
    1017954;; true, rollback if return value is false or the thunk is interrupted by
    1018955;; an exception
     
    1023960    (abort
    1024961     (make-composite-condition
    1025       (make-property-condition
    1026        'exn
    1027        'location 'sqlite3:with-transaction 'arguments (list type)
    1028        'message (sprintf
    1029                  "bad argument ~a, expected deferred, immediate or exclusive"
    1030                  type))
     962      (make-exn-condition 'sqlite3:with-transaction
     963                          (format #f
     964                           "bad argument ~A, expected deferred, immediate or exclusive"
     965                           type)
     966                          type)
    1031967      (make-property-condition 'type))))
    1032968  (let ((success? #f))
    1033969    (dynamic-wind
    1034970        (lambda ()
    1035           (sqlite3:exec db (sprintf "BEGIN ~A TRANSACTION;" type)))
     971          (sqlite3:exec db (format #f "BEGIN ~a TRANSACTION;" type)))
    1036972        (lambda ()
    1037973          (set! success? (thunk)))
     
    1042978                  "ROLLBACK TRANSACTION;"))))))
    1043979
    1044 ;; check if the given string is a valid SQL statement
     980;; Check if the given string is a valid SQL statement
    1045981(define sqlite3:complete?
    1046982  (foreign-lambda bool "sqlite3_complete" nonnull-c-string))
    1047983
    1048 ;; return a descriptive version string
     984;; Return a descriptive version string
    1049985(define sqlite3:library-version
    1050986  (foreign-lambda c-string "sqlite3_libversion"))
  • release/3/sqlite3/trunk/sqlite3.setup

    r6115 r7981  
    33(define so-file "sqlite3.so")
    44(compile
    5    ,@(if (string<? "2.636" (chicken-version)) '(-feature has-extended-define-foreign-enum) '())
    6   -O2 -d0 -X easyffi -X tinyclos -s "sqlite3.scm" -lsqlite3
     5  -O2 -d0 -X easyffi -X tinyclos -s sqlite3.scm -lsqlite3
    76  -o ,so-file
    87  -check-imports -emit-exports "sqlite3.exports")
     
    1110  `(,so-file
    1211    "sqlite3.html" "egg.jpg")
    13   '((version "2.0.1") (documentation "sqlite3.html")))
     12  '((version "2.0.3") (documentation "sqlite3.html")))
Note: See TracChangeset for help on using the changeset viewer.