2008-04-20 18:47:43 -04:00
|
|
|
! Copyright (C) 2008 Doug Coleman.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-09-10 23:11:40 -04:00
|
|
|
USING: accessors kernel math namespaces make sequences random
|
|
|
|
strings math.parser math.intervals combinators math.bitwise
|
2008-10-01 19:13:34 -04:00
|
|
|
nmake db db.tuples db.types classes words shuffle arrays
|
2008-12-17 20:35:53 -05:00
|
|
|
destructors continuations db.tuples.private prettyprint
|
2009-04-11 10:03:00 -04:00
|
|
|
db.private byte-arrays ;
|
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 )
|
|
|
|
dup
|
|
|
|
[ bind-params>> ] [ in-params>> ] bi
|
|
|
|
[
|
|
|
|
dup generator-bind? [
|
|
|
|
generator-singleton>> eval-generator >>value
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] if
|
|
|
|
] 2map >>bind-params ;
|
|
|
|
|
|
|
|
M: retryable execute-statement* ( statement type -- )
|
|
|
|
drop [ retries>> ] [
|
|
|
|
[
|
|
|
|
nip
|
|
|
|
[ query-results dispose t ]
|
|
|
|
[ ]
|
|
|
|
[ 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
|
|
|
|
2008-09-30 00:43:34 -04:00
|
|
|
: query-make ( class quot -- statements )
|
|
|
|
#! query, input, outputs, secondary queries
|
2009-02-12 18:29:31 -05:00
|
|
|
over db-table-name "table-name" set
|
2008-09-27 15:07:39 -04:00
|
|
|
[ sql-props ] dip
|
|
|
|
[ 0 sql-counter rot with-variable ] curry
|
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
|
|
|
|
2008-12-17 20:35:53 -05:00
|
|
|
M: db-connection <update-tuple-statement> ( class -- 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 ;
|
|
|
|
|
2008-04-21 14:11:19 -04:00
|
|
|
M: random-id-generator eval-generator ( singleton -- obj )
|
|
|
|
drop
|
|
|
|
system-random-generator get [
|
2008-09-09 18:27:37 -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
|
|
|
|
|
|
|
|
M: interval where ( spec obj -- )
|
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
|
|
|
|
|
|
|
M: sequence where ( spec obj -- )
|
|
|
|
[
|
|
|
|
[ " or " 0% ] [ dupd where ] interleave drop
|
|
|
|
] in-parens ;
|
|
|
|
|
2009-04-11 10:03:00 -04:00
|
|
|
M: byte-array where ( spec obj -- )
|
|
|
|
over column-name>> 0% " = " 0% bind# ;
|
|
|
|
|
2008-10-10 21:52:28 -04:00
|
|
|
M: NULL where ( spec obj -- )
|
|
|
|
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# ;
|
|
|
|
|
|
|
|
M: object where ( spec obj -- ) object-where ;
|
|
|
|
|
|
|
|
M: integer where ( spec obj -- ) object-where ;
|
|
|
|
|
|
|
|
M: string where ( spec obj -- ) object-where ;
|
|
|
|
|
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
|
|
|
|
2008-12-17 20:35:53 -05:00
|
|
|
M: db-connection <delete-tuples-statement> ( tuple table -- sql )
|
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 ;
|
|
|
|
|
2008-12-17 20:35:53 -05:00
|
|
|
M: db-connection <select-by-slots-statement> ( tuple class -- statement )
|
2008-04-21 01:45:14 -04:00
|
|
|
[
|
|
|
|
"select " 0%
|
2008-09-30 12:00:44 -04:00
|
|
|
[ dupd filter-ignores ] dip
|
2008-10-02 00:33:57 -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 ;
|
|
|
|
|
2008-12-17 20:35:53 -05:00
|
|
|
M: db-connection query>statement ( query -- tuple )
|
2008-09-24 18:59:17 -04:00
|
|
|
[ tuple>> dup class ] 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
|
|
|
|
|
2008-12-17 20:35:53 -05:00
|
|
|
M: db-connection <count-statement> ( query -- statement )
|
2008-09-24 18:59:17 -04:00
|
|
|
[ tuple>> dup class ] 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 ;
|
|
|
|
|
|
|
|
: drop-index ( index-name -- )
|
|
|
|
[ "drop index " % % ] "" make sql-command ;
|