| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2009-02-20 21:40:17 -05:00
										 |  |  | tools.walker accessors combinators fry db.errors ;
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | IN: db | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-17 20:35:53 -05:00
										 |  |  | 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-17 20:35:53 -05:00
										 |  |  | : new-db-connection ( class -- obj )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:27 -04:00
										 |  |  |     new
 | 
					
						
							| 
									
										
										
										
											2008-04-05 21:22:33 -04:00
										 |  |  |         H{ } clone >>insert-statements | 
					
						
							|  |  |  |         H{ } clone >>update-statements | 
					
						
							| 
									
										
										
										
											2008-09-02 23:50:46 -04:00
										 |  |  |         H{ } clone >>delete-statements ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-17 20:35:53 -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-02-11 00:11:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-15 00:23:12 -04:00
										 |  |  | : dispose-statements ( assoc -- ) values dispose-each ;
 | 
					
						
							| 
									
										
										
										
											2008-02-11 00:11:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-17 22:04:17 -05:00
										 |  |  | M: db-connection dispose ( db-connection -- )  | 
					
						
							|  |  |  |     dup db-connection [ | 
					
						
							| 
									
										
										
										
											2008-10-09 15:07:11 -04:00
										 |  |  |         [ 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
 | 
					
						
							| 
									
										
										
										
											2008-02-11 00:11:16 -05:00
										 |  |  |     ] with-variable ;
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-09 15:44:14 -04: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
 | 
					
						
							| 
									
										
										
										
											2008-09-09 15:44:14 -04:00
										 |  |  |         swap >>out-params | 
					
						
							|  |  |  |         swap >>in-params | 
					
						
							|  |  |  |         swap >>sql ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-01 01:48:38 -04:00
										 |  |  | 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 ;
 | 
					
						
							| 
									
										
										
										
											2008-04-18 17:01:31 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-09 15:44:14 -04:00
										 |  |  | : new-statement ( sql in out class -- statement )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:27 -04:00
										 |  |  |     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-02-22 18:06:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-27 19:28:32 -05:00
										 |  |  | GENERIC: bind-statement* ( statement -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-19 23:09:36 -04:00
										 |  |  | GENERIC: low-level-bind ( statement -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-22 18:06:00 -05:00
										 |  |  | GENERIC: bind-tuple ( tuple statement -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-03 00:28:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-18 17:01:31 -04:00
										 |  |  | 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 -- )
 | 
					
						
							| 
									
										
										
										
											2009-02-20 21:40:17 -05:00
										 |  |  |     '[ | 
					
						
							|  |  |  |         _ _ drop query-results dispose | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         parse-db-error rethrow
 | 
					
						
							|  |  |  |     ] recover ;
 | 
					
						
							| 
									
										
										
										
											2008-02-14 02:27:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-24 23:24:34 -04:00
										 |  |  | : execute-one-statement ( statement -- )
 | 
					
						
							|  |  |  |     dup type>> execute-statement* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-18 17:01:31 -04:00
										 |  |  | : execute-statement ( statement -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-17 01:26:05 -04:00
										 |  |  |     dup sequence? [ | 
					
						
							| 
									
										
										
										
											2008-09-24 23:24:34 -04:00
										 |  |  |         [ execute-one-statement ] each
 | 
					
						
							| 
									
										
										
										
											2008-03-17 01:26:05 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-09-24 23:24:34 -04:00
										 |  |  |         execute-one-statement | 
					
						
							| 
									
										
										
										
											2008-03-17 01:26:05 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-14 02:27:54 -05:00
										 |  |  | : bind-statement ( obj statement -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-03 09:56:06 -05:00
										 |  |  |     swap >>bind-params | 
					
						
							| 
									
										
										
										
											2008-02-27 19:28:32 -05:00
										 |  |  |     [ bind-statement* ] keep
 | 
					
						
							| 
									
										
										
										
											2008-03-03 09:56:06 -05:00
										 |  |  |     t >>bound? drop ;
 | 
					
						
							| 
									
										
										
										
											2008-02-14 02:27:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-03 00:28:33 -05:00
										 |  |  | : sql-row ( result-set -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  |     dup #columns [ row-column ] with map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-05 20:59:29 -05:00
										 |  |  | : sql-row-typed ( result-set -- seq )
 | 
					
						
							|  |  |  |     dup #columns [ row-column-typed ] with map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-27 20:27:06 -04:00
										 |  |  | : query-each ( statement quot: ( statement -- ) -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-15 00:39:20 -05:00
										 |  |  |     over more-rows? [ | 
					
						
							|  |  |  |         [ call ] 2keep over advance-row query-each | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-02-15 00:39:20 -05:00
										 |  |  |         2drop
 | 
					
						
							| 
									
										
										
										
											2008-08-27 20:27:06 -04:00
										 |  |  |     ] if ; inline recursive
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : query-map ( statement quot -- seq )
 | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  |     accumulator [ query-each ] dip { } like ; inline
 | 
					
						
							| 
									
										
										
										
											2008-02-01 18:43:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-02 13:11:56 -04: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 | 
					
						
							| 
									
										
										
										
											2008-02-22 18:06:00 -05:00
										 |  |  | : default-query ( query -- result-set )
 | 
					
						
							| 
									
										
										
										
											2008-02-03 00:28:33 -05:00
										 |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-17 20:35:53 -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 | 
					
						
							| 
									
										
										
										
											2009-03-15 19:19:29 -04:00
										 |  |  |     ] with-variable ; inline
 |