audrey 0.2 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/audrey/engine/sqlite3/init.rb +573 -0
- data/lib/audrey/engine/sqlite3/query/q0.rb +342 -0
- data/lib/audrey/engine/sqlite3.rb +1609 -0
- data/lib/audrey/query/q0.rb +373 -0
- data/lib/audrey.rb +1 -1
- metadata +5 -1
@@ -0,0 +1,342 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
# Audrey::Engine::SQLite3::Query::Q0
|
3
|
+
#
|
4
|
+
class Audrey::Engine::SQLite3::Query::Q0
|
5
|
+
#---------------------------------------------------------------------------
|
6
|
+
# initialize
|
7
|
+
#
|
8
|
+
def initialize(p_engine, p_fquery)
|
9
|
+
@engine = p_engine
|
10
|
+
@dbh = @engine.dbh
|
11
|
+
@fquery = p_fquery
|
12
|
+
set_query_pk()
|
13
|
+
end
|
14
|
+
#
|
15
|
+
# initialize
|
16
|
+
#---------------------------------------------------------------------------
|
17
|
+
|
18
|
+
|
19
|
+
#---------------------------------------------------------------------------
|
20
|
+
# set_query_pk
|
21
|
+
#
|
22
|
+
def set_query_pk
|
23
|
+
@qpk = Audrey::Util.randstr(40)
|
24
|
+
sql = 'insert into queries(pk) values(:qpk)'
|
25
|
+
@dbh.execute sql, 'qpk'=>@qpk
|
26
|
+
end
|
27
|
+
#
|
28
|
+
# set_query_pk
|
29
|
+
#---------------------------------------------------------------------------
|
30
|
+
|
31
|
+
|
32
|
+
#---------------------------------------------------------------------------
|
33
|
+
# sub_query_pk
|
34
|
+
#
|
35
|
+
def sub_query_pk()
|
36
|
+
# $tm.hrm
|
37
|
+
rv = Audrey::Util.randstr(40)
|
38
|
+
sql = 'insert into subqueries(pk, query) values(:sqpk, :qpk)'
|
39
|
+
@dbh.execute sql, 'sqpk'=>rv, 'qpk'=>@qpk
|
40
|
+
return rv
|
41
|
+
end
|
42
|
+
#
|
43
|
+
# sub_query_pk
|
44
|
+
#---------------------------------------------------------------------------
|
45
|
+
|
46
|
+
|
47
|
+
#---------------------------------------------------------------------------
|
48
|
+
# iterator
|
49
|
+
#
|
50
|
+
def iterator(opts={})
|
51
|
+
# $tm.hrm
|
52
|
+
subqueries = prepare_subqueries()
|
53
|
+
exec_opts = {}
|
54
|
+
|
55
|
+
# sql
|
56
|
+
sql = <<~'SQL'
|
57
|
+
select o.pk
|
58
|
+
from objects o, query_rows qr
|
59
|
+
where
|
60
|
+
o.pk = qr.parent and
|
61
|
+
qr.subquery = :sqpk
|
62
|
+
SQL
|
63
|
+
|
64
|
+
# options
|
65
|
+
exec_opts['sqpk'] = subqueries['objects']
|
66
|
+
|
67
|
+
# limit
|
68
|
+
if @fquery.limit
|
69
|
+
exec_opts['limit'] = @fquery.limit
|
70
|
+
sql += "limit :limit\n"
|
71
|
+
end
|
72
|
+
|
73
|
+
# offset
|
74
|
+
if @fquery.offset
|
75
|
+
exec_opts['offset'] = @fquery.offset
|
76
|
+
sql += "offset :offset\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
# stmt and resultset
|
80
|
+
stmt = @dbh.prepare(sql)
|
81
|
+
return stmt.execute(exec_opts)
|
82
|
+
end
|
83
|
+
#
|
84
|
+
# iterator
|
85
|
+
#---------------------------------------------------------------------------
|
86
|
+
|
87
|
+
|
88
|
+
#---------------------------------------------------------------------------
|
89
|
+
# each
|
90
|
+
#
|
91
|
+
def each(opts={})
|
92
|
+
itr = iterator(opts)
|
93
|
+
|
94
|
+
itr.each do |row|
|
95
|
+
yield row['pk']
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
itr and itr.close
|
99
|
+
end
|
100
|
+
#
|
101
|
+
# each
|
102
|
+
#---------------------------------------------------------------------------
|
103
|
+
|
104
|
+
|
105
|
+
#---------------------------------------------------------------------------
|
106
|
+
# select_objects
|
107
|
+
#
|
108
|
+
def select_objects(subqueries)
|
109
|
+
# $tm.hrm
|
110
|
+
|
111
|
+
# query params
|
112
|
+
params = {}
|
113
|
+
subqueries['objects'] = params['sqpk'] = sub_query_pk()
|
114
|
+
|
115
|
+
# initial sql
|
116
|
+
sql = <<~'SQL'
|
117
|
+
select
|
118
|
+
:sqpk as sqpk, pk
|
119
|
+
from
|
120
|
+
objects
|
121
|
+
where
|
122
|
+
(partition = :partition)
|
123
|
+
SQL
|
124
|
+
|
125
|
+
# partition pk
|
126
|
+
params['partition'] = @engine.partition
|
127
|
+
|
128
|
+
# fclasses
|
129
|
+
if (fclasses = @fquery.fclasses) and fclasses.any?
|
130
|
+
wheres = []
|
131
|
+
|
132
|
+
fclasses.each do |fclass|
|
133
|
+
rs = Audrey::Util.randstr(40)
|
134
|
+
wheres.push ":#{rs}"
|
135
|
+
params[rs] = fclass
|
136
|
+
end
|
137
|
+
|
138
|
+
# add wheres
|
139
|
+
sql += " and\n" + ' (fclass in (' + wheres.join(', ') + '))'
|
140
|
+
end
|
141
|
+
|
142
|
+
# limit to hashes
|
143
|
+
if subqueries['hash']
|
144
|
+
sql = <<~"SQL"
|
145
|
+
#{sql} and
|
146
|
+
(pk in (select parent from query_rows where subquery=:hashsqpk))
|
147
|
+
SQL
|
148
|
+
|
149
|
+
params['hashsqpk'] = subqueries['hash']
|
150
|
+
end
|
151
|
+
|
152
|
+
# prepend insert into
|
153
|
+
sql = <<~"SQL"
|
154
|
+
insert into
|
155
|
+
query_rows(subquery, parent)
|
156
|
+
#{sql}
|
157
|
+
SQL
|
158
|
+
|
159
|
+
# execute
|
160
|
+
@dbh.execute sql, params
|
161
|
+
end
|
162
|
+
#
|
163
|
+
# select_objects
|
164
|
+
#---------------------------------------------------------------------------
|
165
|
+
|
166
|
+
|
167
|
+
#---------------------------------------------------------------------------
|
168
|
+
# select_hash_elements
|
169
|
+
#
|
170
|
+
def select_hash_elements(subqueries)
|
171
|
+
# $tm.hrm
|
172
|
+
|
173
|
+
# early exit
|
174
|
+
@fquery.fields.any? or return
|
175
|
+
|
176
|
+
# build sql and params
|
177
|
+
sql = "select distinct :sqpk as sqpk, hv.parent\nfrom hash_pairs hv\nwhere"
|
178
|
+
wheres = []
|
179
|
+
params = {}
|
180
|
+
|
181
|
+
# sub_query_pk
|
182
|
+
subqueries['hash'] = params['sqpk'] = sub_query_pk()
|
183
|
+
|
184
|
+
# hash values
|
185
|
+
hash_pairs wheres, params
|
186
|
+
|
187
|
+
# add wheres
|
188
|
+
sql += "\n(" + wheres.join(") and\n(") + ')'
|
189
|
+
|
190
|
+
# wrap in insert
|
191
|
+
sql = <<~"SQL"
|
192
|
+
insert into query_rows
|
193
|
+
#{sql}
|
194
|
+
SQL
|
195
|
+
|
196
|
+
# execute
|
197
|
+
@engine.dbh.execute sql, params
|
198
|
+
end
|
199
|
+
#
|
200
|
+
# select_hash_elements
|
201
|
+
#---------------------------------------------------------------------------
|
202
|
+
|
203
|
+
|
204
|
+
#---------------------------------------------------------------------------
|
205
|
+
# count
|
206
|
+
#
|
207
|
+
def count
|
208
|
+
# $tm.hrm
|
209
|
+
subqueries = prepare_subqueries()
|
210
|
+
|
211
|
+
# sql
|
212
|
+
sql = <<~'SQL'
|
213
|
+
select count(*) as count
|
214
|
+
from objects o, query_rows qr
|
215
|
+
where
|
216
|
+
o.pk = qr.parent and
|
217
|
+
qr.subquery = :sqpk
|
218
|
+
SQL
|
219
|
+
|
220
|
+
# return count
|
221
|
+
return @dbh.get_first_value(sql, 'sqpk'=>subqueries['objects'])
|
222
|
+
end
|
223
|
+
#
|
224
|
+
# count
|
225
|
+
#---------------------------------------------------------------------------
|
226
|
+
|
227
|
+
|
228
|
+
#---------------------------------------------------------------------------
|
229
|
+
# fclasses
|
230
|
+
#
|
231
|
+
def fclasses(wheres, params)
|
232
|
+
fcs = @fquery.fclasses
|
233
|
+
fcs.any? or return
|
234
|
+
where = []
|
235
|
+
|
236
|
+
# loop through fclasses
|
237
|
+
fcs.each do |fc|
|
238
|
+
rs = Audrey::Util.randstr(40)
|
239
|
+
params[rs] = fc
|
240
|
+
where.push ':' + rs
|
241
|
+
end
|
242
|
+
|
243
|
+
# add to wheres
|
244
|
+
wheres.push 'fclass in (' + where.join(', ') + ')'
|
245
|
+
end
|
246
|
+
#
|
247
|
+
# fclasses
|
248
|
+
#---------------------------------------------------------------------------
|
249
|
+
|
250
|
+
|
251
|
+
#---------------------------------------------------------------------------
|
252
|
+
# hash_pairs
|
253
|
+
#
|
254
|
+
def hash_pairs(wheres, params)
|
255
|
+
# $tm.hrm
|
256
|
+
|
257
|
+
# loop through fields
|
258
|
+
@fquery.fields.each do |k, vals|
|
259
|
+
# key
|
260
|
+
krs = Audrey::Util.randstr(40)
|
261
|
+
params[krs] = k
|
262
|
+
|
263
|
+
# if we're looking for a null value
|
264
|
+
is_null = false
|
265
|
+
|
266
|
+
# initialize clause
|
267
|
+
clause = '(hkey=:' + krs + ')'
|
268
|
+
|
269
|
+
# if specific values are wanted
|
270
|
+
unless [*vals].include?(Audrey::Query::Q0::Defined)
|
271
|
+
send_vals = []
|
272
|
+
|
273
|
+
# force to array
|
274
|
+
# Note: just using [*vals] doesn't work because if vals is nil
|
275
|
+
# then [*vals] is an empty array
|
276
|
+
if not vals.is_a?(Array)
|
277
|
+
vals = [vals]
|
278
|
+
end
|
279
|
+
|
280
|
+
vals.each do |val|
|
281
|
+
if val.nil?
|
282
|
+
is_null = true
|
283
|
+
else
|
284
|
+
vrs = Audrey::Util.randstr(40)
|
285
|
+
params[vrs] = val
|
286
|
+
send_vals.push ':' + vrs
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# ors
|
291
|
+
ors = []
|
292
|
+
|
293
|
+
# send_vals
|
294
|
+
if send_vals.any?
|
295
|
+
ors.push 'scalar in (' + send_vals.join(', ') + ')'
|
296
|
+
end
|
297
|
+
|
298
|
+
# if null
|
299
|
+
if is_null
|
300
|
+
ors.push 'scalar is null'
|
301
|
+
end
|
302
|
+
|
303
|
+
# add scalar conditions to clause
|
304
|
+
clause += ' and (' + ors.join(') or (') + ')'
|
305
|
+
end
|
306
|
+
|
307
|
+
# if looking for a null value, add condition in which the parent
|
308
|
+
# element is selected if no such key/value pair exists
|
309
|
+
if is_null
|
310
|
+
null_clause = "((select count(*) from hash_pairs hp where parent=hv.parent and hkey=:#{krs} ) = 0)"
|
311
|
+
clause = "(#{clause}) or #{null_clause}"
|
312
|
+
end
|
313
|
+
|
314
|
+
# add where clause
|
315
|
+
wheres.push clause
|
316
|
+
end
|
317
|
+
end
|
318
|
+
#
|
319
|
+
# hash_pairs
|
320
|
+
#---------------------------------------------------------------------------
|
321
|
+
|
322
|
+
|
323
|
+
# private
|
324
|
+
private
|
325
|
+
|
326
|
+
|
327
|
+
#---------------------------------------------------------------------------
|
328
|
+
# prepare_subqueries
|
329
|
+
#
|
330
|
+
def prepare_subqueries
|
331
|
+
subqueries = {}
|
332
|
+
select_hash_elements subqueries
|
333
|
+
select_objects subqueries
|
334
|
+
return subqueries
|
335
|
+
end
|
336
|
+
#
|
337
|
+
# prepare_subqueries
|
338
|
+
#---------------------------------------------------------------------------
|
339
|
+
end
|
340
|
+
#
|
341
|
+
# Audrey::Engine::SQLite3::Query::Q0
|
342
|
+
#===============================================================================
|