From: John Cowan <xxxxxx@ccil.org>Date: Wednesday, September 18, 2019 8:14 PMOn Wed, Sep 18, 2019 at 4:41 AM Lassi Kortela <xxxxxx@lassi.io> wrote:> I'll modify my existing pre-SRFI in this direction, taking up a good many> of the points already raised, or as many as I can remember. :-)Is your pre-SRFI already readable somewhere? I didn't find it in yourwg1 repo.I've updated it now; it's at <https://bitbucket.org/cowan/r7rs-wg1-infra/src/default/SimpleSqlCowan.md>. Note that while it's no longer SQLite-specific, it is still SQL-specific; it believes in rows, columns, column types, and blobs-as-pseudo-ports.I think that column-fold is the Wrong Thing: it should fold all rows using specified columns. I"ve just added a preliminary entry to the above page.
Opaque object types
Database, statement, result-set
Databases
(open-sql-database filename mode) -> db
mode is symbol: read, write, create
(sql-database? obj) -> boolean
(sql-interrupt db timespec) -> undefined
Attempt to interrupt requests from any thread.
(sql-timeout db timespec) -> undefined
Set timeout in seconds and nanoseconds for each database request. Signal an error if request does not complete.
(sql-in-transaction db thunk) -> what thunk returns
When proc returns, roll back unless sql-commit has been called.
(with-transaction db(lambda ()(query db "INSERT INTO foo (bar, qux) VALUES (1, 2)")(with-transaction(lambda ()(query db "INSERT INTO foo (bar, qux) VALUES (3, 4)");; Oops, decide to roll this back(rollback)))(query db "INSERT INTO foo (bar, qux) VALUES (5, 6)")))
(sql-commit db) -> unspecified
(sql-rollback db) -> unspecified
(sql-in-transaction? db) -> boolean
Is the database currently running a transaction?
Statements and result sets
(sql-statement db code bindings) -> statement
It is an error to mutate either code or bindings; this enables caching of either compiled but unbound statements, fully bound statements, or both.
(sql-statement? obj) -> boolean
(sql-exec db statement) -> implementation-dependent
Use this procedure when statement does not return a result set.
(sql-result-set db statement thunk) -> whatever thunk returns
Executes statement and calls thunk, passing a result-set object.
(sql-read result-set) -> list
Returns a list of Scheme objects representing the next available row of the result-set. NULL is represented by the symbol nil.
(sql-read-all result-set) -> list of lists
Returns all available rows in this result-set.
(sql-for-each proc result-set) -> unspecified
Applies each result of result-set to proc for its side effects.
(sql-map->list proc result-set) -> list
Applies each result of result-set to proc and returns a list of the results.
(sql-fold proc knil result-set) -> any
Call proc on each result of result-set and the current state (initially knil). Order of arguments?
(sql-column-fold proc-list column-list knil-list result-set) -> any
Folds specified columns simultaneously, where column-list specifies the names of the columns of interest, proc-list is the folding procs corresponding to the chosen columns, and knil-list is the initial values of the current states of each fold.
Blobs
ISSUE: Should this be gotten rid of? It's not strictly necessary, but handling really large blobs without it will be messy. Ideally it should give us ports, but adding ports to a Scheme implementation is hard.
Exceptions
(make-sql-exception code message) -> sql-exception
(sql-exception? obj) -> boolean
(sql-exception-code sql-exception) -> exact integer
(sql-exception-message sql-exception) -> string
Meta
This is not standardized over databases, so provided here. There isn't much, but what there is is generally useful.
(sql-tables db) -> list of symbols
The symbols correspond to database tables (including views) accessible to the current user.
(sql-columns db table) -> list of symbols
The symbols represent column names, and appear in ordinal position.
(sql-column-type db table column) -> string
Returns the declared type of the specified table and column. The result is a string whose possible values depend on the database.