factor/basis/db/db.factor

153 lines
4.4 KiB
Factor
Raw Normal View History

2008-02-01 18:43:44 -05:00
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
2008-05-15 00:23:12 -04:00
USING: arrays assocs classes continuations destructors kernel math
2008-09-05 20:29:14 -04:00
namespaces sequences classes.tuple words strings
tools.walker accessors combinators fry db.errors ;
2008-02-01 18:43:44 -05:00
IN: db
TUPLE: db-connection
2008-02-27 20:30:31 -05:00
handle
insert-statements
update-statements
delete-statements ;
2009-02-20 23:59:01 -05:00
<PRIVATE
: new-db-connection ( class -- obj )
new
2008-04-05 21:22:33 -04:00
H{ } clone >>insert-statements
H{ } clone >>update-statements
H{ } clone >>delete-statements ; inline
2008-02-01 18:43:44 -05:00
PRIVATE>
2008-12-17 22:04:17 -05:00
GENERIC: db-open ( db -- db-connection )
HOOK: db-close db-connection ( handle -- )
2009-02-20 23:59:01 -05:00
HOOK: parse-db-error db-connection ( error -- error' )
2008-05-15 00:23:12 -04:00
: dispose-statements ( assoc -- ) values dispose-each ;
2008-12-17 22:04:17 -05:00
M: db-connection dispose ( db-connection -- )
dup db-connection [
[ dispose-statements H{ } clone ] change-insert-statements
[ dispose-statements H{ } clone ] change-update-statements
[ dispose-statements H{ } clone ] change-delete-statements
2008-10-09 16:42:23 -04:00
[ db-close f ] change-handle
drop
] with-variable ;
2008-02-01 18:43:44 -05:00
TUPLE: result-set sql in-params out-params handle n max ;
GENERIC: query-results ( query -- result-set )
GENERIC: #rows ( result-set -- n )
GENERIC: #columns ( result-set -- n )
GENERIC# row-column 1 ( result-set column -- obj )
GENERIC# row-column-typed 1 ( result-set column -- sql )
GENERIC: advance-row ( result-set -- )
GENERIC: more-rows? ( result-set -- ? )
: init-result-set ( result-set -- )
dup #rows >>max
0 >>n drop ;
: new-result-set ( query handle class -- result-set )
new
swap >>handle
2008-11-29 13:18:09 -05:00
[ [ sql>> ] [ in-params>> ] [ out-params>> ] tri ] dip
swap >>out-params
swap >>in-params
swap >>sql ;
TUPLE: statement handle sql in-params out-params bind-params bound? type retries ;
2008-04-05 21:22:33 -04:00
TUPLE: simple-statement < statement ;
TUPLE: prepared-statement < statement ;
: new-statement ( sql in out class -- statement )
new
2008-04-05 21:22:33 -04:00
swap >>out-params
swap >>in-params
2008-06-01 00:38:10 -04:00
swap >>sql ;
2008-12-17 22:04:17 -05:00
HOOK: <simple-statement> db-connection ( string in out -- statement )
HOOK: <prepared-statement> db-connection ( string in out -- statement )
2008-02-01 18:43:44 -05:00
GENERIC: prepare-statement ( statement -- )
GENERIC: bind-statement* ( statement -- )
GENERIC: low-level-bind ( statement -- )
GENERIC: bind-tuple ( tuple statement -- )
GENERIC: execute-statement* ( statement type -- )
2008-03-17 01:26:05 -04:00
2008-06-01 00:38:10 -04:00
M: object execute-statement* ( statement type -- )
'[
_ _ drop query-results dispose
] [
parse-db-error rethrow
] recover ;
: execute-one-statement ( statement -- )
dup type>> execute-statement* ;
: execute-statement ( statement -- )
2008-03-17 01:26:05 -04:00
dup sequence? [
[ execute-one-statement ] each
2008-03-17 01:26:05 -04:00
] [
execute-one-statement
2008-03-17 01:26:05 -04:00
] if ;
: bind-statement ( obj statement -- )
swap >>bind-params
[ bind-statement* ] keep
t >>bound? drop ;
: sql-row ( result-set -- seq )
2010-01-14 10:10:13 -05:00
dup #columns [ row-column ] with { } map-integers ;
2008-02-01 18:43:44 -05:00
: sql-row-typed ( result-set -- seq )
2010-01-14 10:10:13 -05:00
dup #columns [ row-column-typed ] with { } map-integers ;
: query-each ( statement quot: ( statement -- ) -- )
over more-rows? [
[ call ] 2keep over advance-row query-each
2008-02-01 18:43:44 -05:00
] [
2drop
] if ; inline recursive
2008-02-01 18:43:44 -05:00
: query-map ( statement quot -- seq )
collector [ query-each ] dip { } like ; inline
2008-02-01 18:43:44 -05:00
: with-db ( db quot -- )
2008-12-17 22:04:17 -05:00
[ db-open db-connection ] dip
'[ db-connection get [ drop @ ] with-disposal ] with-variable ; inline
2008-02-01 18:43:44 -05:00
2008-10-03 21:19:20 -04:00
! Words for working with raw SQL statements
: default-query ( query -- result-set )
query-results [ [ sql-row ] query-map ] with-disposal ;
2008-02-01 18:43:44 -05:00
2008-09-09 18:27:37 -04:00
: sql-query ( sql -- rows )
f f <simple-statement> [ default-query ] with-disposal ;
2008-10-03 21:19:20 -04:00
: (sql-command) ( string -- )
f f <simple-statement> [ execute-statement ] with-disposal ;
2008-09-09 18:27:37 -04:00
: sql-command ( sql -- )
2008-10-03 21:19:20 -04:00
dup string? [ (sql-command) ] [ [ (sql-command) ] each ] if ;
2008-09-09 18:27:37 -04:00
2008-10-03 21:19:20 -04:00
! Transactions
2008-02-01 18:43:44 -05:00
SYMBOL: in-transaction
2008-10-03 21:19:20 -04:00
2008-12-17 22:04:17 -05:00
HOOK: begin-transaction db-connection ( -- )
HOOK: commit-transaction db-connection ( -- )
HOOK: rollback-transaction db-connection ( -- )
2008-02-01 18:43:44 -05:00
M: db-connection begin-transaction ( -- ) "BEGIN" sql-command ;
M: db-connection commit-transaction ( -- ) "COMMIT" sql-command ;
M: db-connection rollback-transaction ( -- ) "ROLLBACK" sql-command ;
2008-09-09 18:27:37 -04:00
2008-02-01 18:43:44 -05:00
: in-transaction? ( -- ? ) in-transaction get ;
: with-transaction ( quot -- )
t in-transaction [
begin-transaction
[ ] [ rollback-transaction ] cleanup commit-transaction
] with-variable ; inline