mochigome 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mochigome.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'mochigome_ver'
2
2
  require 'exceptions'
3
+ require 'ordered_set'
3
4
  require 'model_extensions'
4
5
  require 'model_graph'
5
6
  require 'data_node'
data/lib/mochigome_ver.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mochigome
2
- VERSION = "0.1.10"
2
+ VERSION = "0.1.11"
3
3
  end
@@ -155,8 +155,9 @@ module Mochigome
155
155
  @model = model
156
156
  @options = {}
157
157
  @options[:fields] = []
158
- @options[:custom_subgroup_exprs] = {}
159
- @options[:custom_assocs] = {}
158
+ @options[:custom_subgroup_exprs] = ActiveSupport::OrderedHash.new
159
+ @options[:custom_assocs] = ActiveSupport::OrderedHash.new
160
+ @options[:ignore_assocs] = Set.new
160
161
  end
161
162
 
162
163
  def type_name(n)
@@ -205,6 +206,11 @@ module Mochigome
205
206
  def custom_association(tgt_cls, expr)
206
207
  @options[:custom_assocs][tgt_cls] = expr
207
208
  end
209
+
210
+ # TODO: Unit test for this feature
211
+ def ignore_assoc(name)
212
+ @options[:ignore_assocs].add name.to_sym
213
+ end
208
214
  end
209
215
 
210
216
  class AggregationSettings
data/lib/model_graph.rb CHANGED
@@ -10,7 +10,12 @@ module Mochigome
10
10
  def initialize
11
11
  @graphed_models = Set.new
12
12
  @table_to_model = {}
13
- @assoc_graph = RGL::DirectedAdjacencyGraph.new
13
+ @assoc_graph = RGL::DirectedAdjacencyGraph.new(OrderedSet)
14
+ # TODO Also maybe need to do this with hashes used internally in traversal
15
+ @assoc_graph.instance_variable_set( # Make path choice more predictable
16
+ :@vertice_dict,
17
+ ActiveSupport::OrderedHash.new
18
+ )
14
19
  @edge_conditions = {}
15
20
  @shortest_paths = {}
16
21
  end
@@ -98,8 +103,15 @@ module Mochigome
98
103
  @table_to_model[model.table_name] = model
99
104
  end
100
105
 
106
+ ignore_assocs = []
107
+ if model.acts_as_mochigome_focus?
108
+ ignore_assocs = model.mochigome_focus_settings.options[:ignore_assocs]
109
+ end
110
+
101
111
  model.reflections.
102
112
  reject{|name, assoc| assoc.through_reflection}.
113
+ reject{|name, assoc| ignore_assocs.include? name}.
114
+ to_a.sort{|a,b| a.first.to_s <=> b.first.to_s}.
103
115
  each do |name, assoc|
104
116
  # TODO: What about self associations?
105
117
  # TODO: What about associations to the same model on different keys?
@@ -117,6 +129,7 @@ module Mochigome
117
129
 
118
130
  if model.acts_as_mochigome_focus?
119
131
  model.mochigome_focus_settings.options[:custom_assocs].each do |t,e|
132
+ next if ignore_assocs.include?(t.to_s.to_sym)
120
133
  cond = e.call(model.arel_table, t.arel_table)
121
134
  [[model, t], [t, model]]. each do |edge|
122
135
  @assoc_graph.add_edge(*edge)
@@ -129,6 +142,12 @@ module Mochigome
129
142
  end
130
143
 
131
144
  added_models.each do |model|
145
+ # FIXME: Un-DRY, this is a C&P from above
146
+ ignore_assocs = []
147
+ if model.acts_as_mochigome_focus?
148
+ ignore_assocs = model.mochigome_focus_settings.options[:ignore_assocs]
149
+ end
150
+
132
151
  next unless @assoc_graph.has_vertex?(model)
133
152
  path_tree = @assoc_graph.bfs_search_tree_from(model).reverse
134
153
  path_tree.depth_first_search do |tgt_model|
@@ -143,6 +162,8 @@ module Mochigome
143
162
  # Use through reflections as a hint for preferred indirect paths
144
163
  model.reflections.
145
164
  select{|name, assoc| assoc.through_reflection}.
165
+ reject{|name, assoc| ignore_assocs.include? name}.
166
+ to_a.sort{|a,b| a.first.to_s <=> b.first.to_s}.
146
167
  each do |name, assoc|
147
168
  begin
148
169
  foreign_model = assoc.klass
@@ -0,0 +1,11 @@
1
+ module Mochigome
2
+ private
3
+
4
+ # From http://stackoverflow.com/a/8451605/351149
5
+ class OrderedSet < Set
6
+ def initialize enum = nil, &block
7
+ @hash = ActiveSupport::OrderedHash.new
8
+ super
9
+ end
10
+ end
11
+ end
data/lib/relation.rb CHANGED
@@ -8,6 +8,7 @@ module Mochigome
8
8
  @model_graph = ModelGraph.new
9
9
  @spine_layers = layers
10
10
  @models = Set.new
11
+ @model_join_stack = []
11
12
  @spine = []
12
13
  @joins = []
13
14
 
@@ -43,7 +44,7 @@ module Mochigome
43
44
 
44
45
  # Route to it in as few steps as possible, closer to spine end if tie.
45
46
  best_path = nil
46
- (@spine.reverse + (@models.to_a - @spine)).each do |link_model|
47
+ (@spine.reverse + (@models.to_a - @spine).sort{|a,b| a.name <=> b.name}).each do |link_model|
47
48
  path = @model_graph.path_thru([link_model, model])
48
49
  if path && (best_path.nil? || path.size < best_path.size)
49
50
  best_path = path
@@ -127,15 +128,24 @@ module Mochigome
127
128
  def add_join_link(src, tgt)
128
129
  raise QueryError.new("Can't join from #{src}, not available") unless
129
130
  @models.include?(src)
130
- @models.add tgt
131
- cond = @model_graph.edge_condition(src, tgt)
132
- join_to_expr_models(cond)
133
- @rel = @rel.join(tgt.arel_table, Arel::Nodes::InnerJoin).on(cond)
131
+
132
+ @model_join_stack.push tgt
133
+ begin
134
+ cond = @model_graph.edge_condition(src, tgt)
135
+ join_to_expr_models(cond)
136
+ @rel = @rel.join(tgt.arel_table, Arel::Nodes::InnerJoin).on(cond)
137
+ ensure
138
+ @model_join_stack.pop
139
+ end
140
+
134
141
  @joins << [src, tgt]
142
+ @models.add tgt
135
143
  end
136
144
 
137
145
  def join_to_expr_models(expr)
138
- @model_graph.expr_models(expr).each{|m| join_to_model(m)}
146
+ @model_graph.expr_models(expr).each do |m|
147
+ join_to_model(m) unless @model_join_stack.include?(m)
148
+ end
139
149
  end
140
150
  end
141
151
  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: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 10
10
- version: 0.1.10
9
+ - 11
10
+ version: 0.1.11
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-17 00:00:00 Z
18
+ date: 2012-05-18 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -112,6 +112,7 @@ files:
112
112
  - lib/mochigome_ver.rb
113
113
  - lib/model_extensions.rb
114
114
  - lib/model_graph.rb
115
+ - lib/ordered_set.rb
115
116
  - lib/query.rb
116
117
  - lib/relation.rb
117
118
  - lib/subgroup_model.rb