rgviz-rails 0.10 → 0.11

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.
@@ -6,8 +6,12 @@ module Rgviz
6
6
  def initialize(model_class, query)
7
7
  @model_class = model_class
8
8
  @query = query
9
+ @selects = []
9
10
  @joins = {}
10
11
  @labels = {}
12
+ @pivots = {}
13
+ @group_bys = {}
14
+ @original_columns = []
11
15
  case ActiveRecord::Base.connection.adapter_name.downcase
12
16
  when 'sqlite'
13
17
  @adapter = SqliteAdapter.new
@@ -20,12 +24,15 @@ module Rgviz
20
24
  @table = Table.new
21
25
  @extra_conditions = options[:conditions]
22
26
 
27
+ process_pivot
23
28
  process_labels
29
+ process_options
24
30
 
25
31
  generate_columns
26
32
  generate_conditions
27
33
  generate_group
28
34
  generate_order
35
+
29
36
  generate_rows
30
37
 
31
38
  @table
@@ -39,6 +46,33 @@ module Rgviz
39
46
  end
40
47
  end
41
48
 
49
+ def process_options
50
+ return unless @query.options.present?
51
+
52
+ @query.options.each do |option|
53
+ case option.option
54
+ when Option::NoValues
55
+ @no_values = true
56
+ when Option::NoFormat
57
+ @no_format = true
58
+ end
59
+ end
60
+ end
61
+
62
+ def process_pivot
63
+ if @query.pivot
64
+ @query.pivot.columns.each do |column|
65
+ @pivots[column.to_s] = true
66
+ end
67
+ end
68
+
69
+ if @query.group_by
70
+ @query.group_by.columns.each do |column|
71
+ @group_bys[column.to_s] = true
72
+ end
73
+ end
74
+ end
75
+
42
76
  def add_joins(joins)
43
77
  map = @joins
44
78
  joins.each do |join|
@@ -50,14 +84,15 @@ module Rgviz
50
84
  end
51
85
 
52
86
  def generate_columns
53
- @selects = []
54
-
55
87
  if @query.select && @query.select.columns.present?
56
88
  # Select the specified columns
57
89
  i = 0
58
90
  @query.select.columns.each do |col|
59
- @table.cols << (Column.new :id => column_id(col, i), :type => column_type(col), :label => column_label(col.to_s))
91
+ col_to_s = col.to_s
92
+
93
+ @table.cols << (Column.new :id => column_id(col, i), :type => column_type(col), :label => column_label(col_to_s))
60
94
  @selects << "(#{column_select(col)}) as c#{i}"
95
+ @original_columns << col_to_s
61
96
  i += 1
62
97
  end
63
98
  else
@@ -66,6 +101,19 @@ module Rgviz
66
101
  @model_class.send(:columns).each do |col|
67
102
  @table.cols << (Column.new :id => col.name, :type => (rails_column_type col), :label => column_label(col.name))
68
103
  @selects << "(#{col.name}) as c#{i}"
104
+ @original_columns << col_to_s
105
+ i += 1
106
+ end
107
+ end
108
+
109
+ # Select pivot columns
110
+ if @query.pivot
111
+ @query.pivot.columns.each do |col|
112
+ col_to_s = col.to_s
113
+
114
+ @table.cols << (Column.new :id => column_id(col, i), :type => column_type(col), :label => column_label(col_to_s))
115
+ @selects << "(#{column_select(col)}) as c#{i}"
116
+ @original_columns << col_to_s
69
117
  i += 1
70
118
  end
71
119
  end
@@ -77,6 +125,15 @@ module Rgviz
77
125
 
78
126
  def generate_group
79
127
  @group = to_string @query.group_by, ColumnVisitor if @query.group_by
128
+ pivot = to_string @query.pivot, ColumnVisitor if @query.pivot
129
+
130
+ if pivot.present?
131
+ if @group.present?
132
+ @group += ',' + pivot
133
+ else
134
+ @group = pivot
135
+ end
136
+ end
80
137
  end
81
138
 
82
139
  def generate_order
@@ -106,14 +163,102 @@ module Rgviz
106
163
  :offset => @query.offset,
107
164
  :joins => @joins
108
165
 
109
- results.each do |result|
110
- row = Row.new
111
- @table.rows << row
166
+ if @pivots.empty?
167
+ # Simple, just convert the results to a table
168
+ results.each do |result|
169
+ row = Row.new
170
+ @table.rows << row
171
+
172
+ i = 0
173
+ @table.cols.each do |col|
174
+ hash = {}
175
+ hash[:v] = column_value(col, result.send("c#{i}")) unless @no_values
176
+ row.c << Cell.new(hash)
177
+ i += 1
178
+ end
179
+ end
180
+ else
181
+ # A little more complicated...
182
+
183
+ # This has the grouping as a key and the pivoted selection values as a key (in a list)
184
+ fin = ActiveSupport::OrderedHash.new
112
185
 
113
- i = 0
114
- @table.cols.each do |col|
115
- row.c << (Cell.new :v => column_value(col, result.send("c#{i}")))
116
- i += 1
186
+ # The uniq pivot values
187
+ uniq_pivots = []
188
+
189
+ # Fill fin and uniq_pivots
190
+ results.each do |result|
191
+
192
+ # The grouping key of this result
193
+ grouped_by = []
194
+
195
+ # The pivots of this result
196
+ pivots = []
197
+
198
+ # The selections of this result
199
+ selections = []
200
+
201
+ # Fill grouped_by, pivots and selections, as well as uniq_pivots
202
+ @table.cols.each_with_index do |col, i|
203
+ val = column_value(col, result.send("c#{i}"))
204
+ if @group_bys.include?(@original_columns[i])
205
+ grouped_by << val
206
+ elsif @pivots.include?(@original_columns[i])
207
+ pivots << val
208
+ uniq_pivots << val unless uniq_pivots.include? val
209
+ else
210
+ selections << val
211
+ end
212
+ end
213
+
214
+ # Now put all this info into fin
215
+ fin[grouped_by] = {} unless fin[grouped_by]
216
+ pivots.each do |pivot|
217
+ selections.each do |selection|
218
+ fin[grouped_by][pivot] = selection
219
+ end
220
+ end
221
+ end
222
+
223
+ # Sort the uniq pivots so the results will be sorted for a human
224
+ uniq_pivots.sort!
225
+
226
+ # Regenerate the columns info: the current info has the values
227
+ # we needed to get the info we needed
228
+ col_i = 0
229
+ new_cols = []
230
+ @original_columns.each_with_index do |original_column, i|
231
+ old_col = @table.cols[i]
232
+ if @group_bys.include?(original_column)
233
+ old_col.id = "c#{col_i}"
234
+ new_cols << @table.cols[i]
235
+ col_i += 1
236
+ elsif !@pivots.include?(original_column)
237
+ uniq_pivots.each do |uniq_pivot|
238
+ new_cols << (Column.new :id => "c#{col_i}", :type => old_col.type, :label => "#{uniq_pivot} #{old_col.label}")
239
+ col_i += 1
240
+ end
241
+ end
242
+ end
243
+
244
+ @table.cols = new_cols
245
+
246
+ # Create the rows
247
+ fin.each do |key, value|
248
+ row = Row.new
249
+ @table.rows << row
250
+
251
+ group_i = 0
252
+ @original_columns.each_with_index do |original_column, i|
253
+ if @group_bys.include?(original_column)
254
+ row.c << (Cell.new :v => key[group_i])
255
+ group_i += 1
256
+ elsif !@pivots.include?(original_column)
257
+ uniq_pivots.each do |uniq_pivot|
258
+ row.c << (Cell.new :v => value[uniq_pivot])
259
+ end
260
+ end
261
+ end
117
262
  end
118
263
  end
119
264
  end
@@ -202,11 +202,21 @@ describe Executor do
202
202
  Person.make :age => 3
203
203
 
204
204
  table = exec 'select age where age > 1', :conditions => 'age < 3'
205
+ it "processes with conditions as string" do
206
+ Person.make :age => 1
207
+ Person.make :age => 2
208
+ Person.make :age => 3
209
+
210
+ table = exec 'select age', :conditions => 'age = 2'
205
211
 
206
212
  table.rows.length.should == 1
207
213
  table.rows[0].c.length.should == 1
208
214
  table.rows[0].c[0].v.should == 2
209
215
  end
216
+ table.rows.length.should == 1
217
+ table.rows[0].c.length.should == 1
218
+ table.rows[0].c[0].v.should == 2
219
+ end
210
220
 
211
221
  it "processes with conditions as array" do
212
222
  Person.make :age => 1
@@ -276,4 +286,78 @@ describe Executor do
276
286
  Person.make :age => 2
277
287
  end
278
288
 
289
+ it_processes_single_select_column "1 options no_values", 'c0', :number, nil, "1"
290
+
291
+ it "processes pivot" do
292
+ Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 1000
293
+ Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 500
294
+ Person.make :name => 'Eng', :birthday => '2000-01-13', :age => 600
295
+ Person.make :name => 'Sales', :birthday => '2000-01-12', :age => 400
296
+ Person.make :name => 'Sales', :birthday => '2000-01-12', :age => 350
297
+ Person.make :name => 'Marketing', :birthday => '2000-01-13', :age => 800
298
+
299
+ table = exec 'select name, sum(age) group by name pivot birthday'
300
+
301
+ table.cols.length.should == 3
302
+
303
+ i = 0
304
+ [['c0', :string, 'name'],
305
+ ['c1', :number, '2000-01-12 sum(age)'],
306
+ ['c2', :number, '2000-01-13 sum(age)']].each do |id, type, label|
307
+ table.cols[i].id.should == id
308
+ table.cols[i].type.should == type
309
+ table.cols[i].label.should == label
310
+ i += 1
311
+ end
312
+
313
+ table.rows.length.should == 3
314
+
315
+ i = 0
316
+ [['Eng', 1500, 600],
317
+ ['Marketing', nil, 800],
318
+ ['Sales', 750, nil]].each do |values|
319
+ table.rows[i].c.length.should == 3
320
+ values.each_with_index do |v, j|
321
+ table.rows[i].c[j].v.should == v
322
+ end
323
+ i += 1
324
+ end
325
+ end
326
+
327
+ it "processes pivot2" do
328
+ Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 1000
329
+ Person.make :name => 'Eng', :birthday => '2000-01-12', :age => 500
330
+ Person.make :name => 'Eng', :birthday => '2000-01-13', :age => 600
331
+ Person.make :name => 'Sales', :birthday => '2000-01-12', :age => 400
332
+ Person.make :name => 'Sales', :birthday => '2000-01-12', :age => 350
333
+ Person.make :name => 'Marketing', :birthday => '2000-01-13', :age => 800
334
+
335
+ table = exec 'select sum(age), name group by name pivot birthday'
336
+
337
+ table.cols.length.should == 3
338
+
339
+ i = 0
340
+ [['c0', :number, '2000-01-12 sum(age)'],
341
+ ['c1', :number, '2000-01-13 sum(age)'],
342
+ ['c2', :string, 'name']].each do |id, type, label|
343
+ table.cols[i].id.should == id
344
+ table.cols[i].type.should == type
345
+ table.cols[i].label.should == label
346
+ i += 1
347
+ end
348
+
349
+ table.rows.length.should == 3
350
+
351
+ i = 0
352
+ [[1500, 600, 'Eng'],
353
+ [nil, 800, 'Marketing'],
354
+ [750, nil, 'Sales']].each do |values|
355
+ table.rows[i].c.length.should == 3
356
+ values.each_with_index do |v, j|
357
+ table.rows[i].c[j].v.should == v
358
+ end
359
+ i += 1
360
+ end
361
+ end
362
+
279
363
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgviz-rails
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 10
9
- version: "0.10"
8
+ - 11
9
+ version: "0.11"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ary Borenszweig