| 
									
										
										
										
											2008-04-20 18:47:43 -04:00
										 |  |  | ! Copyright (C) 2008 Doug Coleman. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2012-07-24 14:55:16 -04:00
										 |  |  | USING: accessors arrays byte-arrays classes classes.tuple | 
					
						
							|  |  |  | combinators continuations db db.errors db.private db.tuples | 
					
						
							| 
									
										
										
										
											2011-09-04 17:52:44 -04:00
										 |  |  | db.tuples.private db.types destructors kernel make math | 
					
						
							|  |  |  | math.bitwise math.intervals math.parser namespaces nmake | 
					
						
							|  |  |  | prettyprint random sequences shuffle strings words fry ;
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:47:43 -04:00
										 |  |  | IN: db.queries | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-21 14:11:19 -04:00
										 |  |  | GENERIC: where ( specs obj -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  | SINGLETON: retryable | 
					
						
							|  |  |  | : make-retryable ( obj -- obj' )
 | 
					
						
							|  |  |  |     dup sequence? [ | 
					
						
							|  |  |  |         [ make-retryable ] map
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         retryable >>type | 
					
						
							|  |  |  |         10 >>retries | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:47:43 -04:00
										 |  |  | : maybe-make-retryable ( statement -- statement )
 | 
					
						
							| 
									
										
										
										
											2009-01-29 23:19:07 -05:00
										 |  |  |     dup in-params>> [ generator-bind? ] any?
 | 
					
						
							| 
									
										
										
										
											2008-06-01 00:38:10 -04:00
										 |  |  |     [ make-retryable ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:47:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  | : regenerate-params ( statement -- statement )
 | 
					
						
							| 
									
										
										
										
											2015-06-29 19:43:15 -04:00
										 |  |  |     dup
 | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  |     [ bind-params>> ] [ in-params>> ] bi
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         dup generator-bind? [ | 
					
						
							|  |  |  |             generator-singleton>> eval-generator >>value | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             drop
 | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] 2map >>bind-params ;
 | 
					
						
							| 
									
										
										
										
											2015-06-29 19:43:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: retryable execute-statement* | 
					
						
							| 
									
										
										
										
											2017-06-01 17:59:35 -04:00
										 |  |  |     drop [ retries>> <iota> ] [ | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  |         [ | 
					
						
							|  |  |  |             nip
 | 
					
						
							|  |  |  |             [ query-results dispose t ] | 
					
						
							| 
									
										
										
										
											2015-06-29 19:43:15 -04:00
										 |  |  |             [ ] | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  |             [ regenerate-params bind-statement* f ] cleanup
 | 
					
						
							|  |  |  |         ] curry
 | 
					
						
							|  |  |  |     ] bi attempt-all drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sql-props ( class -- columns table )
 | 
					
						
							| 
									
										
										
										
											2009-02-12 18:29:31 -05:00
										 |  |  |     [ db-columns ] [ db-table-name ] bi ;
 | 
					
						
							| 
									
										
										
										
											2008-09-08 17:19:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 13:39:20 -05:00
										 |  |  | : query-make ( ..a class quot: ( ..a columns table -- ..b ) -- ..b statements )
 | 
					
						
							| 
									
										
										
										
											2015-09-08 19:15:10 -04:00
										 |  |  |     ! query, input, outputs, secondary queries | 
					
						
							| 
									
										
										
										
											2008-09-27 15:07:39 -04:00
										 |  |  |     [ sql-props ] dip
 | 
					
						
							| 
									
										
										
										
											2018-02-14 13:39:20 -05:00
										 |  |  |     '[ 0 sql-counter [ dup "table-name" set @ ] with-variable ] | 
					
						
							| 
									
										
										
										
											2008-09-30 00:43:34 -04:00
										 |  |  |     { "" { } { } { } } nmake | 
					
						
							|  |  |  |     [ <simple-statement> maybe-make-retryable ] dip
 | 
					
						
							| 
									
										
										
										
											2008-09-30 12:00:44 -04:00
										 |  |  |     [ [ 1array ] dip append ] unless-empty ; inline
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:47:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:55:08 -04:00
										 |  |  | : where-primary-key% ( specs -- )
 | 
					
						
							|  |  |  |     " where " 0% | 
					
						
							| 
									
										
										
										
											2008-09-27 15:07:39 -04:00
										 |  |  |     find-primary-key [ | 
					
						
							|  |  |  |         " and " 0% | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         dup column-name>> 0% " = " 0% bind% | 
					
						
							|  |  |  |     ] interleave ;
 | 
					
						
							| 
									
										
										
										
											2008-04-20 18:55:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: db-connection <update-tuple-statement> | 
					
						
							| 
									
										
										
										
											2008-04-20 18:55:08 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         "update " 0% 0% | 
					
						
							|  |  |  |         " set " 0% | 
					
						
							|  |  |  |         dup remove-id | 
					
						
							|  |  |  |         [ ", " 0% ] [ dup column-name>> 0% " = " 0% bind% ] interleave
 | 
					
						
							|  |  |  |         where-primary-key% | 
					
						
							|  |  |  |     ] query-make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: random-id-generator eval-generator | 
					
						
							| 
									
										
										
										
											2008-04-21 14:11:19 -04:00
										 |  |  |     drop
 | 
					
						
							|  |  |  |     system-random-generator get [ | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |         63 [ random-bits ] keep 1 - set-bit | 
					
						
							| 
									
										
										
										
											2008-04-21 14:11:19 -04:00
										 |  |  |     ] with-random ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : interval-comparison ( ? str -- str )
 | 
					
						
							|  |  |  |     "from" = " >" " <" ? swap [ "= " append ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-28 21:27:37 -04:00
										 |  |  | : (infinite-interval?) ( interval -- ?1 ?2 )
 | 
					
						
							|  |  |  |     [ from>> ] [ to>> ] bi
 | 
					
						
							|  |  |  |     [ first fp-infinity? ] bi@ ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : double-infinite-interval? ( obj -- ? )
 | 
					
						
							|  |  |  |     dup interval? [ (infinite-interval?) and ] [ drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : infinite-interval? ( obj -- ? )
 | 
					
						
							|  |  |  |     dup interval? [ (infinite-interval?) or ] [ drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | : where-interval ( spec obj from/to -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-28 20:41:35 -04:00
										 |  |  |     over first fp-infinity? [ | 
					
						
							|  |  |  |         3drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         pick column-name>> 0% | 
					
						
							| 
									
										
										
										
											2008-11-29 13:18:09 -05:00
										 |  |  |         [ first2 ] dip interval-comparison 0% | 
					
						
							| 
									
										
										
										
											2008-04-28 20:41:35 -04:00
										 |  |  |         bind# | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : in-parens ( quot -- )
 | 
					
						
							|  |  |  |     "(" 0% call ")" 0% ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: interval where | 
					
						
							| 
									
										
										
										
											2008-04-28 21:27:37 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ from>> "from" where-interval ] [ | 
					
						
							|  |  |  |             nip infinite-interval? [ " and " 0% ] unless
 | 
					
						
							|  |  |  |         ] [ to>> "to" where-interval ] 2tri
 | 
					
						
							|  |  |  |     ] in-parens ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: sequence where | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         [ " or " 0% ] [ dupd where ] interleave drop
 | 
					
						
							|  |  |  |     ] in-parens ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: byte-array where | 
					
						
							| 
									
										
										
										
											2009-04-11 10:03:00 -04:00
										 |  |  |     over column-name>> 0% " = " 0% bind# ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: NULL where | 
					
						
							| 
									
										
										
										
											2008-10-10 21:52:28 -04:00
										 |  |  |     drop column-name>> 0% " is NULL" 0% ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | : object-where ( spec obj -- )
 | 
					
						
							|  |  |  |     over column-name>> 0% " = " 0% bind# ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: object where object-where ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: integer where object-where ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: string where object-where ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-28 21:27:37 -04:00
										 |  |  | : filter-slots ( tuple specs -- specs' )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         slot-name>> swap get-slot-named | 
					
						
							|  |  |  |         dup double-infinite-interval? [ drop f ] when
 | 
					
						
							|  |  |  |     ] with filter ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-27 15:07:39 -04:00
										 |  |  | : many-where ( tuple seq -- )
 | 
					
						
							|  |  |  |     " where " 0% [ | 
					
						
							|  |  |  |         " and " 0% | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-09-27 15:07:39 -04:00
										 |  |  |         2dup slot-name>> swap get-slot-named where | 
					
						
							|  |  |  |     ] interleave drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : where-clause ( tuple specs -- )
 | 
					
						
							|  |  |  |     dupd filter-slots [ drop ] [ many-where ] if-empty ;
 | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: db-connection <delete-tuples-statement> | 
					
						
							| 
									
										
										
										
											2008-04-28 18:35:45 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         "delete from " 0% 0% | 
					
						
							| 
									
										
										
										
											2008-04-28 21:27:37 -04:00
										 |  |  |         where-clause | 
					
						
							| 
									
										
										
										
											2008-04-28 18:35:45 -04:00
										 |  |  |     ] query-make ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-02 00:33:57 -04:00
										 |  |  | ERROR: all-slots-ignored class ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: db-connection <select-by-slots-statement> | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         "select " 0% | 
					
						
							| 
									
										
										
										
											2008-09-30 12:00:44 -04:00
										 |  |  |         [ dupd filter-ignores ] dip
 | 
					
						
							| 
									
										
										
										
											2015-08-13 19:13:05 -04:00
										 |  |  |         over empty? [ all-slots-ignored ] when
 | 
					
						
							| 
									
										
										
										
											2008-09-30 12:00:44 -04:00
										 |  |  |         over
 | 
					
						
							|  |  |  |         [ ", " 0% ] | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  |         [ dup column-name>> 0% 2, ] interleave
 | 
					
						
							|  |  |  |         " from " 0% 0% | 
					
						
							| 
									
										
										
										
											2008-04-28 21:27:37 -04:00
										 |  |  |         where-clause | 
					
						
							| 
									
										
										
										
											2008-04-21 01:45:14 -04:00
										 |  |  |     ] query-make ;
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : do-group ( tuple groups -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-18 16:15:27 -04:00
										 |  |  |     dup string? [ 1array ] when
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:10:41 -05:00
										 |  |  |     [ ", " join " group by " glue ] curry change-sql drop ;
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : do-order ( tuple order -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-18 16:15:27 -04:00
										 |  |  |     dup string? [ 1array ] when
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:10:41 -05:00
										 |  |  |     [ ", " join " order by " glue ] curry change-sql drop ;
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : do-offset ( tuple n -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:10:41 -05:00
										 |  |  |     [ number>string " offset " glue ] curry change-sql drop ;
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : do-limit ( tuple n -- )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 20:10:41 -05:00
										 |  |  |     [ number>string " limit " glue ] curry change-sql drop ;
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-23 16:59:33 -04:00
										 |  |  | : make-query* ( tuple query -- tuple' )
 | 
					
						
							| 
									
										
										
										
											2008-05-30 23:47:38 -04:00
										 |  |  |     dupd
 | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-09-05 20:29:14 -04:00
										 |  |  |         [ group>> [ drop ] [ do-group ] if-empty ] | 
					
						
							|  |  |  |         [ order>> [ drop ] [ do-order ] if-empty ] | 
					
						
							| 
									
										
										
										
											2008-05-30 19:00:42 -04:00
										 |  |  |         [ limit>> [ do-limit ] [ drop ] if* ] | 
					
						
							|  |  |  |         [ offset>> [ do-offset ] [ drop ] if* ] | 
					
						
							|  |  |  |     } 2cleave ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: db-connection query>statement | 
					
						
							| 
									
										
										
										
											2011-10-24 20:00:09 -04:00
										 |  |  |     [ tuple>> dup class-of ] keep
 | 
					
						
							| 
									
										
										
										
											2008-09-23 16:59:33 -04:00
										 |  |  |     [ <select-by-slots-statement> ] dip make-query* ;
 | 
					
						
							| 
									
										
										
										
											2008-06-07 11:48:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! select ID, NAME, SCORE from EXAM limit 1 offset 3 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 17:41:17 -04:00
										 |  |  | M: db-connection <count-statement> | 
					
						
							| 
									
										
										
										
											2011-10-24 20:00:09 -04:00
										 |  |  |     [ tuple>> dup class-of ] keep
 | 
					
						
							| 
									
										
										
										
											2008-06-07 11:48:05 -04:00
										 |  |  |     [ [ "select count(*) from " 0% 0% where-clause ] query-make ] | 
					
						
							| 
									
										
										
										
											2008-09-23 16:59:33 -04:00
										 |  |  |     dip make-query* ;
 | 
					
						
							| 
									
										
										
										
											2008-06-07 11:48:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-13 02:17:10 -04:00
										 |  |  | : create-index ( index-name table-name columns -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-11-29 16:19:09 -05:00
										 |  |  |         [ [ "create index " % % ] dip " on " % % ] dip "(" % | 
					
						
							| 
									
										
										
										
											2008-06-13 02:17:10 -04:00
										 |  |  |         "," join % ")" % | 
					
						
							|  |  |  |     ] "" make sql-command ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-20 13:14:02 -05:00
										 |  |  | : ensure-index ( index-name table-name columns -- )
 | 
					
						
							|  |  |  |     '[ _ _ _ create-index ] ignore-index-exists ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-13 02:17:10 -04:00
										 |  |  | : drop-index ( index-name -- )
 | 
					
						
							|  |  |  |     [ "drop index " % % ] "" make sql-command ;
 | 
					
						
							| 
									
										
										
										
											2011-09-04 17:52:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : create-database ( string -- )
 | 
					
						
							|  |  |  |     "create database " ";" surround sql-command ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ensure-database ( string -- )
 | 
					
						
							|  |  |  |     '[ _ create-database ] ignore-database-exists ;
 |