mochigome 0.1.7 → 0.1.8
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.
- data/lib/mochigome_ver.rb +1 -1
- data/lib/model_extensions.rb +19 -2
- data/lib/model_graph.rb +12 -0
- data/test/app_root/app/models/widget.rb +7 -0
- data/test/app_root/app/models/widget_divisor.rb +12 -0
- data/test/app_root/db/migrate/20110817163830_create_tables.rb +8 -0
- data/test/unit/query_test.rb +43 -0
- metadata +6 -4
data/lib/mochigome_ver.rb
CHANGED
data/lib/model_extensions.rb
CHANGED
@@ -75,7 +75,7 @@ module Mochigome
|
|
75
75
|
end
|
76
76
|
|
77
77
|
if assoc.options[:as]
|
78
|
-
# FIXME Can we assume that this is the polymorphic type field?
|
78
|
+
# FIXME Can we really assume that this is the polymorphic type field?
|
79
79
|
cond = cond.and(ftable["#{assoc.options[:as]}_type"].eq(model.name))
|
80
80
|
end
|
81
81
|
|
@@ -156,6 +156,7 @@ module Mochigome
|
|
156
156
|
@options = {}
|
157
157
|
@options[:fields] = []
|
158
158
|
@options[:custom_subgroup_exprs] = {}
|
159
|
+
@options[:custom_assocs] = {}
|
159
160
|
end
|
160
161
|
|
161
162
|
def type_name(n)
|
@@ -200,6 +201,10 @@ module Mochigome
|
|
200
201
|
def custom_subgroup_expression(name, expr)
|
201
202
|
@options[:custom_subgroup_exprs][name] = expr
|
202
203
|
end
|
204
|
+
|
205
|
+
def custom_association(tgt_cls, expr)
|
206
|
+
@options[:custom_assocs][tgt_cls] = expr
|
207
|
+
end
|
203
208
|
end
|
204
209
|
|
205
210
|
class AggregationSettings
|
@@ -284,6 +289,12 @@ module Mochigome
|
|
284
289
|
:sum => lambda{|a| a.sum}
|
285
290
|
}
|
286
291
|
|
292
|
+
AGG_FUNC_DEFAULTS = {
|
293
|
+
:count => 0,
|
294
|
+
:distinct => 0,
|
295
|
+
:sum => 0
|
296
|
+
}
|
297
|
+
|
287
298
|
# Given an object, tries to coerce it into a proc that takes a node
|
288
299
|
# and returns an expression node to collect some aggregate data from it.
|
289
300
|
def self.aggregation_proc(obj)
|
@@ -330,9 +341,15 @@ module Mochigome
|
|
330
341
|
raise ModelSetupError.new "Wrong # of components for agg: #{obj.inspect}"
|
331
342
|
end
|
332
343
|
|
333
|
-
{
|
344
|
+
r = {
|
334
345
|
:agg_proc => aggregation_proc(vals[0]),
|
335
346
|
:value_proc => value_proc(vals[1])
|
336
347
|
}.merge(vals[2] || {})
|
348
|
+
|
349
|
+
if AGG_FUNC_DEFAULTS.has_key?(vals[0])
|
350
|
+
r[:default] = AGG_FUNC_DEFAULTS[vals[0]]
|
351
|
+
end
|
352
|
+
|
353
|
+
r
|
337
354
|
end
|
338
355
|
end
|
data/lib/model_graph.rb
CHANGED
@@ -114,6 +114,18 @@ module Mochigome
|
|
114
114
|
@assoc_graph.add_edge(*edge)
|
115
115
|
@edge_conditions[edge] = model.assoc_condition(name)
|
116
116
|
end
|
117
|
+
|
118
|
+
if model.acts_as_mochigome_focus?
|
119
|
+
model.mochigome_focus_settings.options[:custom_assocs].each do |t,e|
|
120
|
+
cond = e.call(model.arel_table, t.arel_table)
|
121
|
+
[[model, t], [t, model]]. each do |edge|
|
122
|
+
@assoc_graph.add_edge(*edge)
|
123
|
+
# This deliberately allows custom assocs to overwrite normal ones
|
124
|
+
@edge_conditions[edge] = cond
|
125
|
+
end
|
126
|
+
added_models << t unless added_models.include?(t)
|
127
|
+
end
|
128
|
+
end
|
117
129
|
end
|
118
130
|
|
119
131
|
added_models.each do |model|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class WidgetDivisor < ActiveRecord::Base
|
2
|
+
acts_as_mochigome_focus do |f|
|
3
|
+
f.name lambda {|r| "Divisor #{r.divisor}"}
|
4
|
+
f.custom_association Widget, lambda {|src_tbl,tgt_tbl|
|
5
|
+
# Argh, arel doesn't provide easy access to the modulus operator
|
6
|
+
((tgt_tbl[:number]/src_tbl[:divisor])*src_tbl[:divisor]).
|
7
|
+
eq(tgt_tbl[:number])
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
validates_presence_of :divisor
|
12
|
+
end
|
@@ -51,6 +51,14 @@ class CreateTables < ActiveRecord::Migration
|
|
51
51
|
t.string :foo
|
52
52
|
t.string :bar
|
53
53
|
end
|
54
|
+
|
55
|
+
# These models are for testing custom associations
|
56
|
+
create_table :widgets do |t|
|
57
|
+
t.integer :number
|
58
|
+
end
|
59
|
+
create_table :widget_divisors do |t|
|
60
|
+
t.integer :divisor
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
64
|
def self.down
|
data/test/unit/query_test.rb
CHANGED
@@ -38,6 +38,14 @@ describe Mochigome::Query do
|
|
38
38
|
].each do |sp, n|
|
39
39
|
n.times{create(:sale, :store_product => sp)}
|
40
40
|
end
|
41
|
+
|
42
|
+
(1..5).each do |div_num|
|
43
|
+
WidgetDivisor.create(:divisor => div_num)
|
44
|
+
end
|
45
|
+
|
46
|
+
(1..25).each do |num|
|
47
|
+
Widget.create(:number => num)
|
48
|
+
end
|
41
49
|
end
|
42
50
|
|
43
51
|
after do
|
@@ -47,6 +55,8 @@ describe Mochigome::Query do
|
|
47
55
|
Store.delete_all
|
48
56
|
StoreProduct.delete_all
|
49
57
|
Sale.delete_all
|
58
|
+
WidgetDivisor.delete_all
|
59
|
+
Widget.delete_all
|
50
60
|
end
|
51
61
|
|
52
62
|
# Convenience functions to check DataNode output validity
|
@@ -544,4 +554,37 @@ describe Mochigome::Query do
|
|
544
554
|
assert_equal 0, (dn/0)['Gross']
|
545
555
|
assert_equal 0, (dn/0/0)['Gross']
|
546
556
|
end
|
557
|
+
|
558
|
+
it "assumes 0 as a default value for appropriate simple aggregations" do
|
559
|
+
Sale.destroy_all
|
560
|
+
q = Mochigome::Query.new(
|
561
|
+
[Store, Product],
|
562
|
+
:aggregate_sources => [[Product, Sale]]
|
563
|
+
)
|
564
|
+
dn = q.run
|
565
|
+
assert_equal 3, dn.children.size
|
566
|
+
assert_equal 0, dn['Sales count']
|
567
|
+
assert_equal 0, (dn/0)['Sales count']
|
568
|
+
assert_equal 0, (dn/0/0)['Sales count']
|
569
|
+
end
|
570
|
+
|
571
|
+
it "can use custom associations to link records" do
|
572
|
+
q = Mochigome::Query.new([WidgetDivisor, Widget])
|
573
|
+
dn = q.run
|
574
|
+
assert_equal "Divisor 1", (dn/0).name
|
575
|
+
assert_equal 25, (dn/0).children.size
|
576
|
+
assert_equal "Divisor 2", (dn/1).name
|
577
|
+
assert_equal 12, (dn/1).children.size
|
578
|
+
assert_equal "Divisor 5", (dn/4).name
|
579
|
+
assert_equal 5, (dn/4).children.size
|
580
|
+
end
|
581
|
+
|
582
|
+
it "can follow custom associations in reverse" do
|
583
|
+
q = Mochigome::Query.new([Widget, WidgetDivisor])
|
584
|
+
dn = q.run
|
585
|
+
assert_equal "Widget 1", (dn/0).name
|
586
|
+
assert_equal 1, (dn/0).children.size
|
587
|
+
assert_equal "Widget 6", (dn/5).name
|
588
|
+
assert_equal 3, (dn/5).children.size
|
589
|
+
end
|
547
590
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mochigome
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 8
|
10
|
+
version: 0.1.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Mike Simon
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-05-
|
18
|
+
date: 2012-05-07 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -124,6 +124,8 @@ files:
|
|
124
124
|
- test/app_root/app/models/sale.rb
|
125
125
|
- test/app_root/app/models/store.rb
|
126
126
|
- test/app_root/app/models/store_product.rb
|
127
|
+
- test/app_root/app/models/widget.rb
|
128
|
+
- test/app_root/app/models/widget_divisor.rb
|
127
129
|
- test/app_root/app/transforms/report.fo.via-html.xslt.haml
|
128
130
|
- test/app_root/app/transforms/report.html.xslt.haml
|
129
131
|
- test/app_root/app/views/layouts/application.html.haml
|