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,373 @@
|
|
1
|
+
#===============================================================================
|
2
|
+
# Audrey::Query::Q0
|
3
|
+
#
|
4
|
+
class Audrey::Query::Q0 < Audrey::Query
|
5
|
+
attr_reader :db
|
6
|
+
attr_accessor :fields
|
7
|
+
attr_accessor :fclass
|
8
|
+
attr_accessor :limit
|
9
|
+
attr_accessor :offset
|
10
|
+
|
11
|
+
#---------------------------------------------------------------------------
|
12
|
+
# initialize
|
13
|
+
#
|
14
|
+
def initialize(p_db)
|
15
|
+
# check that we got a Audrey object
|
16
|
+
if not p_db.is_a?(Audrey)
|
17
|
+
raise 'db-not-audrey: ' + pdb.class.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
@db = p_db
|
21
|
+
@engine = @db.engine
|
22
|
+
@fclass = nil
|
23
|
+
@fields = Audrey::Query::Q0::Fields.new()
|
24
|
+
end
|
25
|
+
#
|
26
|
+
# initialize
|
27
|
+
#---------------------------------------------------------------------------
|
28
|
+
|
29
|
+
|
30
|
+
#---------------------------------------------------------------------------
|
31
|
+
# each
|
32
|
+
#
|
33
|
+
def each(opts={})
|
34
|
+
# $tm.hrm
|
35
|
+
equery = @engine.q0(self)
|
36
|
+
|
37
|
+
# loop through equery results
|
38
|
+
equery.each(opts) do |pk|
|
39
|
+
yield @db.object_from_pk(pk)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
#
|
43
|
+
# each
|
44
|
+
#---------------------------------------------------------------------------
|
45
|
+
|
46
|
+
|
47
|
+
#---------------------------------------------------------------------------
|
48
|
+
# sample
|
49
|
+
#
|
50
|
+
def sample
|
51
|
+
# $tm.hrm
|
52
|
+
cl = self.clone()
|
53
|
+
cl.limit = 1
|
54
|
+
cl.offset = rand(self.count)
|
55
|
+
return cl.first
|
56
|
+
end
|
57
|
+
#
|
58
|
+
# sample
|
59
|
+
#---------------------------------------------------------------------------
|
60
|
+
|
61
|
+
|
62
|
+
#---------------------------------------------------------------------------
|
63
|
+
# samples
|
64
|
+
# KLUDGE: This routine could be more efficient by not creating an object
|
65
|
+
# out of every sample until it's determined that we don't already have the
|
66
|
+
# object.
|
67
|
+
#
|
68
|
+
def samples(count)
|
69
|
+
rv = {}
|
70
|
+
|
71
|
+
# loop until we get enough objects
|
72
|
+
while rv.length < count
|
73
|
+
obj = sample()
|
74
|
+
|
75
|
+
if not rv[obj.audrey.pk]
|
76
|
+
rv[obj.audrey.pk] = obj
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# return
|
81
|
+
return rv.values
|
82
|
+
end
|
83
|
+
#
|
84
|
+
# sample
|
85
|
+
#---------------------------------------------------------------------------
|
86
|
+
|
87
|
+
|
88
|
+
#---------------------------------------------------------------------------
|
89
|
+
# count
|
90
|
+
#
|
91
|
+
def count
|
92
|
+
return @engine.q0(self).count
|
93
|
+
end
|
94
|
+
#
|
95
|
+
# count
|
96
|
+
#---------------------------------------------------------------------------
|
97
|
+
|
98
|
+
|
99
|
+
#---------------------------------------------------------------------------
|
100
|
+
# sum
|
101
|
+
#
|
102
|
+
def sum(fname)
|
103
|
+
total = 0
|
104
|
+
|
105
|
+
# optimize the query by cloning and add Defined
|
106
|
+
qopt = self.clone
|
107
|
+
qopt.fields.add 'calls', qopt.defined
|
108
|
+
|
109
|
+
# loop through records
|
110
|
+
qopt.run do |record|
|
111
|
+
field = record.audrey[fname]
|
112
|
+
|
113
|
+
if field.is_a?(Numeric)
|
114
|
+
total += field
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# return
|
119
|
+
return total
|
120
|
+
end
|
121
|
+
#
|
122
|
+
# sum
|
123
|
+
#---------------------------------------------------------------------------
|
124
|
+
|
125
|
+
|
126
|
+
#---------------------------------------------------------------------------
|
127
|
+
# first
|
128
|
+
# returns the first record in the query, or nil if the query didn't find
|
129
|
+
# anything
|
130
|
+
#
|
131
|
+
def first
|
132
|
+
each() do |obj|
|
133
|
+
return obj
|
134
|
+
end
|
135
|
+
|
136
|
+
return nil
|
137
|
+
end
|
138
|
+
#
|
139
|
+
# first
|
140
|
+
#---------------------------------------------------------------------------
|
141
|
+
|
142
|
+
|
143
|
+
#---------------------------------------------------------------------------
|
144
|
+
# defined
|
145
|
+
#
|
146
|
+
def defined
|
147
|
+
return Audrey::Query::Q0::Defined
|
148
|
+
end
|
149
|
+
#
|
150
|
+
# defined
|
151
|
+
#---------------------------------------------------------------------------
|
152
|
+
|
153
|
+
|
154
|
+
#---------------------------------------------------------------------------
|
155
|
+
# fclasses
|
156
|
+
#
|
157
|
+
def fclasses
|
158
|
+
# $tm.hrm
|
159
|
+
|
160
|
+
# early exit: no fclass
|
161
|
+
if not @fclass
|
162
|
+
return nil
|
163
|
+
end
|
164
|
+
|
165
|
+
# initialize
|
166
|
+
fcs = [*@fclass]
|
167
|
+
|
168
|
+
# early exit: fclass is an empty array
|
169
|
+
# NOTE: An empty array would mean that not records are returned, so
|
170
|
+
# we'll interpret it to mean all records.
|
171
|
+
if not fcs.any?
|
172
|
+
return nil
|
173
|
+
end
|
174
|
+
|
175
|
+
# initialize
|
176
|
+
rv = {}
|
177
|
+
|
178
|
+
# build fclasses
|
179
|
+
fcs.each do |fclass|
|
180
|
+
fclass.fclasses.each do |desc|
|
181
|
+
rv[desc] = nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# return
|
186
|
+
return rv.keys
|
187
|
+
end
|
188
|
+
#
|
189
|
+
# fclasses
|
190
|
+
#---------------------------------------------------------------------------
|
191
|
+
|
192
|
+
|
193
|
+
#---------------------------------------------------------------------------
|
194
|
+
# clone
|
195
|
+
#
|
196
|
+
def clone
|
197
|
+
# $tm.hrm
|
198
|
+
rv = self.class.new(@db)
|
199
|
+
|
200
|
+
# fclass
|
201
|
+
if @fclass.is_a?(Array)
|
202
|
+
rv.fclass = @fclass.clone
|
203
|
+
else
|
204
|
+
rv.fclass = @fclass
|
205
|
+
end
|
206
|
+
|
207
|
+
# fields
|
208
|
+
rv.fields = @fields.clone
|
209
|
+
|
210
|
+
# return
|
211
|
+
return rv
|
212
|
+
end
|
213
|
+
#
|
214
|
+
# clone
|
215
|
+
#---------------------------------------------------------------------------
|
216
|
+
|
217
|
+
|
218
|
+
#---------------------------------------------------------------------------
|
219
|
+
# iterator
|
220
|
+
#
|
221
|
+
def iterator
|
222
|
+
# $tm.hrm
|
223
|
+
return Audrey::Query::Q0::Iterator.new(self, @engine.q0(self).iterator)
|
224
|
+
end
|
225
|
+
#
|
226
|
+
# iterator
|
227
|
+
#---------------------------------------------------------------------------
|
228
|
+
end
|
229
|
+
#
|
230
|
+
# Audrey::Query::Q0
|
231
|
+
#===============================================================================
|
232
|
+
|
233
|
+
|
234
|
+
#===============================================================================
|
235
|
+
# Audrey::Query::Q0::Defined
|
236
|
+
# This module doesn't do anything. It's just a way of inidicating in a query
|
237
|
+
# that any defined hash value is acceptable.
|
238
|
+
#
|
239
|
+
module Audrey::Query::Q0::Defined
|
240
|
+
end
|
241
|
+
#
|
242
|
+
# Audrey::Query::Q0::Defined
|
243
|
+
#===============================================================================
|
244
|
+
|
245
|
+
|
246
|
+
#===============================================================================
|
247
|
+
# Audrey::Query::Q0::Fields
|
248
|
+
#
|
249
|
+
class Audrey::Query::Q0::Fields
|
250
|
+
extend Forwardable
|
251
|
+
|
252
|
+
#---------------------------------------------------------------------------
|
253
|
+
# delegate hash functions to @root
|
254
|
+
#
|
255
|
+
delegate(%w(
|
256
|
+
[] []= each length keys values delete clear == <= >= ===
|
257
|
+
has_key? any?
|
258
|
+
) => :@hsh);
|
259
|
+
#
|
260
|
+
# delegate hash functions to @root
|
261
|
+
#---------------------------------------------------------------------------
|
262
|
+
|
263
|
+
|
264
|
+
#---------------------------------------------------------------------------
|
265
|
+
# initialize
|
266
|
+
#
|
267
|
+
def initialize
|
268
|
+
@hsh = {}
|
269
|
+
end
|
270
|
+
#
|
271
|
+
# initialize
|
272
|
+
#---------------------------------------------------------------------------
|
273
|
+
|
274
|
+
|
275
|
+
#---------------------------------------------------------------------------
|
276
|
+
# add
|
277
|
+
#
|
278
|
+
def add(key, val)
|
279
|
+
if not @hsh[key].is_a?(Array)
|
280
|
+
@hsh[key] = [@hsh[key]]
|
281
|
+
end
|
282
|
+
|
283
|
+
@hsh[key].push val
|
284
|
+
end
|
285
|
+
#
|
286
|
+
# add
|
287
|
+
#---------------------------------------------------------------------------
|
288
|
+
|
289
|
+
|
290
|
+
#---------------------------------------------------------------------------
|
291
|
+
# clone
|
292
|
+
#
|
293
|
+
def clone
|
294
|
+
rv = self.class.new()
|
295
|
+
|
296
|
+
# fields
|
297
|
+
@hsh.each do |k,v|
|
298
|
+
if v.is_a?(Array)
|
299
|
+
rv[k] = v.clone
|
300
|
+
else
|
301
|
+
rv[k] = v
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# return
|
306
|
+
return rv
|
307
|
+
end
|
308
|
+
#
|
309
|
+
# clone
|
310
|
+
#---------------------------------------------------------------------------
|
311
|
+
end
|
312
|
+
#
|
313
|
+
# Audrey::Query::Q0::Fields
|
314
|
+
#===============================================================================
|
315
|
+
|
316
|
+
|
317
|
+
#===============================================================================
|
318
|
+
# Audrey::Query::Q0::Iterator
|
319
|
+
#
|
320
|
+
class Audrey::Query::Q0::Iterator
|
321
|
+
attr_reader :pk
|
322
|
+
attr_reader :eiterator
|
323
|
+
|
324
|
+
#---------------------------------------------------------------------------
|
325
|
+
# initialize
|
326
|
+
#
|
327
|
+
def initialize(q0, eiterator)
|
328
|
+
@pk = Audrey::Util.randstr
|
329
|
+
@q0 = q0
|
330
|
+
@db = @q0.db
|
331
|
+
@eiterator = eiterator
|
332
|
+
@q0.db.closers[@pk] = self
|
333
|
+
end
|
334
|
+
#
|
335
|
+
# initialize
|
336
|
+
#---------------------------------------------------------------------------
|
337
|
+
|
338
|
+
|
339
|
+
#---------------------------------------------------------------------------
|
340
|
+
# next
|
341
|
+
#
|
342
|
+
def next
|
343
|
+
# $tm.hrm
|
344
|
+
|
345
|
+
# if we get a next record
|
346
|
+
if row = @eiterator.next
|
347
|
+
return @db.object_from_pk(row['pk'])
|
348
|
+
|
349
|
+
# else close
|
350
|
+
else
|
351
|
+
close()
|
352
|
+
return nil
|
353
|
+
end
|
354
|
+
end
|
355
|
+
#
|
356
|
+
# next
|
357
|
+
#---------------------------------------------------------------------------
|
358
|
+
|
359
|
+
|
360
|
+
#---------------------------------------------------------------------------
|
361
|
+
# close
|
362
|
+
#
|
363
|
+
def close
|
364
|
+
@eiterator.close
|
365
|
+
@q0.db.closers.delete(@pk)
|
366
|
+
end
|
367
|
+
#
|
368
|
+
# close
|
369
|
+
#---------------------------------------------------------------------------
|
370
|
+
end
|
371
|
+
#
|
372
|
+
# Audrey::Query::Q0::Iterator
|
373
|
+
#===============================================================================
|
data/lib/audrey.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: audrey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike O'Sullivan
|
@@ -47,6 +47,10 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- README.md
|
49
49
|
- lib/audrey.rb
|
50
|
+
- lib/audrey/engine/sqlite3.rb
|
51
|
+
- lib/audrey/engine/sqlite3/init.rb
|
52
|
+
- lib/audrey/engine/sqlite3/query/q0.rb
|
53
|
+
- lib/audrey/query/q0.rb
|
50
54
|
homepage: https://rubygems.org/gems/audrey
|
51
55
|
licenses:
|
52
56
|
- MIT
|