]> gitweb.factorcode.org Git - factor.git/blob - basis/db/tuples/tuples.factor
Fix permission bits
[factor.git] / basis / db / tuples / tuples.factor
1 ! Copyright (C) 2008 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays assocs classes db kernel namespaces
4 classes.tuple words sequences slots math accessors
5 math.parser io prettyprint db.types continuations
6 destructors mirrors sets db.types ;
7 IN: db.tuples
8
9 <PRIVATE
10 ! returns a sequence of prepared-statements
11 HOOK: create-sql-statement db ( class -- object )
12 HOOK: drop-sql-statement db ( class -- object )
13
14 HOOK: <insert-db-assigned-statement> db ( class -- object )
15 HOOK: <insert-user-assigned-statement> db ( class -- object )
16 HOOK: <update-tuple-statement> db ( class -- object )
17 HOOK: <delete-tuples-statement> db ( tuple class -- object )
18 HOOK: <select-by-slots-statement> db ( tuple class -- tuple )
19 HOOK: <count-statement> db ( query -- statement )
20 HOOK: query>statement db ( query -- statement )
21
22 HOOK: insert-tuple-set-key db ( tuple statement -- )
23
24 SYMBOL: sql-counter
25 : next-sql-counter ( -- str )
26     sql-counter [ inc ] [ get ] bi number>string ;
27
28 GENERIC: eval-generator ( singleton -- object )
29
30 : resulting-tuple ( exemplar-tuple row out-params -- tuple )
31     rot class new [
32         [ [ slot-name>> ] dip set-slot-named ] curry 2each
33     ] keep ;
34
35 : query-tuples ( exemplar-tuple statement -- seq )
36     [ out-params>> ] keep query-results [
37         [ sql-row-typed swap resulting-tuple ] with with query-map
38     ] with-disposal ;
39  
40 : query-modify-tuple ( tuple statement -- )
41     [ query-results [ sql-row-typed ] with-disposal ] keep
42     out-params>> rot [
43         [ slot-name>> ] dip set-slot-named
44     ] curry 2each ;
45
46 : with-disposals ( object quotation -- )
47     over sequence? [
48         [ with-disposal ] curry each
49     ] [
50         with-disposal
51     ] if ; inline
52
53 : insert-db-assigned-statement ( tuple -- )
54     dup class
55     db get insert-statements>> [ <insert-db-assigned-statement> ] cache
56     [ bind-tuple ] 2keep insert-tuple-set-key ;
57
58 : insert-user-assigned-statement ( tuple -- )
59     dup class
60     db get insert-statements>> [ <insert-user-assigned-statement> ] cache
61     [ bind-tuple ] keep execute-statement ;
62
63 : do-select ( exemplar-tuple statement -- tuples )
64     [ [ bind-tuple ] [ query-tuples ] 2bi ] with-disposal ;
65
66 : do-count ( exemplar-tuple statement -- tuples )
67     [ [ bind-tuple ] [ nip default-query ] 2bi ] with-disposal ;
68 PRIVATE>
69
70
71 ! High level
72 ERROR: no-slots-named class seq ;
73 : check-columns ( class columns -- )
74     tuck
75     [ [ first ] map ]
76     [ all-slots [ name>> ] map ] bi* diff
77     [ drop ] [ no-slots-named ] if-empty ;
78
79 : define-persistent ( class table columns -- )
80     pick dupd
81     check-columns
82     [ dupd "db-table" set-word-prop dup ] dip
83     [ relation? ] partition swapd
84     dupd [ spec>tuple ] with map
85     "db-columns" set-word-prop
86     "db-relations" set-word-prop ;
87
88 TUPLE: query tuple group order offset limit ;
89
90 : <query> ( -- query ) \ query new ;
91
92 GENERIC: >query ( object -- query )
93
94 M: query >query clone ;
95
96 M: tuple >query <query> swap >>tuple ;
97
98 : create-table ( class -- )
99     create-sql-statement [ execute-statement ] with-disposals ;
100
101 : drop-table ( class -- )
102     drop-sql-statement [ execute-statement ] with-disposals ;
103
104 : recreate-table ( class -- )
105     [
106         [ drop-sql-statement [ execute-statement ] with-disposals
107         ] curry ignore-errors
108     ] [ create-table ] bi ;
109
110 : ensure-table ( class -- ) [ create-table ] curry ignore-errors ;
111
112 : ensure-tables ( classes -- ) [ ensure-table ] each ;
113
114 : insert-tuple ( tuple -- )
115     dup class db-columns find-primary-key db-assigned-id-spec?
116     [ insert-db-assigned-statement ] [ insert-user-assigned-statement ] if ;
117
118 : update-tuple ( tuple -- )
119     dup class
120     db get update-statements>> [ <update-tuple-statement> ] cache
121     [ bind-tuple ] keep execute-statement ;
122
123 : delete-tuples ( tuple -- )
124     dup dup class <delete-tuples-statement> [
125         [ bind-tuple ] keep execute-statement
126     ] with-disposal ;
127
128 : select-tuples ( query/tuple -- tuples )
129     >query [ tuple>> ] [ query>statement ] bi do-select ;
130
131 : select-tuple ( query/tuple -- tuple/f )
132     >query 1 >>limit [ tuple>> ] [ query>statement ] bi do-select
133     [ f ] [ first ] if-empty ;
134
135 : count-tuples ( query/tuple -- n )
136     >query [ tuple>> ] [ <count-statement> ] bi do-count
137     dup length 1 =
138     [ first first string>number ] [ [ first string>number ] map ] if ;