gooddata 0.6.4 → 0.6.5

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.
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
@@ -46,7 +46,7 @@ module GoodData
46
46
  # schema = Schema.load(schema) unless schema.respond_to?(:to_maql_create)
47
47
  # project = GoodData.project unless project
48
48
  uri = "/gdc/projects/#{GoodData.project.pid}/model/diff"
49
- result = GoodData.post(uri, bp.to_wire_model)
49
+ result = GoodData.post(uri, bp.to_wire)
50
50
  link = result['asyncTask']['link']['poll']
51
51
  response = GoodData.get(link, :process => false)
52
52
  # pp response
@@ -75,9 +75,10 @@ module GoodData
75
75
 
76
76
  end
77
77
 
78
- bp.datasets.each do |ds|
79
- schema = ds.to_schema
80
- GoodData::ProjectMetadata["manifest_#{schema.name}"] = schema.to_manifest.to_json
78
+ bp.datasets.zip(GoodData::Model::ToManifest.to_manifest(bp.to_hash)).each do |ds|
79
+ dataset = ds[0]
80
+ manifest = ds[1]
81
+ GoodData::ProjectMetadata["manifest_#{dataset.name}"] = manifest.to_json
81
82
  end
82
83
  end
83
84
 
@@ -2,78 +2,39 @@
2
2
 
3
3
  require_relative 'profile'
4
4
 
5
+ require_relative '../mixins/mixins'
6
+
5
7
  module GoodData
6
8
  class ProjectRole
7
- def initialize(json)
8
- @json = json
9
- end
9
+ attr_accessor :json
10
10
 
11
- # Gets Project Role Identifier
12
- #
13
- # @return [string] Project Role
14
- def identifier
15
- @json['projectRole']['meta']['identifier']
16
- end
11
+ include GoodData::Mixin::RestGetters
17
12
 
18
- # Gets Project Role Author
19
- #
20
- # @return [GoodData::Profile] Project Role author
21
- def author
22
- url = @json['projectRole']['meta']['author']
23
- tmp = GoodData.get url
24
- GoodData::Profile.new(tmp)
13
+ class << self
14
+ include GoodData::Mixin::RestResource
25
15
  end
26
16
 
27
- # Gets Project Role Contributor
28
- #
29
- # @return [GoodData::Profile] Project Role Contributor
30
- def contributor
31
- url = @json['projectRole']['meta']['contributor']
32
- tmp = GoodData.get url
33
- GoodData::Profile.new(tmp)
34
- end
17
+ ProjectRole.root_key :projectRole
35
18
 
36
- # Gets DateTime time when created
37
- #
38
- # @return [DateTime] Date time of creation
39
- def created
40
- DateTime.parse(@json['projectRole']['meta']['created'])
41
- end
19
+ include GoodData::Mixin::RootKeyGetter
20
+ include GoodData::Mixin::Author
21
+ include GoodData::Mixin::Contributor
22
+ include GoodData::Mixin::Timestamps
42
23
 
43
- # Gets Project Role Permissions
44
- #
45
- # @return [string] Project Role
46
- def permissions
47
- @json['projectRole']['permissions']
48
- end
49
-
50
- # Gets Project Role Title
51
- #
52
- # @return [string] Project Role Title
53
- def title
54
- @json['projectRole']['meta']['title']
24
+ def initialize(json)
25
+ @json = json
55
26
  end
56
27
 
57
- # Gets Project Role Summary
58
- #
59
- # @return [string] Project Role Summary
60
- def summary
61
- @json['projectRole']['meta']['summary']
62
- end
28
+ ProjectRole.data_property_reader :permissions
63
29
 
64
- # Gets DateTime time when updated
65
- #
66
- # @return [DateTime] Date time of last update
67
- def updated
68
- DateTime.parse(@json['projectRole']['meta']['updated'])
69
- end
30
+ ProjectRole.metadata_property_reader :identifier, :title, :summary
70
31
 
71
32
  # Gets Users with this Role
72
33
  #
73
34
  # @return [Array<GoodData::Profile>] List of users
74
35
  def users
75
36
  res = []
76
- url = @json['projectRole']['links']['roleUsers']
37
+ url = data['links']['roleUsers']
77
38
  tmp = GoodData.get url
78
39
  tmp['associatedUsers']['users'].each do |user_url|
79
40
  user = GoodData.get user_url
@@ -88,5 +49,9 @@ module GoodData
88
49
  def uri
89
50
  @json['projectRole']['links']['roleUsers'].split('/')[0...-1].join('/')
90
51
  end
52
+
53
+ def ==(other)
54
+ uri == other.uri
55
+ end
91
56
  end
92
57
  end
@@ -6,147 +6,332 @@ module GoodData
6
6
  module Model
7
7
  class DatasetBlueprint
8
8
  attr_accessor :data
9
+ # Checks if a dataset has an anchor.
10
+ #
11
+ # @param dataset [Hash] Dataset blueprint
12
+ # @return [Boolean] returns true if dataset has an anchor
13
+ def self.anchor?(dataset)
14
+ columns(dataset).any? { |c| c[:type].to_s == 'anchor' }
15
+ end
9
16
 
10
- def change(&block)
11
- builder = SchemaBuilder.create_from_data(self)
12
- block.call(builder)
13
- @data = builder.to_hash
14
- self
17
+ # Returns anchor of a dataset
18
+ #
19
+ # @param dataset [Hash] Dataset blueprint
20
+ # @return [Hash] returns the anchor or nil
21
+ def self.anchor(dataset)
22
+ find_column_by_type(dataset, :anchor, :first)
15
23
  end
16
24
 
17
- def initialize(init_data)
18
- @data = init_data
25
+ # Returns attributes of a dataset
26
+ #
27
+ # @param dataset [Hash] Dataset blueprint
28
+ # @return [Array<Hash>] returns the attribute or an empty array
29
+ def self.attributes(dataset)
30
+ find_column_by_type(dataset, :attribute, :all)
19
31
  end
20
32
 
21
- def upload(source, options = {})
22
- project = options[:project] || GoodData.project
23
- fail 'You have to specify a project into which you want to load.' if project.nil?
24
- mode = options[:load] || 'FULL'
25
- project.upload(source, to_schema, mode)
33
+ # Returns all labels that is referenced by a label
34
+ #
35
+ # @param dataset [Hash] Dataset blueprint
36
+ # @return [Array<Hash>] returns the labels or an empty array
37
+ def self.attribute_for_label(dataset, label)
38
+ find_column_by_type(dataset, [:attribute, :anchor], :all).find { |a| label[:reference] == a[:name] }
26
39
  end
27
40
 
28
- def merge!(a_blueprint)
29
- new_blueprint = GoodData::Model.merge_dataset_columns(self, a_blueprint)
30
- @data = new_blueprint
31
- self
41
+ # Returns all the fields of a dataset. This means facts, attributes, references
42
+ #
43
+ # @param ds [Hash] Dataset blueprint
44
+ # @return [Boolean]
45
+ def self.columns(ds)
46
+ ds[:columns] || []
32
47
  end
48
+ singleton_class.send(:alias_method, :fields, :columns)
33
49
 
34
- def name
35
- data[:name]
50
+ # Tells you if the object is a dataset. It consumes both Hash represenation
51
+ # or the GoodData::Model::DatasetBlueprint
52
+ #
53
+ # @param ds [Object] Value to be tested
54
+ # @return [Boolean]
55
+ def self.dataset_blueprint?(ds)
56
+ if ds.is_a?(DatasetBlueprint)
57
+ true
58
+ elsif ds.respond_to?(:[]) && ds.is_a?(Hash) && ds[:type].to_sym == :dataset
59
+ true
60
+ else
61
+ false
62
+ end
36
63
  end
37
64
 
38
- def title
39
- data[:title] || name.titleize
65
+ # Returns date facts of a dataset
66
+ #
67
+ # @param dataset [Hash] Dataset blueprint
68
+ # @return [Array<Hash>] returns the attribute or an empty array
69
+ def self.date_facts(dataset)
70
+ find_column_by_type(dataset, :date_fact, :all)
40
71
  end
41
72
 
42
- def to_hash
43
- data
73
+ # Returns label that is marked as default for a particular attribtue.
74
+ # This does not necessarily need to be the first one. This is a default label
75
+ # in terms of what is displayed on the UI
76
+ #
77
+ # @param dataset [Hash] Dataset blueprint
78
+ # @return [Array<Hash>] returns the labels or an empty array
79
+ def self.default_label_for_attribute(dataset, attribute)
80
+ default_label = labels_for_attribute(dataset, attribute).find { |l| l[:default_label] == true }
81
+ default_label || attribute
44
82
  end
45
83
 
46
- def columns
47
- data[:columns]
84
+ # Returns facts of a dataset
85
+ #
86
+ # @param dataset [Hash] Dataset blueprint
87
+ # @return [Array<Hash>] returns the attribute or an empty array
88
+ def self.facts(dataset)
89
+ find_column_by_type(dataset, [:fact, :date_fact], :all)
48
90
  end
49
91
 
50
- def anchor?
51
- columns.any? { |c| c[:type].to_s == 'anchor' }
92
+ # Finds a specific column given a name
93
+ #
94
+ # @param dataset [Hash] Dataset blueprint
95
+ # @param name [String] Name of a field
96
+ # @param all [Symbol] if :all is passed all mathching objects are returned
97
+ # Otherwise only the first one is
98
+ # @return [Array<Hash>] matching fields
99
+ def self.find_column_by_name(dataset, name, all = nil)
100
+ if all == :all
101
+ columns(dataset).select { |c| c[:name].to_s == name }
102
+ else
103
+ columns(dataset).find { |c| c[:name].to_s == name }
104
+ end
105
+ end
106
+
107
+ # Returns all the fields of a specified type. You can specify more types
108
+ # as an array if you need more than one type.
109
+ #
110
+ # @param dataset [Hash] Dataset blueprint
111
+ # @param type [String | Symbol | Array[Symmbol] | Array[String]] Type or types you would like to get
112
+ # @param all [Symbol] if :all is passed
113
+ # as third parameter it return all object otherwise it returns the first one
114
+ # @return [Array<Hash>] matching fields
115
+ def self.find_column_by_type(dataset, type, all = nil)
116
+ types = if type.is_a?(Enumerable)
117
+ type
118
+ else
119
+ [type]
120
+ end
121
+ if all == :all
122
+ columns(dataset).select { |c| types.any? { |t| t.to_s == c[:type].to_s } }
123
+ else
124
+ columns(dataset).find { |c| types.any? { |t| t.to_s == c[:type].to_s } }
125
+ end
52
126
  end
53
127
 
128
+ # Returns labels facts of a dataset
129
+ #
130
+ # @param dataset [Hash] Dataset blueprint
131
+ # @return [Array<Hash>] returns the label or an empty array
132
+ def self.labels(dataset)
133
+ find_column_by_type(dataset, :label, :all)
134
+ end
135
+
136
+ # Returns labels for a particular attribute
137
+ #
138
+ # @param dataset [Hash] Dataset blueprint
139
+ # @param attribute [Hash] Attribute
140
+ # @return [Array<Hash>] returns the labels or an empty array
141
+ def self.labels_for_attribute(dataset, attribute)
142
+ labels(dataset).select { |l| l[:reference] == attribute[:name] }
143
+ end
144
+
145
+ # Returns references of a dataset
146
+ #
147
+ # @param dataset [Hash] Dataset blueprint
148
+ # @return [Array<Hash>] returns the references or an empty array
149
+ def self.references(dataset)
150
+ find_column_by_type(dataset, [:reference, :date], :all)
151
+ end
152
+
153
+ # Returns anchor of a dataset
154
+ #
155
+ # @return [Hash] returns the anchor or nil
54
156
  def anchor
55
157
  find_column_by_type(:anchor, :first)
56
158
  end
57
159
 
58
- def references
59
- find_column_by_type(:reference)
160
+ # Checks if a dataset has an anchor.
161
+ #
162
+ # @return [Boolean] returns true if dataset has an anchor
163
+ def anchor?
164
+ columns.any? { |c| c[:type].to_s == 'anchor' }
60
165
  end
61
166
 
167
+ # Returns attributes of a dataset
168
+ #
169
+ # @return [Array<Hash>] returns the attribute or an empty array
62
170
  def attributes
63
- find_column_by_type(:attribute)
171
+ DatasetBlueprint.attributes(to_hash)
64
172
  end
65
173
 
66
- def facts
67
- find_column_by_type(:fact)
174
+ def attributes_and_anchors
175
+ anchor? ? attributes + [anchor] : attributes
68
176
  end
69
177
 
70
- def labels
71
- find_column_by_type(:label)
178
+ # Changes the dataset through a builder. You provide a block with an istance of
179
+ # GoodData::Model::SchemaBuilder and you
180
+ #
181
+ # @param dataset [Hash] Dataset blueprint
182
+ # @return [Array<Hash>] returns the labels or an empty array
183
+ def change(&block)
184
+ builder = SchemaBuilder.create_from_data(self)
185
+ block.call(builder)
186
+ @data = builder.to_hash
187
+ self
72
188
  end
73
189
 
74
- def attributes_and_anchors
75
- anchor? ? attributes + [anchor] : attributes
190
+ # Returns all the fields of a dataset. This means facts, attributes, references
191
+ #
192
+ # @return [Boolean]
193
+ def columns
194
+ DatasetBlueprint.columns(to_hash)
76
195
  end
196
+ alias_method :fields, :columns
77
197
 
78
- def find_column_by_type(type, all = :all)
79
- type = type.to_s
80
- if all == :all
81
- columns.select { |c| c[:type].to_s == type }
82
- else
83
- columns.find { |c| c[:type].to_s == type }
84
- end
198
+ # Creates a metric which counts numnber of lines in dataset. Works for both
199
+ # datasets with or without anchor
200
+ #
201
+ # @return [Boolean]
202
+ def count
203
+ id = if anchor?
204
+ GoodData::Model.identifier_for(to_hash, anchor)
205
+ else
206
+ GoodData::Model.identifier_for(to_hash, type: :anchor_no_label)
207
+ end
208
+ # binding.pry
209
+ attribute = GoodData::Attribute[id]
210
+ attribute.create_metric.execute
85
211
  end
86
212
 
87
- def find_column_by_name(type, all = :all)
88
- type = type.to_s
89
- if all == :all
90
- columns.select { |c| c[:name].to_s == type }
91
- else
92
- columns.find { |c| c[:name].to_s == type }
93
- end
213
+ # Returns date facts of a dataset
214
+ #
215
+ # @return [Array<Hash>] returns the attribute or an empty array
216
+ def date_facts
217
+ DatasetBlueprint.date_facts(to_hash)
94
218
  end
95
219
 
96
- def suggest_metrics
97
- identifiers = facts.map { |f| identifier_for(f) }
98
- identifiers.zip(facts).map do |id, fact|
99
- Metric.xcreate(
100
- :title => fact[:name].titleize,
101
- :expression => "SELECT SUM(![#{id}])")
102
- end
220
+ # Duplicates the DatasetBlueprint. It is done as a deep duplicate
221
+ #
222
+ # @return [GoodData::Model::DatasetBlueprint] matching fields
223
+ def dup
224
+ DatasetBlueprint.new(data.deep_dup)
103
225
  end
104
226
 
105
- def to_schema
106
- Schema.new(to_hash)
227
+ # Compares two blueprints. This is done by comapring the hash represenatation.
228
+ # It has to be exacty identical including the order of the columns
229
+ #
230
+ # @param name [GoodData::Model::DatasetBlueprint] Name of a field
231
+ # @return [Boolean] matching fields
232
+ def eql?(other)
233
+ to_hash == other.to_hash
107
234
  end
108
235
 
109
- def to_manifest
110
- to_schema.to_manifest
236
+ # Returns facts of a dataset
237
+ #
238
+ # @return [Array<Hash>] returns the attribute or an empty array
239
+ def facts
240
+ DatasetBlueprint.facts(to_hash)
111
241
  end
112
242
 
113
- def pretty_print(printer)
114
- printer.text "Schema <#{object_id}>:\n"
115
- printer.text " Name: #{name}\n"
116
- printer.text " Columns: \n"
117
- printer.text columns.map do |c|
118
- " #{c[:name]}: #{c[:type]}"
119
- end.join("\n")
243
+ # Finds a specific column given a name
244
+ #
245
+ # @param name [String] Name of a field
246
+ # @param all [Symbol] if :all is passed all mathching objects are returned
247
+ # Otherwise only the first one is
248
+ # @return [Array<Hash>] matching fields
249
+ def find_column_by_name(type, all = :all)
250
+ DatasetBlueprint.find_column_by_name(to_hash, type, all)
120
251
  end
121
252
 
122
- def dup
123
- DatasetBlueprint.new(data.deep_dup)
253
+ # Returns all the fields of a specified type. You can specify more types
254
+ # as an array if you need more than one type.
255
+ #
256
+ # @param type [String | Symbol | Array[Symmbol] | Array[String]] Type or types you would like to get
257
+ # @param all [Symbol] if :all is passed
258
+ # as third parameter it return all object otherwise it returns the first one
259
+ # @return [Array<Hash>] matching fields
260
+ def find_column_by_type(type, all = nil)
261
+ DatasetBlueprint.find_column_by_type(to_hash, type, all)
124
262
  end
125
263
 
126
- def to_wire_model
127
- to_schema.to_wire_model
264
+ # Creates a DatasetBlueprint
265
+ #
266
+ # @param dataset [Hash] Dataset blueprint
267
+ # @return [DatasetBlueprint] returns the labels or an empty array
268
+ def initialize(init_data)
269
+ @data = init_data
128
270
  end
129
271
 
130
- def ==(other)
131
- to_hash == other.to_hash
272
+ # Returns labels facts of a dataset
273
+ #
274
+ # @param dataset [Hash] Dataset blueprint
275
+ # @return [Array<Hash>] returns the label or an empty array
276
+ def labels
277
+ DatasetBlueprint.labels(to_hash)
132
278
  end
133
279
 
134
- def eql?(other)
135
- to_hash == other.to_hash
280
+ # Merges two schemas together. This method changes the blueprint
281
+ # in place. If you would prefer the method that generates a new blueprint
282
+ # use merge method
283
+ #
284
+ # @param a_blueprint [GoodData::Model::DatasetBlueprint] Dataset blueprint to be merged
285
+ # @return [GoodData::Model::DatasetBlueprint] returns itself changed
286
+ def merge!(a_blueprint)
287
+ new_blueprint = GoodData::Model.merge_dataset_columns(self, a_blueprint)
288
+ @data = new_blueprint
289
+ self
290
+ end
291
+
292
+ # Returns name of the dataset
293
+ #
294
+ # @return [String]
295
+ def name
296
+ data[:name]
136
297
  end
137
298
 
138
- def identifier_for(column)
139
- column = find_column_by_name(column) if column.is_a?(String)
140
- case column[:type].to_sym
141
- when :attribute
142
- "attr.#{name}.#{column[:name]}"
143
- when :anchor
144
- "attr.#{name}.#{column[:name]}"
145
- when :fact
146
- "fact.#{name}.#{column[:name]}"
299
+ # Returns references of a dataset
300
+ #
301
+ # @return [Array<Hash>] returns the references or an empty array
302
+ def references
303
+ DatasetBlueprint.references(to_hash)
304
+ end
305
+
306
+ # Method for suggest a couple of metrics that might get you started
307
+ # Idea is that we will provide couple of strategies. Currently the metrics
308
+ # are created in the random way but they should work.
309
+ #
310
+ # @return [Array<GoodData::Metric>] matching fields
311
+ def suggest_metrics
312
+ identifiers = facts.map { |f| identifier_for(f) }
313
+ identifiers.zip(facts).map do |id, fact|
314
+ Metric.xcreate(
315
+ :title => fact[:name].titleize,
316
+ :expression => "SELECT SUM(![#{id}])")
147
317
  end
148
318
  end
149
319
 
320
+ # Returns title of the dataset. If it is not set up. It is generated for you
321
+ # based on the name which is titleized
322
+ #
323
+ # @return [String]
324
+ def title
325
+ data[:title] || name.titleize
326
+ end
327
+
328
+ # Returns hash representation which is much better suited for processing
329
+ #
330
+ # @return [Hash]
331
+ def to_hash
332
+ data
333
+ end
334
+
150
335
  # Validate the blueprint return array of errors that are found.
151
336
  #
152
337
  # @return [Array] array of errors
@@ -170,6 +355,24 @@ module GoodData
170
355
  find_column_by_name(label[:reference]).empty?
171
356
  end
172
357
  end
358
+
359
+ # Helper methods to decide wheather the dataset is considered wide.
360
+ # Currently the wider datasets have both performance and usability
361
+ # penalty
362
+ #
363
+ # @return [Boolean] matching fields
364
+ def wide?
365
+ fields.count > 32
366
+ end
367
+
368
+ # Compares two blueprints. This is done by comapring the hash represenatation.
369
+ # It has to be exacty identical including the order of the columns
370
+ #
371
+ # @param name [GoodData::Model::DatasetBlueprint] Name of a field
372
+ # @return [Boolean] matching fields
373
+ def ==(other)
374
+ to_hash == other.to_hash
375
+ end
173
376
  end
174
377
  end
175
378
  end