gooddata 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +4 -0
  3. data/README.md +1 -0
  4. data/lib/gooddata/cli/commands/project_cmd.rb +2 -7
  5. data/lib/gooddata/client.rb +0 -2
  6. data/lib/gooddata/commands/project.rb +10 -0
  7. data/lib/gooddata/core/rest.rb +12 -2
  8. data/lib/gooddata/exceptions/attr_element_not_found.rb +12 -0
  9. data/lib/gooddata/extensions/enumerable.rb +12 -0
  10. data/lib/gooddata/helpers/global_helpers.rb +20 -0
  11. data/lib/gooddata/mixins/author.rb +16 -0
  12. data/lib/gooddata/mixins/content_getter.rb +11 -0
  13. data/lib/gooddata/mixins/content_property_reader.rb +13 -0
  14. data/lib/gooddata/mixins/content_property_writer.rb +13 -0
  15. data/lib/gooddata/mixins/contributor.rb +16 -0
  16. data/lib/gooddata/mixins/data_getter.rb +11 -0
  17. data/lib/gooddata/mixins/data_property_reader.rb +13 -0
  18. data/lib/gooddata/mixins/data_property_writer.rb +13 -0
  19. data/lib/gooddata/mixins/is_attribute.rb +13 -0
  20. data/lib/gooddata/mixins/is_fact.rb +13 -0
  21. data/lib/gooddata/mixins/is_label.rb +15 -0
  22. data/lib/gooddata/mixins/links.rb +11 -0
  23. data/lib/gooddata/mixins/md_finders.rb +36 -0
  24. data/lib/gooddata/mixins/md_id_to_uri.rb +29 -0
  25. data/lib/gooddata/mixins/md_json.rb +11 -0
  26. data/lib/gooddata/mixins/md_object_id.rb +11 -0
  27. data/lib/gooddata/mixins/md_object_indexer.rb +36 -0
  28. data/lib/gooddata/mixins/md_object_query.rb +83 -0
  29. data/lib/gooddata/mixins/md_relations.rb +39 -0
  30. data/lib/gooddata/mixins/meta_getter.rb +11 -0
  31. data/lib/gooddata/mixins/meta_property_reader.rb +13 -0
  32. data/lib/gooddata/mixins/meta_property_writer.rb +13 -0
  33. data/lib/gooddata/mixins/mixins.rb +15 -0
  34. data/lib/gooddata/mixins/not_attribute.rb +13 -0
  35. data/lib/gooddata/mixins/not_exportable.rb +11 -0
  36. data/lib/gooddata/mixins/not_fact.rb +13 -0
  37. data/lib/gooddata/mixins/not_label.rb +15 -0
  38. data/lib/gooddata/mixins/not_metric.rb +13 -0
  39. data/lib/gooddata/mixins/obj_id.rb +11 -0
  40. data/lib/gooddata/mixins/rest_getters.rb +13 -0
  41. data/lib/gooddata/mixins/rest_resource.rb +19 -0
  42. data/lib/gooddata/mixins/root_key_getter.rb +11 -0
  43. data/lib/gooddata/mixins/root_key_setter.rb +11 -0
  44. data/lib/gooddata/mixins/timestamps.rb +15 -0
  45. data/lib/gooddata/models/from_wire.rb +153 -0
  46. data/lib/gooddata/models/metadata.rb +28 -230
  47. data/lib/gooddata/models/metadata/attribute.rb +4 -6
  48. data/lib/gooddata/models/metadata/fact.rb +4 -6
  49. data/lib/gooddata/models/metadata/{display_form.rb → label.rb} +17 -11
  50. data/lib/gooddata/models/metadata/metric.rb +1 -1
  51. data/lib/gooddata/models/metadata/report_definition.rb +2 -2
  52. data/lib/gooddata/models/model.rb +55 -23
  53. data/lib/gooddata/models/models.rb +0 -2
  54. data/lib/gooddata/models/module_constants.rb +0 -2
  55. data/lib/gooddata/models/process.rb +1 -1
  56. data/lib/gooddata/models/project.rb +117 -76
  57. data/lib/gooddata/models/project_blueprint.rb +322 -42
  58. data/lib/gooddata/models/project_creator.rb +5 -4
  59. data/lib/gooddata/models/project_role.rb +20 -55
  60. data/lib/gooddata/models/schema_blueprint.rb +287 -84
  61. data/lib/gooddata/models/schema_builder.rb +0 -4
  62. data/lib/gooddata/models/to_manifest.rb +160 -0
  63. data/lib/gooddata/models/to_wire.rb +150 -0
  64. data/lib/gooddata/version.rb +1 -1
  65. data/spec/data/blueprint_invalid.json +3 -1
  66. data/spec/data/gd_gse_data_blueprint.json +1370 -0
  67. data/spec/data/gd_gse_data_manifest.json +1424 -0
  68. data/spec/data/gd_gse_data_model.json +1772 -0
  69. data/spec/data/manifest_test_project.json +116 -0
  70. data/spec/data/model_view.json +1772 -0
  71. data/spec/data/superfluous_titles_view.json +81 -0
  72. data/spec/data/test_project_model_spec.json +7 -4
  73. data/spec/data/wire_test_project.json +143 -0
  74. data/spec/helpers/crypto_helper.rb +9 -0
  75. data/spec/helpers/project_helper.rb +2 -0
  76. data/spec/integration/command_projects_spec.rb +4 -2
  77. data/spec/integration/full_project_spec.rb +51 -18
  78. data/spec/integration/partial_md_export_import_spec.rb +1 -1
  79. data/spec/spec_helper.rb +2 -1
  80. data/spec/unit/models/attribute_column_spec.rb +7 -7
  81. data/spec/unit/models/domain_spec.rb +2 -2
  82. data/spec/unit/models/from_wire_spec.rb +119 -0
  83. data/spec/unit/models/metadata_spec.rb +4 -2
  84. data/spec/unit/models/project_blueprint_spec.rb +32 -16
  85. data/spec/unit/models/project_role_spec.rb +6 -4
  86. data/spec/unit/models/project_spec.rb +26 -3
  87. data/spec/unit/models/schema_builder_spec.rb +5 -6
  88. data/spec/unit/models/to_manifest_spec.rb +24 -0
  89. data/spec/unit/models/to_wire_spec.rb +63 -0
  90. metadata +53 -29
  91. data/lib/gooddata/models/attributes/anchor.rb +0 -37
  92. data/lib/gooddata/models/attributes/attributes.rb +0 -8
  93. data/lib/gooddata/models/attributes/date_attribute.rb +0 -25
  94. data/lib/gooddata/models/attributes/time_attribute.rb +0 -24
  95. data/lib/gooddata/models/columns/attribute.rb +0 -71
  96. data/lib/gooddata/models/columns/columns.rb +0 -8
  97. data/lib/gooddata/models/columns/date_column.rb +0 -63
  98. data/lib/gooddata/models/columns/fact_model.rb +0 -54
  99. data/lib/gooddata/models/columns/label.rb +0 -55
  100. data/lib/gooddata/models/columns/reference.rb +0 -57
  101. data/lib/gooddata/models/facts/facts.rb +0 -8
  102. data/lib/gooddata/models/facts/time_fact.rb +0 -20
  103. data/lib/gooddata/models/folders/attribute_folder.rb +0 -20
  104. data/lib/gooddata/models/folders/fact_folder.rb +0 -20
  105. data/lib/gooddata/models/folders/folders.rb +0 -8
  106. data/lib/gooddata/models/metadata/column.rb +0 -61
  107. data/lib/gooddata/models/metadata/data_set.rb +0 -32
  108. data/lib/gooddata/models/metadata/date_dimension.rb +0 -26
  109. data/lib/gooddata/models/metadata/schema.rb +0 -227
  110. data/lib/gooddata/models/references/date_reference.rb +0 -44
  111. data/lib/gooddata/models/references/references.rb +0 -8
  112. data/lib/gooddata/models/references/time_reference.rb +0 -13
  113. data/spec/helpers/schema_helper.rb +0 -16
  114. data/spec/unit/models/anchor_spec.rb +0 -32
  115. data/spec/unit/models/tools_spec.rb +0 -95
  116. data/test/test_upload.rb +0 -79
@@ -5,6 +5,11 @@ module GoodData
5
5
  class ProjectBlueprint
6
6
  attr_accessor :data
7
7
 
8
+ # Instantiates a project blueprint either from a file or from a string containing
9
+ # json. Also eats Hash for convenience.
10
+ #
11
+ # @param spec [String | Hash] value of an label you are looking for
12
+ # @return [GoodData::Model::ProjectBlueprint]
8
13
  def self.from_json(spec)
9
14
  if spec.is_a?(String)
10
15
  if File.file?(spec)
@@ -17,6 +22,131 @@ module GoodData
17
22
  end
18
23
  end
19
24
 
25
+ # Removes dataset from blueprint. Dataset can be given as either a name
26
+ # or a DatasetBlueprint or a Hash representation.
27
+ #
28
+ # @param project [Hash] Project blueprint
29
+ # @param dataset_name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset to be removed
30
+ # @return [Hash] project with removed dataset
31
+ def self.remove_dataset(project, dataset_name)
32
+ dataset = dataset_name.is_a?(String) ? find_dataset(project, dataset_name) : dataset_name
33
+ index = project[:datasets].index(dataset)
34
+ dupped_project = project.deep_dup
35
+ dupped_project[:datasets].delete_at(index)
36
+ dupped_project
37
+ end
38
+
39
+ # Removes dataset from blueprint. Dataset can be given as either a name
40
+ # or a DatasetBlueprint or a Hash representation. This version mutates
41
+ # the dataset in place
42
+ #
43
+ # @param project [Hash] Project blueprint
44
+ # @param dataset_name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset to be removed
45
+ # @return [Hash] project with removed dataset
46
+ def self.remove_dataset!(project, dataset_name)
47
+ dataset = dataset_name.is_a?(String) ? find_dataset(project, dataset_name) : dataset_name
48
+ index = project[:datasets].index(dataset)
49
+ project[:datasets].delete_at(index)
50
+ project
51
+ end
52
+
53
+ # Returns datasets of blueprint. Those can be optionally including
54
+ # date dimensions
55
+ #
56
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
57
+ # @param options [Hash] options
58
+ # @return [Array<Hash>]
59
+ def self.datasets(project, options = {})
60
+ include_date_dimensions = options[:include_date_dimensions] || options[:dd]
61
+ ds = (project.to_hash[:datasets] || [])
62
+ if include_date_dimensions
63
+ ds + date_dimensions(project)
64
+ else
65
+ ds
66
+ end
67
+ end
68
+
69
+ # Returns true if a dataset contains a particular dataset false otherwise
70
+ #
71
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
72
+ # @param name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset
73
+ # @return [Boolean]
74
+ def self.dataset?(project, name)
75
+ find_dataset(project, name)
76
+ true
77
+ rescue
78
+ false
79
+ end
80
+
81
+ # Returns dataset specified. It can check even for a date dimension
82
+ #
83
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
84
+ # @param name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset
85
+ # @param options [Hash] options
86
+ # @return [GoodData::Model::DatasetBlueprint]
87
+ def self.find_dataset(project, name, options = {})
88
+ include_date_dimensions = options[:include_date_dimensions] || options[:dd]
89
+ return name.to_hash if DatasetBlueprint.dataset_blueprint?(name)
90
+ all_datasets = if include_date_dimensions
91
+ datasets(project) + date_dimensions(project)
92
+ else
93
+ datasets(project)
94
+ end
95
+ ds = all_datasets.find { |d| d[:name] == name }
96
+ fail "Dataset #{name} could not be found" if ds.nil?
97
+ ds
98
+ end
99
+
100
+ # Returns list of date dimensions
101
+ #
102
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
103
+ # @return [Array<Hash>]
104
+ def self.date_dimensions(project)
105
+ project.to_hash[:date_dimensions] || []
106
+ end
107
+
108
+ # Returns true if a date dimension of a given name exists in a bleuprint
109
+ #
110
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
111
+ # @param name [string] Date dimension
112
+ # @return [Boolean]
113
+ def self.date_dimension?(project, name)
114
+ find_date_dimension(project, name)
115
+ true
116
+ rescue
117
+ false
118
+ end
119
+
120
+ # Finds a date dimension of a given name in a bleuprint. If a dataset is
121
+ # not found it throws an exeception
122
+ #
123
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
124
+ # @param name [string] Date dimension
125
+ # @return [Hash]
126
+ def self.find_date_dimension(project, name)
127
+ ds = date_dimensions(project).find { |d| d[:name] == name }
128
+ fail "Date dimension #{name} could not be found" if ds.nil?
129
+ ds
130
+ end
131
+
132
+ # Returns fields from all datasets
133
+ #
134
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
135
+ # @return [Array<Hash>]
136
+ def self.fields(project)
137
+ datasets(project).mapcat { |d| DatasetBlueprint.fields(d) }
138
+ end
139
+
140
+ # Returns a dataset of a given name. If a dataset is not found it throws an exeception
141
+ #
142
+ # @param project [GoodData::Model::ProjectBlueprint | Hash] Project blueprint
143
+ # @param project [String] Dataset title
144
+ # @return [Array<Hash>]
145
+ def find_dataset_by_title(project, title)
146
+ ds = datasets(project).find { |d| Model.title(d) == title }
147
+ fail "Dataset #{title} could not be found" if ds.nil?
148
+ end
149
+
20
150
  def change(&block)
21
151
  builder = ProjectBuilder.create_from_data(self)
22
152
  block.call(builder)
@@ -24,9 +154,13 @@ module GoodData
24
154
  self
25
155
  end
26
156
 
27
- def datasets
28
- sets = data[:datasets] || []
29
- sets.map { |d| DatasetBlueprint.new(d) }
157
+ # Returns datasets of blueprint. Those can be optionally including
158
+ # date dimensions
159
+ #
160
+ # @param options [Hash] options
161
+ # @return [Array<GoodData::Model::DatasetBlueprint>]
162
+ def datasets(options = {})
163
+ ProjectBlueprint.datasets(to_hash, options).map { |d| DatasetBlueprint.new(d) }
30
164
  end
31
165
 
32
166
  def add_dataset(a_dataset, index = nil)
@@ -37,10 +171,22 @@ module GoodData
37
171
  end
38
172
  end
39
173
 
174
+ # Removes dataset from blueprint. Dataset can be given as either a name
175
+ # or a DatasetBlueprint or a Hash representation.
176
+ #
177
+ # @param dataset_name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset to be removed
178
+ # @return [Hash] project with removed dataset
40
179
  def remove_dataset(dataset_name)
41
- dataset = dataset_name.is_a?(String) ? find_dataset(dataset_name) : dataset_name
42
- index = data[:datasets].index(dataset)
43
- data[:datasets].delete_at(index)
180
+ ProjectBlueprint.remove_dataset(to_hash, dataset_name)
181
+ end
182
+
183
+ # Removes dataset from blueprint. Dataset can be given as either a name
184
+ # or a DatasetBlueprint or a Hash representation.
185
+ #
186
+ # @param dataset_name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset to be removed
187
+ # @return [Hash] project with removed dataset
188
+ def remove_dataset!(dataset_name)
189
+ ProjectBlueprint.remove_dataset!(to_hash, dataset_name)
44
190
  end
45
191
 
46
192
  # Is this a project blueprint?
@@ -50,18 +196,36 @@ module GoodData
50
196
  true
51
197
  end
52
198
 
199
+ # Returns list of date dimensions
200
+ #
201
+ # @return [Array<Hash>]
53
202
  def date_dimensions
54
- data[:date_dimensions]
203
+ ProjectBlueprint.date_dimensions(to_hash)
55
204
  end
56
205
 
206
+ # Returns true if a dataset contains a particular dataset false otherwise
207
+ #
208
+ # @param name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset
209
+ # @return [Boolean]
57
210
  def dataset?(name)
58
- found = data[:datasets].find { |d| d[:name] == name }
59
- found != nil
211
+ ProjectBlueprint.dataset?(to_hash, name)
60
212
  end
61
213
 
62
- def find_dataset(name)
63
- ds = data[:datasets].find { |d| d[:name] == name }
64
- fail "Dataset #{name} could not be found" if ds.nil?
214
+ # Returns dataset specified. It can check even for a date dimension
215
+ #
216
+ # @param name [GoodData::Model::DatasetBlueprint | String | Hash] Dataset
217
+ # @param options [Hash] options
218
+ # @return [GoodData::Model::DatasetBlueprint]
219
+ def find_dataset(name, options = {})
220
+ DatasetBlueprint.new(ProjectBlueprint.find_dataset(to_hash, name, options))
221
+ end
222
+
223
+ # Returns a dataset of a given name. If a dataset is not found it throws an exeception
224
+ #
225
+ # @param project [String] Dataset title
226
+ # @return [Array<Hash>]
227
+ def find_dataset_by_title(title)
228
+ ds = ProjectBlueprint.find_dataset_by_title(to_hash, title)
65
229
  DatasetBlueprint.new(ds)
66
230
  end
67
231
 
@@ -87,12 +251,12 @@ module GoodData
87
251
  if datasets.count == 1
88
252
  []
89
253
  else
90
- x = datasets.reduce([]) { |a, e| e.anchor? ? a << [e.name, e.anchor[:name]] : a }
254
+ x = datasets.reduce([]) { |a, e| e.anchor? ? a << [e.name] : a } + date_dimensions.map { |y| [y[:name]] }
91
255
  refs = datasets.reduce([]) do |a, e|
92
256
  a.concat(e.references)
93
257
  end
94
258
  refs.reduce([]) do |a, e|
95
- x.include?([e[:dataset], e[:reference]]) ? a : a.concat([e])
259
+ x.include?([e[:dataset]]) ? a : a.concat([e])
96
260
  end
97
261
  end
98
262
  end
@@ -113,29 +277,59 @@ module GoodData
113
277
  validate.empty?
114
278
  end
115
279
 
280
+ # Returns list of datasets which are referenced by given dataset. This can be
281
+ # optionally switched to return even date dimensions
282
+ #
283
+ # @param project [GoodData::Model::DatasetBlueprint | Hash | String] Dataset blueprint
284
+ # @return [Array<Hash>]
116
285
  def referenced_by(dataset)
117
- dataset = find_dataset(dataset) if dataset.is_a?(String)
118
- dataset.references.map do |ds|
119
- find_dataset(ds[:dataset])
286
+ find_dataset(dataset).references.map do |ref|
287
+ find_dataset(ref[:dataset], include_date_dimensions: true)
120
288
  end
121
289
  end
122
290
 
291
+ # Returns list of attributes from all the datasets in a blueprint
292
+ #
293
+ # @return [Array<Hash>]
123
294
  def attributes
124
295
  datasets.reduce([]) { |a, e| a.concat(e.attributes) }
125
296
  end
126
297
 
298
+ # Returns list of attributes and anchors from all the datasets in a blueprint
299
+ #
300
+ # @return [Array<Hash>]
127
301
  def attributes_and_anchors
128
- datasets.reduce([]) { |a, e| a.concat(e.attributes_and_anchors) }
302
+ datasets.mapcat(&:attributes_and_anchors)
129
303
  end
130
304
 
305
+ # Returns list of labels from all the datasets in a blueprint
306
+ #
307
+ # @return [Array<Hash>]
131
308
  def labels
132
- datasets.reduce([]) { |a, e| a.concat(e.labels) }
309
+ datasets.mapcat(&:labels)
133
310
  end
134
311
 
312
+ # Returns list of facts from all the datasets in a blueprint
313
+ #
314
+ # @return [Array<Hash>]
135
315
  def facts
136
- datasets.reduce([]) { |a, e| a.concat(e.facts) }
316
+ datasets.mapcat(&:facts)
317
+ end
318
+
319
+ # Returns list of fields from all the datasets in a blueprint
320
+ #
321
+ # @return [Array<Hash>]
322
+ def fields
323
+ ProjectBlueprint.fields(to_hash)
137
324
  end
138
325
 
326
+ # Returns list of attributes that can break facts in a given dataset.
327
+ # This basically means that it is giving you all attributes from the
328
+ # datasets that are references by given dataset. Currently does not
329
+ # work transitively
330
+ #
331
+ # @param project [GoodData::Model::DatasetBlueprint | Hash | String] Dataset blueprint
332
+ # @return [Array<Hash>]
139
333
  def can_break(dataset)
140
334
  dataset = find_dataset(dataset) if dataset.is_a?(String)
141
335
  referenced_by(dataset).reduce([]) do |a, e|
@@ -146,13 +340,68 @@ module GoodData
146
340
  end
147
341
  end
148
342
 
343
+ # Experimental but a basis for automatic check of health of a project
344
+ #
345
+ # @param project [GoodData::Model::DatasetBlueprint | Hash | String] Dataset blueprint
346
+ # @return [Array<Hash>]
347
+ def lint(full = false)
348
+ errors = []
349
+ find_star_centers.each do |dataset|
350
+ if dataset.anchor?
351
+ errors << {
352
+ type: :anchor_on_fact_dataset,
353
+ dataset_name: dataset.name,
354
+ anchor_name: dataset.anchor[:name]
355
+ }
356
+ end
357
+ end
358
+
359
+ date_facts = datasets.mapcat { |d| d.date_facts }
360
+ date_facts.each do |date_fact|
361
+ errors << {
362
+ type: :date_fact,
363
+ date_fact: date_fact[:name]
364
+ }
365
+ end
366
+
367
+ unique_titles = fields.map { |f| Model.title(f) }.uniq
368
+ (fields.map { |f| Model.title(f) } - unique_titles).each do |duplicate_title|
369
+ errors << {
370
+ type: :duplicate_title,
371
+ title: duplicate_title
372
+ }
373
+ end
374
+
375
+ datasets.select(&:wide?).each do |wide_dataset|
376
+ errors << {
377
+ type: :wide_dataset,
378
+ dataset: wide_dataset.name
379
+ }
380
+ end
381
+
382
+ if full
383
+ # GoodData::Attributes.all(:full => true).select { |attr| attr.used_by}
384
+ end
385
+ errors
386
+ end
387
+
388
+ # Return list of datasets that are centers of the stars in datamart.
389
+ # This means these datasets are not referenced by anybody else
390
+ # In a good blueprint design these should be fact tables
391
+ #
392
+ # @return [Array<Hash>]
149
393
  def find_star_centers
150
- referenced = datasets.map { |d| referenced_by(d) }
394
+ referenced = datasets.mapcat { |d| referenced_by(d) }
151
395
  referenced.flatten!
152
396
  res = datasets.map(&:to_hash) - referenced.map(&:to_hash)
153
397
  res.map { |d| DatasetBlueprint.new(d) }
154
398
  end
155
399
 
400
+ # Returns some reports that might get you started. They are just simple
401
+ # reports. Currently it is implemented by getting facts from star centers
402
+ # and randomly picking attributes form referenced datasets.
403
+ #
404
+ # @return [Array<Hash>]
156
405
  def suggest_reports(options = {})
157
406
  strategy = options[:strategy] || :stupid
158
407
  case strategy
@@ -181,18 +430,32 @@ module GoodData
181
430
  end
182
431
  end
183
432
 
433
+ # Returns some metrics that might get you started. They are just simple
434
+ # reports. Currently it is implemented by getting facts from star centers
435
+ # and randomly picking attributes form referenced datasets.
436
+ #
437
+ # @return [Array<Hash>]
184
438
  def suggest_metrics
185
439
  stars = find_star_centers
186
440
  metrics = stars.map { |s| s.suggest_metrics }
187
441
  stars.zip(metrics)
188
442
  end
189
443
 
444
+ # Merging two blueprints. The self blueprint is changed in place
445
+ #
446
+ # @param a_blueprint [GoodData::Model::DatasetBlueprint] Dataset blueprint to be merged
447
+ # @return [GoodData::Model::ProjectBlueprint]
190
448
  def merge!(a_blueprint)
191
449
  temp_blueprint = merge(a_blueprint)
192
450
  @data = temp_blueprint.data
193
451
  self
194
452
  end
195
453
 
454
+ # Merging two blueprints. A new blueprint is created. The self one
455
+ # is nto mutated
456
+ #
457
+ # @param a_blueprint [GoodData::Model::DatasetBlueprint] Dataset blueprint to be merged
458
+ # @return [GoodData::Model::ProjectBlueprint]
196
459
  def merge(a_blueprint)
197
460
  temp_blueprint = dup
198
461
  a_blueprint.datasets.each do |dataset|
@@ -209,34 +472,51 @@ module GoodData
209
472
  temp_blueprint
210
473
  end
211
474
 
475
+ # Duplicated blueprint
476
+ #
477
+ # @param a_blueprint [GoodData::Model::DatasetBlueprint] Dataset blueprint to be merged
478
+ # @return [GoodData::Model::DatasetBlueprint]
212
479
  def dup
213
480
  ProjectBlueprint.new(data.deep_dup)
214
481
  end
215
482
 
483
+ # Returns title of a dataset. If not present it is generated from the name
484
+ #
485
+ # @return [String] a title
216
486
  def title
217
- data[:title]
218
- end
219
-
220
- def to_wire_model
221
- {
222
- 'diffRequest' => {
223
- 'targetModel' => {
224
- 'projectModel' => {
225
- 'datasets' => datasets.map { |d| d.to_wire_model },
226
- 'dateDimensions' => date_dimensions.map do |d|
227
- {
228
- 'dateDimension' => {
229
- 'name' => d[:name],
230
- 'title' => d[:title] || d[:name].humanize
231
- }
232
- }
233
- end
234
- }
235
- }
236
- }
237
- }
487
+ Model.title(to_hash)
488
+ end
489
+
490
+ # Returns Wire representation. This is used by our API to generate and
491
+ # change projects
492
+ #
493
+ # @return [Hash] a title
494
+ def to_wire
495
+ ToWire.to_wire(data)
238
496
  end
239
497
 
498
+ # Returns SLI manifest representation. This is used by our API to allow
499
+ # loading data
500
+ #
501
+ # @return [Array<Hash>] a title
502
+ def to_manifest
503
+ ToManifest.to_manifest(to_hash)
504
+ end
505
+
506
+ # Returns SLI manifest for one dataset. This is used by our API to allow
507
+ # loading data. The method is on project blueprint because you need
508
+ # acces to whole project to be able to generate references
509
+ #
510
+ # @param dataset [GoodData::Model::DatasetBlueprint | Hash | String] Dataset
511
+ # @param mode [String] Method of loading. FULL or INCREMENTAL
512
+ # @return [Array<Hash>] a title
513
+ def dataset_to_manifest(dataset, mode = 'FULL')
514
+ ToManifest.dataset_to_manifest(self, dataset, mode)
515
+ end
516
+
517
+ # Returns hash representation of blueprint
518
+ #
519
+ # @return [Hash] a title
240
520
  def to_hash
241
521
  @data
242
522
  end