Class: MDQuery::Model::DatasetModel

Inherits:
Object
  • Object
show all
Defined in:
lib/mdquery/model.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs) ⇒ DatasetModel

Returns a new instance of DatasetModel.



180
181
182
183
# File 'lib/mdquery/model.rb', line 180

def initialize(attrs)
  MDQuery::Util.assign_attributes(self, attrs, [:source, :dimension_models, :measure_models])
  validate
end

Instance Attribute Details

#dimension_modelsObject (readonly)

Returns the value of attribute dimension_models.



177
178
179
# File 'lib/mdquery/model.rb', line 177

def dimension_models
  @dimension_models
end

#measure_modelsObject (readonly)

Returns the value of attribute measure_models.



178
179
180
# File 'lib/mdquery/model.rb', line 178

def measure_models
  @measure_models
end

#sourceObject (readonly)

Returns the value of attribute source.



176
177
178
# File 'lib/mdquery/model.rb', line 176

def source
  @source
end

Instance Method Details

#all_dimension_segment_modelsObject

a list of lists of dimension-segments



202
203
204
# File 'lib/mdquery/model.rb', line 202

def all_dimension_segment_models
  dimension_models.map(&:segment_models)
end

#collectObject

run the queries and put the results in a Dataset



265
266
267
# File 'lib/mdquery/model.rb', line 265

def collect
  MDQuery::Dataset::Dataset.new(self, do_queries)
end

#construct_query(scope, region_segment_models, measure_models) ⇒ Object

construct a query for a region



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/mdquery/model.rb', line 223

def construct_query(scope, region_segment_models, measure_models)
  narrowed_scope = region_segment_models.reduce(scope){|scope, ds| ds.do_narrow(scope)}

  dimension_select_strings = region_segment_models.map(&:select_string)

  measure_select_strings = measure_models.map{|m| m.select_string(region_segment_models)}

  select_string = (dimension_select_strings + measure_select_strings).join(",")

  group_string = (1..region_segment_models.length).to_a.join(",")

  narrowed_scope.select(select_string).group(group_string)
end

#do_queriesObject

run the queries defined by the DatasetModel



252
253
254
255
256
257
258
259
260
261
262
# File 'lib/mdquery/model.rb', line 252

def do_queries
  data = []

  with_regions do |region_segment_models|
    q = construct_query(source, region_segment_models, measure_models)
    points = extract(q.all, region_segment_models, measure_models)
    data += points
  end

  data
end

#extract(rows, region_segment_models, measure_models) ⇒ Object

extract data points from a list of ActiveRecord models



238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/mdquery/model.rb', line 238

def extract(rows, region_segment_models, measure_models)
  rows.map do |row|
    dimension_values = region_segment_models.map do |ds|
      {ds.dimension_model.key => ds.do_cast(row.send(ds.dimension_model.key))}
    end
    measure_values = measure_models.map do |m|
      {m.key => m.do_cast(row.send(m.key))}
    end

    (dimension_values + measure_values).reduce(&:merge)
  end
end

#inspectObject



191
192
193
# File 'lib/mdquery/model.rb', line 191

def inspect
  "#<DatasetDefinition: dimension_models=#{dimension_models.inspect}, measure_models=#{measure_models.inspect}>"
end

#region_segment_model_indexesObject

a list of tuples of dimension-segment indexes, each tuple specifying one segment for each dimension. it is the cross-join of the dimension-segment indexes



197
198
199
# File 'lib/mdquery/model.rb', line 197

def region_segment_model_indexes
  dimension_models.reduce(nil){|indexes, dimension_model| dimension_model.index_list(indexes)}
end

#region_segment_models(indexes) ⇒ Object

given a list of dimension-segment indexes, one for each dimension, retrieve a list of dimension-segments, one for each dimension, specifying a region



209
210
211
212
213
# File 'lib/mdquery/model.rb', line 209

def region_segment_models(indexes)
  ds = all_dimension_segment_models
  d_i = (0...indexes.length).zip(indexes)
  d_i.map{|d,i| ds[d][i]}
end

#validateObject



185
186
187
188
189
# File 'lib/mdquery/model.rb', line 185

def validate
  raise "no source!" if !source
  raise "no dimension_models!" if !dimension_models || dimension_models.empty?
  raise "no measure_models!" if !measure_models || measure_models.empty?
end

#with_regions(&proc) ⇒ Object

call a block with a list of dimension-segments, one for each dimension



216
217
218
219
220
# File 'lib/mdquery/model.rb', line 216

def with_regions(&proc)
  region_segment_model_indexes.each do |indexes|
    proc.call(region_segment_models(indexes))
  end
end