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
@@ -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