Class: GoodData::Model::ProjectBlueprint

Inherits:
Object
  • Object
show all
Defined in:
lib/gooddata/models/blueprint/project_blueprint.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(init_data) ⇒ ProjectBlueprint

Constructor

Parameters:

  • init_data (ProjectBlueprint | Hash)

    Blueprint or a blueprint definition. If passed a hash it is used as data for new instance. If there is a ProjectBlueprint passed it is duplicated and a new instance is created.



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 409

def initialize(init_data)
  some_data = if init_data.respond_to?(:project_blueprint?) && init_data.project_blueprint?
                init_data.to_hash
              elsif init_data.respond_to?(:to_blueprint)
                init_data.to_blueprint.to_hash
              else
                init_data
              end
  @data = GoodData::Helpers.symbolize_keys(GoodData::Helpers.deep_dup(some_data))
  (@data[:datasets] || []).each do |d|
    d[:type] = d[:type].to_sym
    d[:columns].each do |c|
      c[:type] = c[:type].to_sym
    end
  end
  (@data[:date_dimensions] || []).each do |d|
    d[:type] = d[:type].to_sym
  end
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



10
11
12
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 10

def data
  @data
end

Class Method Details

.build(title, &block) ⇒ Object



30
31
32
33
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 30

def build(title, &block)
  pb = ProjectBuilder.create(title, &block)
  pb.to_blueprint
end

.dataset?(project, name, options = {}) ⇒ Boolean

Returns true if a dataset contains a particular dataset false otherwise

Parameters:

Returns:

  • (Boolean)


114
115
116
117
118
119
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 114

def self.dataset?(project, name, options = {})
  find_dataset(project, name, options)
  true
rescue
  false
end

.datasets(project_blueprint, options = {}) ⇒ Array<Hash>

Returns datasets of blueprint. Those can be optionally including date dimensions

Parameters:

Returns:



84
85
86
87
88
89
90
91
92
93
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 84

def self.datasets(project_blueprint, options = {})
  project_blueprint = project_blueprint.to_hash
  include_date_dimensions = options[:include_date_dimensions] || options[:dd]
  ds = (project_blueprint.to_hash[:datasets] || [])
  if include_date_dimensions
    ds + date_dimensions(project_blueprint)
  else
    ds
  end
end

.date_dimension?(project, name) ⇒ Boolean

Returns true if a date dimension of a given name exists in a bleuprint

Parameters:

Returns:

  • (Boolean)


150
151
152
153
154
155
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 150

def self.date_dimension?(project, name)
  find_date_dimension(project, name)
  true
rescue
  false
end

.date_dimensions(project_blueprint) ⇒ Array<Hash>

Returns list of date dimensions

Parameters:

Returns:



140
141
142
143
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 140

def self.date_dimensions(project_blueprint)
  project_blueprint.to_hash[:date_dimensions] || []
  # dims.map {|dim| DateDimension.new(dim, project_blueprint)}
end

.fields(project) ⇒ Array<Hash>

Returns fields from all datasets

Parameters:

Returns:



173
174
175
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 173

def self.fields(project)
  datasets(project).mapcat { |d| DatasetBlueprint.fields(d) }
end

.find_dataset(project_blueprint, obj, options = {}) ⇒ GoodData::Model::DatasetBlueprint

Returns dataset specified. It can check even for a date dimension

Parameters:

Returns:



127
128
129
130
131
132
133
134
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 127

def self.find_dataset(project_blueprint, obj, options = {})
  return obj.to_hash if DatasetBlueprint.dataset_blueprint?(obj)
  all_datasets = datasets(project_blueprint, options)
  name = obj.respond_to?(:to_hash) ? obj.to_hash[:id] : obj
  ds = all_datasets.find { |d| d[:id] == name }
  fail "Dataset #{name} could not be found" if ds.nil?
  ds
end

.find_date_dimension(project, name) ⇒ Hash

Finds a date dimension of a given name in a bleuprint. If a dataset is not found it throws an exeception

Parameters:

Returns:



163
164
165
166
167
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 163

def self.find_date_dimension(project, name)
  ds = date_dimensions(project).find { |d| d[:id] == name }
  fail "Date dimension #{name} could not be found" unless ds
  ds
end

.from_json(spec) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 18

def from_json(spec)
  if spec.is_a?(String)
    if File.file?(spec)
      ProjectBlueprint.new(MultiJson.load(File.read(spec), :symbolize_keys => true))
    else
      ProjectBlueprint.new(MultiJson.load(spec, :symbolize_keys => true))
    end
  else
    ProjectBlueprint.new(spec)
  end
end

.remove_column!(project, dataset, column_id) ⇒ Hash | GoodData::Model::ProjectBlueprint

Removes column from from the blueprint

Parameters:

Returns:



42
43
44
45
46
47
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 42

def self.remove_column!(project, dataset, column_id)
  dataset = find_dataset(project, dataset)
  col = dataset[:columns].find { |c| c[:id] == column_id }
  dataset[:columns].delete(col)
  project
end

.remove_dataset(project, dataset_id) ⇒ Hash

Removes dataset from blueprint. Dataset can be given as either a name or a DatasetBlueprint or a Hash representation.

Parameters:

Returns:

  • (Hash)

    new project with removed dataset



55
56
57
58
59
60
61
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 55

def self.remove_dataset(project, dataset_id)
  dataset = dataset_id.is_a?(String) ? find_dataset(project, dataset_id) : dataset_name
  index = project[:datasets].index(dataset)
  dupped_project = GoodData::Helpers.deep_dup(project)
  dupped_project[:datasets].delete_at(index)
  dupped_project
end

.remove_dataset!(project, dataset_id) ⇒ Hash

Removes dataset from blueprint. Dataset can be given as either a name or a DatasetBlueprint or a Hash representation. This version mutates the dataset in place

Parameters:

Returns:

  • (Hash)

    project with removed dataset



70
71
72
73
74
75
76
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 70

def self.remove_dataset!(project, dataset_id)
  project = project.to_hash
  dataset = dataset_id.is_a?(String) ? find_dataset(project, dataset_id) : dataset_id
  index = project[:datasets].index(dataset)
  project[:datasets].delete_at(index)
  project
end

Instance Method Details

#==(other) ⇒ Object



735
736
737
738
739
740
741
742
743
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 735

def ==(other)
  # to_hash == other.to_hash
  return false unless id == other.id
  return false unless title == other.title
  left = to_hash[:datasets].map { |d| d[:columns].to_set }.to_set
  right = other.to_hash[:datasets].map { |d| d[:columns].to_set }.to_set
  return false unless left == right
  true
end

#add_column!(dataset, column_definition) ⇒ GoodData::Model::ProjectBlueprint

Adds column to particular dataset in the blueprint

Parameters:

Returns:



235
236
237
238
239
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 235

def add_column!(dataset, column_definition)
  ds = ProjectBlueprint.find_dataset(to_hash, dataset)
  ds[:columns] << column_definition
  self
end

#add_dataset!(a_dataset, index = nil) ⇒ GoodData::Model::ProjectBlueprint

Adds dataset to the blueprint

Parameters:

  • a_dataset (Hash | GoodData::Model::SchemaBlueprint)

    dataset to be added

  • index (Integer) (defaults to: nil)

    number specifying at which position the new dataset should be added. If not specified it is added at the end

Returns:



211
212
213
214
215
216
217
218
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 211

def add_dataset!(a_dataset, index = nil)
  if index.nil? || index > datasets.length
    data[:datasets] << a_dataset.to_hash
  else
    data[:datasets].insert(index, a_dataset.to_hash)
  end
  self
end

#add_date_dimension!(a_dimension, index = nil) ⇒ Object



220
221
222
223
224
225
226
227
228
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 220

def add_date_dimension!(a_dimension, index = nil)
  dim = a_dimension.to_hash
  if index.nil? || index > date_dimensions.length
    data[:date_dimensions] << dim
  else
    data[:date_dimensions].insert(index, dim)
  end
  self
end

#attributesArray<Hash>

Returns list of attributes from all the datasets in a blueprint

Returns:



310
311
312
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 310

def attributes
  datasets.reduce([]) { |acc, elem| acc.concat(elem.attributes) }
end

#attributes_and_anchorsArray<Hash>

Returns list of attributes and anchors from all the datasets in a blueprint

Returns:



317
318
319
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 317

def attributes_and_anchors
  datasets.mapcat(&:attributes_and_anchors)
end

#change(&block) ⇒ GoodData::Model::ProjectBlueprint

Changes the dataset through a builder. You provide a block and an istance of GoodData::Model::ProjectBuilder is passed in as the only parameter

Returns:



181
182
183
184
185
186
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 181

def change(&block)
  builder = ProjectBuilder.create_from_data(self)
  block.call(builder)
  @data = builder.to_hash
  self
end

#dataset?(name, options = {}) ⇒ Boolean

Returns true if a dataset contains a particular dataset false otherwise

Parameters:

Returns:

  • (Boolean)


339
340
341
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 339

def dataset?(name, options = {})
  ProjectBlueprint.dataset?(to_hash, name, options)
end

#dataset_to_manifest(dataset, mode = 'FULL') ⇒ Array<Hash>

Returns SLI manifest for one dataset. This is used by our API to allow loading data. The method is on project blueprint because you need acces to whole project to be able to generate references

Parameters:

Returns:

  • (Array<Hash>)

    a title



350
351
352
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 350

def dataset_to_manifest(dataset, mode = 'FULL')
  ToManifest.dataset_to_manifest(self, dataset, mode)
end

#datasets(id = :all, options = {}) ⇒ Array<GoodData::Model::DatasetBlueprint>

Returns datasets of blueprint. Those can be optionally including date dimensions

Parameters:

  • options (Hash) (defaults to: {})

    options

Returns:



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 193

def datasets(id = :all, options = {})
  id = id.respond_to?(:id) ? id.id : id
  dss = ProjectBlueprint.datasets(self, options).map do |d|
    case d[:type]
    when :date_dimension
      DateDimension.new(d, self)
    when :dataset
      DatasetBlueprint.new(d, self)
    end
  end
  id == :all ? dss : dss.find { |d| d.id == id }
end

#date_dimensionsArray<Hash>

Returns list of date dimensions

Returns:



331
332
333
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 331

def date_dimensions
  ProjectBlueprint.date_dimensions(self).map { |dd| GoodData::Model::DateDimension.new(dd, self) }
end

#dupGoodData::Model::DatasetBlueprint

Duplicated blueprint

Parameters:

Returns:



358
359
360
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 358

def dup
  ProjectBlueprint.new(GoodData::Helpers.deep_dup(data))
end

#duplicate!(col, from_dataset, to_dataset) ⇒ Object



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 284

def duplicate!(col, from_dataset, to_dataset)
  from_dataset = find_dataset(from_dataset)
  to_dataset = find_dataset(to_dataset)
  column = if col.is_a?(String)
             from_dataset.find_column_by_id(col)
           else
             from_dataset.find_column(col)
           end
  fail "Column #{col} cannot be found in dataset #{from_dataset.id}" unless column
  stuff = case column.type
          when :attribute
            [column] + column.labels
          when :fact
            [column]
          when :reference
            [column]
          else
            fail 'Duplicate does not support moving #{col.type} type of field'
          end
  stuff.map(&:data).each { |c| add_column!(to_dataset, c) }
  self
end

#factsArray<Hash>

Returns list of facts from all the datasets in a blueprint

Returns:



365
366
367
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 365

def facts
  datasets.mapcat(&:facts)
end

#fieldsArray<Hash>

Returns list of fields from all the datasets in a blueprint

Returns:



372
373
374
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 372

def fields
  datasets.flat_map(&:fields)
end

#find_dataset(name, options = {}) ⇒ GoodData::Model::DatasetBlueprint

Returns dataset specified. It can check even for a date dimension

Parameters:

Returns:



381
382
383
384
385
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 381

def find_dataset(name, options = {})
  ds = datasets(name, options)
  fail "Dataset \"#{name}\" could not be found" unless ds
  ds
end

#find_dataset_by_title(title) ⇒ Array<Hash>

Returns a dataset of a given name. If a dataset is not found it throws an exeception

Parameters:

  • project (String)

    Dataset title

Returns:



391
392
393
394
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 391

def find_dataset_by_title(title)
  ds = ProjectBlueprint.find_dataset_by_title(to_hash, title)
  DatasetBlueprint.new(ds)
end

#find_star_centersArray<Hash>

Return list of datasets that are centers of the stars in datamart. This means these datasets are not referenced by anybody else In a good blueprint design these should be fact tables

Returns:



401
402
403
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 401

def find_star_centers
  datasets.select { |d| d.referenced_by.empty? }
end

#idObject



429
430
431
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 429

def id
  data[:id]
end

#labelsArray<Hash>

Returns list of labels from all the datasets in a blueprint

Returns:



436
437
438
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 436

def labels
  datasets.mapcat(&:labels)
end

#lint(full = false) ⇒ Array<Hash>

Experimental but a basis for automatic check of health of a project

Parameters:

Returns:



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 444

def lint(full = false)
  errors = []
  find_star_centers.each do |dataset|
    next unless dataset.anchor?
    errors << {
      type: :anchor_on_fact_dataset,
      dataset_name: dataset.name,
      anchor_name: dataset.anchor[:name]
    }
  end
  date_facts = datasets.mapcat(&:date_facts)
  date_facts.each do |date_fact|
    errors << {
      type: :date_fact,
      date_fact: date_fact[:name]
    }
  end

  unique_titles = fields.map { |f| Model.title(f) }.uniq
  (fields.map { |f| Model.title(f) } - unique_titles).each do |duplicate_title|
    errors << {
      type: :duplicate_title,
      title: duplicate_title
    }
  end

  datasets.select(&:wide?).each do |wide_dataset|
    errors << {
      type: :wide_dataset,
      dataset: wide_dataset.name
    }
  end

  if full
    # GoodData::Attributes.all(:full => true).select { |attr| attr.used_by}
  end
  errors
end

#merge(a_blueprint) ⇒ GoodData::Model::ProjectBlueprint

Merging two blueprints. A new blueprint is created. The self one is nto mutated

Parameters:

Returns:



627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 627

def merge(a_blueprint)
  temp_blueprint = dup
  return temp_blueprint unless a_blueprint
  a_blueprint.datasets.each do |dataset|
    if temp_blueprint.dataset?(dataset.id)
      local_dataset = temp_blueprint.find_dataset(dataset.id)
      index = temp_blueprint.datasets.index(local_dataset)
      local_dataset.merge!(dataset)
      temp_blueprint.remove_dataset!(local_dataset.id)
      temp_blueprint.add_dataset!(local_dataset, index)
    else
      temp_blueprint.add_dataset!(dataset.dup)
    end
  end
  a_blueprint.date_dimensions.each do |dd|
    if temp_blueprint.dataset?(dd.id, dd: true)
      local_dim = temp_blueprint.find_dataset(dd.id, dd: true)
      fail "Unable to merge date dimensions #{dd.id} with defintion #{dd.data} with #{local_dim.data}" unless local_dim.data == dd.data
    else
      temp_blueprint.add_date_dimension!(dd.dup)
    end
  end
  temp_blueprint
end

#merge!(a_blueprint) ⇒ GoodData::Model::ProjectBlueprint

Merging two blueprints. The self blueprint is changed in place

Parameters:

Returns:



487
488
489
490
491
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 487

def merge!(a_blueprint)
  temp_blueprint = merge(a_blueprint)
  @data = temp_blueprint.data
  self
end

#move!(col, from_dataset, to_dataset) ⇒ GoodData::Model::ProjectBlueprint

Moves column to particular dataset in the blueprint. It currently supports moving of attributes and facts only. The rest of the fields probably does not make sense In case of attribute it moves its labels as well.

Parameters:

Returns:



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 259

def move!(col, from_dataset, to_dataset)
  from_dataset = find_dataset(from_dataset)
  to_dataset = find_dataset(to_dataset)
  column = if col.is_a?(String)
             from_dataset.find_column_by_id(col)
           else
             from_dataset.find_column(col)
           end
  fail "Column #{col} cannot be found in dataset #{from_dataset.id}" unless column
  stuff = case column.type
          when :attribute
            [column] + column.labels
          when :fact
            [column]
          when :reference
            [column]
          else
            fail 'Duplicate does not support moving #{col.type} type of field'
          end
  stuff = stuff.map(&:data)
  stuff.each { |c| remove_column!(from_dataset, c[:id]) }
  stuff.each { |c| add_column!(to_dataset, c) }
  self
end

#project_blueprint?Boolean

Is this a project blueprint?

Returns:

  • (Boolean)

    if it is



324
325
326
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 324

def project_blueprint?
  true
end

#refactor_split_df(dataset) ⇒ Object



588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 588

def refactor_split_df(dataset)
  fail ValidationError unless valid?
  o = find_dataset(dataset)
  new_dataset = GoodData::Model::DatasetBlueprint.new({ type: :dataset, id: "#{o.id}_dim", columns: [] }, self)
  new_dataset.change do |d|
    d.add_anchor('vymysli_id')
    d.add_label('label.vymysli_id', reference: 'vymysli_id')
  end
  nb = merge(new_dataset.to_blueprint)
  o.attributes.each { |a| nb.move!(a, o, new_dataset.id) }
  old = nb.find_dataset(dataset)
  old.attributes.each do |a|
    remove_column!(old, a)
  end
  old.change do |d|
    d.add_reference(new_dataset.id)
  end
  nb
end

#refactor_split_facts(dataset, column_names, new_dataset_title) ⇒ Object



608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 608

def refactor_split_facts(dataset, column_names, new_dataset_title)
  fail ValidationError unless valid?
  change do |p|
    p.add_dataset(new_dataset_title) do |d|
      d.add_anchor("#{new_dataset_title}.id")
    end
  end
  dataset_to_refactor = find_dataset(dataset)
  new_dataset = find_dataset(new_dataset_title)
  column_names.each { |c| move!(c, dataset_to_refactor, new_dataset) }
  dataset_to_refactor.references.each { |ref| duplicate!(ref, dataset_to_refactor, new_dataset) }
  self
end

#referenced_by(dataset) ⇒ Array<Hash>

Returns list of datasets which are referenced by given dataset. This can be optionally switched to return even date dimensions

Parameters:

Returns:



498
499
500
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 498

def referenced_by(dataset)
  find_dataset(dataset, include_date_dimensions: true).referencing
end

#referencing(dataset) ⇒ Object



502
503
504
505
506
507
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 502

def referencing(dataset)
  datasets(:all, include_date_dimensions: true)
    .flat_map(&:references)
    .select { |r| r.dataset == dataset }
    .map(&:dataset_blueprint)
end

#remove_column!(dataset, id) ⇒ GoodData::Model::ProjectBlueprint

Removes column to particular dataset in the blueprint

Parameters:

Returns:



246
247
248
249
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 246

def remove_column!(dataset, id)
  ProjectBlueprint.remove_column!(to_hash, dataset, id)
  self
end

#remove_dataset(dataset_name) ⇒ Hash

Removes dataset from blueprint. Dataset can be given as either a name or a DatasetBlueprint or a Hash representation.

Parameters:

Returns:

  • (Hash)

    project with removed dataset



514
515
516
517
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 514

def remove_dataset(dataset_name)
  ProjectBlueprint.remove_dataset(to_hash, dataset_name)
  self
end

#remove_dataset!(dataset_id) ⇒ Hash

Removes dataset from blueprint. Dataset can be given as either a name or a DatasetBlueprint or a Hash representation.

Parameters:

Returns:

  • (Hash)

    project with removed dataset



524
525
526
527
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 524

def remove_dataset!(dataset_id)
  ProjectBlueprint.remove_dataset!(to_hash, dataset_id)
  self
end

#store_to_file(filename) ⇒ Object

Helper for storing the project blueprint into a file as JSON.

Parameters:

  • filename (String)

    Name of the file where the blueprint should be stored



655
656
657
658
659
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 655

def store_to_file(filename)
  File.open(filename, 'w') do |f|
    f << JSON.pretty_generate(to_hash)
  end
end

#strip_anchor!(dataset) ⇒ GoodData::Model::ProjectBlueprint

Removes all the labels from the anchor. This is a typical operation that people want to perform on fact tables

Returns:



533
534
535
536
537
538
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 533

def strip_anchor!(dataset)
  from_dataset = find_dataset(dataset)
  stuff = dataset.anchor.labels.map(&:data)
  stuff.each { |column| remove_column!(from_dataset, column[:id]) }
  self
end

#suggest_metricsArray<Hash> Also known as: suggest_measures

Returns some metrics that might get you started. They are just simple reports. Currently it is implemented by getting facts from star centers and randomly picking attributes form referenced datasets.

Returns:



576
577
578
579
580
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 576

def suggest_metrics
  stars = find_star_centers
  metrics = stars.map(&:suggest_metrics)
  stars.zip(metrics)
end

#suggest_reports(options = {}) ⇒ Array<Hash>

Returns some reports that might get you started. They are just simple reports. Currently it is implemented by getting facts from star centers and randomly picking attributes form referenced datasets.

Returns:



545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 545

def suggest_reports(options = {})
  strategy = options[:strategy] || :stupid
  case strategy
  when :stupid
    reports = suggest_metrics.reduce([]) do |a, e|
      star, metrics = e
      metrics.each(&:save)
      reports_stubs = metrics.map do |m|
        breaks = broken_by(star).map { |ds, a_m| ds.identifier_for(a_m) }
        [breaks, m]
      end
      a.concat(reports_stubs)
    end
    reports.reduce([]) do |a, e|
      attrs, metric = e

      attrs.each do |attr|
        a << GoodData::Report.create(:title => 'Fantastic report',
                                     :top => [attr],
                                     :left => metric)
      end
      a
    end
  end
end

#swap_date_dimension!(what, for_what) ⇒ GoodData::Model::ProjectBlueprint

Returns blueprint with all references to one date dimensions changed to reference to the other. Changes the Blueprint in place.

Parameters:

Returns:



100
101
102
103
104
105
106
107
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 100

def swap_date_dimension!(what, for_what)
  what_id = what.respond_to?(:id) ? what.id : what
  for_what_id = what.respond_to?(:id) ? for_what.id : for_what

  fields = to_hash[:datasets].flat_map { |x| x[:columns] }.select { |x| x[:type] == :date }.select { |i| i[:dataset] == what_id }
  fields.each { |f| f[:dataset] = for_what_id }
  self
end

#titleString

Returns title of a dataset. If not present it is generated from the name

Returns:



664
665
666
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 664

def title
  Model.title(to_hash) if to_hash[:title]
end

#title=(a_title) ⇒ String

Returns title of a dataset. If not present it is generated from the name

Returns:



671
672
673
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 671

def title=(a_title)
  @data[:title] = a_title
end

#to_blueprintObject



584
585
586
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 584

def to_blueprint
  self
end

#to_hashHash

Returns hash representation of blueprint

Returns:

  • (Hash)

    a title



696
697
698
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 696

def to_hash
  @data
end

#to_manifestArray<Hash>

Returns SLI manifest representation. This is used by our API to allow loading data

Returns:

  • (Array<Hash>)

    a title



688
689
690
691
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 688

def to_manifest
  validate
  ToManifest.to_manifest(to_hash)
end

#to_wireHash

Returns Wire representation. This is used by our API to generate and change projects

Returns:

  • (Hash)

    a title



679
680
681
682
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 679

def to_wire
  validate
  ToWire.to_wire(data)
end

#valid?Boolean

Validate the blueprint and all its datasets and return true if model is valid. False otherwise.

Returns:

  • (Boolean)

    is model valid?



731
732
733
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 731

def valid?
  validate.empty?
end

#validateArray

Validate the blueprint and all its datasets return array of errors that are found.

Returns:

  • (Array)

    array of errors



718
719
720
721
722
723
724
725
726
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 718

def validate
  errors = []
  errors.concat validate_references
  errors.concat datasets.reduce([]) { |acc, elem| acc.concat(elem.validate) }
  errors.concat datasets.reduce([]) { |acc, elem| acc.concat(elem.validate_gd_data_type_errors) }
  errors
rescue
  raise GoodData::ValidationError
end

#validate_referencesArray

Validate the blueprint in particular if all references reference existing datasets and valid fields inside them.

Returns:

  • (Array)

    array of errors



703
704
705
706
707
708
709
710
711
712
713
# File 'lib/gooddata/models/blueprint/project_blueprint.rb', line 703

def validate_references
  stuff = datasets(:all, include_date_dimensions: true).flat_map(&:references).select do |ref|
    begin
      ref.dataset
      false
    rescue RuntimeError
      true
    end
  end
  stuff.map { |r| { type: :bad_reference, reference: r.data, referencing_dataset: r.data[:dataset] } }
end