gooddata 0.6.18 → 0.6.19

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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +8 -19
  4. data/Guardfile +5 -0
  5. data/README.md +1 -3
  6. data/bin/gooddata +1 -1
  7. data/gooddata.gemspec +6 -4
  8. data/lib/gooddata.rb +1 -1
  9. data/lib/gooddata/bricks/middleware/aws_middleware.rb +24 -0
  10. data/lib/gooddata/cli/commands/console_cmd.rb +1 -1
  11. data/lib/gooddata/cli/commands/project_cmd.rb +29 -9
  12. data/lib/gooddata/cli/hooks.rb +9 -3
  13. data/lib/gooddata/commands/datawarehouse.rb +1 -7
  14. data/lib/gooddata/commands/project.rb +4 -3
  15. data/lib/gooddata/core/logging.rb +14 -2
  16. data/lib/gooddata/exceptions/execution_limit_exceeded.rb +9 -0
  17. data/lib/gooddata/exceptions/uncomputable_report.rb +8 -0
  18. data/lib/gooddata/exceptions/validation_error.rb +1 -1
  19. data/lib/gooddata/goodzilla/goodzilla.rb +5 -1
  20. data/lib/gooddata/helpers/data_helper.rb +40 -9
  21. data/lib/gooddata/mixins/md_finders.rb +35 -0
  22. data/lib/gooddata/models/blueprint/anchor_field.rb +46 -0
  23. data/lib/gooddata/models/blueprint/attribute_field.rb +25 -0
  24. data/lib/gooddata/models/blueprint/blueprint.rb +7 -0
  25. data/lib/gooddata/models/blueprint/blueprint_field.rb +66 -0
  26. data/lib/gooddata/models/{dashboard_builder.rb → blueprint/dashboard_builder.rb} +0 -0
  27. data/lib/gooddata/models/{schema_blueprint.rb → blueprint/dataset_blueprint.rb} +176 -117
  28. data/lib/gooddata/models/blueprint/date_dimension.rb +10 -0
  29. data/lib/gooddata/models/blueprint/fact_field.rb +16 -0
  30. data/lib/gooddata/models/blueprint/label_field.rb +39 -0
  31. data/lib/gooddata/models/{project_blueprint.rb → blueprint/project_blueprint.rb} +366 -168
  32. data/lib/gooddata/models/blueprint/project_builder.rb +79 -0
  33. data/lib/gooddata/models/blueprint/reference_field.rb +39 -0
  34. data/lib/gooddata/models/blueprint/schema_blueprint.rb +156 -0
  35. data/lib/gooddata/models/blueprint/schema_builder.rb +85 -0
  36. data/lib/gooddata/models/{to_manifest.rb → blueprint/to_manifest.rb} +25 -20
  37. data/lib/gooddata/models/{to_wire.rb → blueprint/to_wire.rb} +33 -52
  38. data/lib/gooddata/models/datawarehouse.rb +2 -2
  39. data/lib/gooddata/models/domain.rb +3 -2
  40. data/lib/gooddata/models/execution.rb +2 -2
  41. data/lib/gooddata/models/execution_detail.rb +7 -2
  42. data/lib/gooddata/models/from_wire.rb +60 -71
  43. data/lib/gooddata/models/from_wire_parse.rb +125 -125
  44. data/lib/gooddata/models/metadata.rb +14 -0
  45. data/lib/gooddata/models/metadata/dashboard.rb +2 -2
  46. data/lib/gooddata/models/metadata/label.rb +1 -1
  47. data/lib/gooddata/models/metadata/report.rb +6 -5
  48. data/lib/gooddata/models/metadata/report_definition.rb +44 -59
  49. data/lib/gooddata/models/model.rb +131 -43
  50. data/lib/gooddata/models/process.rb +13 -11
  51. data/lib/gooddata/models/profile.rb +12 -1
  52. data/lib/gooddata/models/project.rb +223 -19
  53. data/lib/gooddata/models/project_creator.rb +4 -15
  54. data/lib/gooddata/models/schedule.rb +1 -0
  55. data/lib/gooddata/models/user_filters/user_filter_builder.rb +2 -2
  56. data/lib/gooddata/rest/client.rb +18 -18
  57. data/lib/gooddata/rest/connection.rb +113 -94
  58. data/lib/gooddata/version.rb +1 -1
  59. data/lib/templates/project/model/model.rb.erb +15 -16
  60. data/spec/data/blueprints/additional_dataset_module.json +32 -0
  61. data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
  62. data/spec/data/blueprints/invalid_blueprint.json +103 -0
  63. data/spec/data/blueprints/m_n_model.json +104 -0
  64. data/spec/data/blueprints/model_module.json +25 -0
  65. data/spec/data/blueprints/test_blueprint.json +38 -0
  66. data/spec/data/blueprints/test_project_model_spec.json +106 -0
  67. data/spec/data/gd_gse_data_manifest.json +34 -34
  68. data/spec/data/manifests/test_blueprint.json +32 -0
  69. data/spec/data/{manifest_test_project.json → manifests/test_project.json} +9 -18
  70. data/spec/data/wire_models/test_blueprint.json +63 -0
  71. data/spec/data/wire_test_project.json +5 -5
  72. data/spec/environment/default.rb +33 -0
  73. data/spec/environment/develop.rb +26 -0
  74. data/spec/environment/environment.rb +14 -0
  75. data/spec/environment/hotfix.rb +17 -0
  76. data/spec/environment/production.rb +31 -0
  77. data/spec/environment/release.rb +17 -0
  78. data/spec/helpers/blueprint_helper.rb +10 -7
  79. data/spec/helpers/cli_helper.rb +24 -22
  80. data/spec/helpers/connection_helper.rb +27 -25
  81. data/spec/helpers/crypto_helper.rb +7 -5
  82. data/spec/helpers/csv_helper.rb +5 -3
  83. data/spec/helpers/process_helper.rb +15 -10
  84. data/spec/helpers/project_helper.rb +40 -33
  85. data/spec/helpers/schedule_helper.rb +15 -9
  86. data/spec/helpers/spec_helper.rb +11 -0
  87. data/spec/integration/blueprint_updates_spec.rb +93 -0
  88. data/spec/integration/command_datawarehouse_spec.rb +2 -1
  89. data/spec/integration/command_projects_spec.rb +9 -8
  90. data/spec/integration/create_from_template_spec.rb +1 -1
  91. data/spec/integration/create_project_spec.rb +1 -1
  92. data/spec/integration/full_process_schedule_spec.rb +1 -1
  93. data/spec/integration/full_project_spec.rb +91 -30
  94. data/spec/integration/over_to_user_filters_spec.rb +24 -28
  95. data/spec/integration/partial_md_export_import_spec.rb +4 -4
  96. data/spec/integration/project_spec.rb +1 -1
  97. data/spec/integration/rest_spec.rb +1 -1
  98. data/spec/integration/user_filters_spec.rb +19 -24
  99. data/spec/integration/variables_spec.rb +7 -9
  100. data/spec/logging_in_logging_out_spec.rb +1 -1
  101. data/spec/spec_helper.rb +10 -1
  102. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +47 -0
  103. data/spec/unit/core/connection_spec.rb +2 -2
  104. data/spec/unit/core/logging_spec.rb +12 -4
  105. data/spec/unit/helpers/data_helper_spec.rb +60 -0
  106. data/spec/unit/models/blueprint/attributes_spec.rb +24 -0
  107. data/spec/unit/models/blueprint/dataset_spec.rb +116 -0
  108. data/spec/unit/models/blueprint/labels_spec.rb +39 -0
  109. data/spec/unit/models/blueprint/project_blueprint_spec.rb +643 -0
  110. data/spec/unit/models/blueprint/reference_spec.rb +24 -0
  111. data/spec/unit/models/{schema_builder_spec.rb → blueprint/schema_builder_spec.rb} +12 -4
  112. data/spec/unit/models/blueprint/to_wire_spec.rb +169 -0
  113. data/spec/unit/models/domain_spec.rb +13 -2
  114. data/spec/unit/models/from_wire_spec.rb +277 -98
  115. data/spec/unit/models/metadata_spec.rb +22 -4
  116. data/spec/unit/models/model_spec.rb +49 -39
  117. data/spec/unit/models/profile_spec.rb +1 -0
  118. data/spec/unit/models/project_spec.rb +7 -7
  119. data/spec/unit/models/schedule_spec.rb +20 -0
  120. data/spec/unit/models/to_manifest_spec.rb +31 -11
  121. data/spec/unit/rest/polling_spec.rb +86 -0
  122. metadata +102 -30
  123. data/lib/gooddata/models/project_builder.rb +0 -136
  124. data/lib/gooddata/models/schema_builder.rb +0 -77
  125. data/out.txt +0 -0
  126. data/spec/data/additional_dataset_module.json +0 -18
  127. data/spec/data/blueprint_invalid.json +0 -38
  128. data/spec/data/m_n_model/blueprint.json +0 -76
  129. data/spec/data/model_module.json +0 -18
  130. data/spec/data/test_project_model_spec.json +0 -76
  131. data/spec/unit/models/attribute_column_spec.rb +0 -7
  132. data/spec/unit/models/project_blueprint_spec.rb +0 -239
  133. data/spec/unit/models/to_wire_spec.rb +0 -71
@@ -12,17 +12,7 @@ module GoodData
12
12
  # @param dataset [Hash] Dataset blueprint hash represenation
13
13
  # @return [Hash] Manifest for a particular reference
14
14
  def self.anchor_to_wire(_project, dataset)
15
- if DatasetBlueprint.anchor(dataset)
16
- attribute_to_wire(dataset, DatasetBlueprint.anchor(dataset))
17
- else
18
- {
19
- attribute: {
20
- identifier: GoodData::Model.identifier_for(dataset, type: :anchor_no_label),
21
- title: "Records of #{ GoodData::Model.title(dataset) }",
22
- folder: dataset[:folder] || GoodData::Model.title(dataset)
23
- }
24
- }
25
- end
15
+ attribute_to_wire(dataset, DatasetBlueprint.anchor(dataset))
26
16
  end
27
17
 
28
18
  # Converts atttribute to wire format.
@@ -42,28 +32,26 @@ module GoodData
42
32
  # @param attribute [Hash] Attribute
43
33
  # @return [Hash] Manifest for a particular reference
44
34
  def self.attribute_to_wire(dataset, attribute)
45
- default_label = DatasetBlueprint.default_label_for_attribute(dataset, attribute)
46
- label = default_label[:type].to_sym == :label ? default_label : default_label.merge(type: :primary_label)
47
- payload = {
48
- attribute: {
49
- identifier: GoodData::Model.identifier_for(dataset, attribute),
50
- title: GoodData::Model.title(attribute),
51
- folder: attribute[:folder] || dataset[:folder] || GoodData::Model.title(dataset),
52
- labels: ([attribute.merge(type: :primary_label)] + DatasetBlueprint.labels_for_attribute(dataset, attribute)).map do |l|
53
- {
54
- label: {
55
- identifier: GoodData::Model.identifier_for(dataset, l, attribute),
56
- title: GoodData::Model.title(l),
57
- type: l[:gd_type],
58
- dataType: l[:gd_data_type]
59
- }
60
- }
61
- end,
62
- defaultLabel: GoodData::Model.identifier_for(dataset, label, attribute)
35
+ ls = DatasetBlueprint.labels_for_attribute(dataset, attribute)
36
+ labels = ls.map do |l|
37
+ {
38
+ label: {
39
+ identifier: l[:id],
40
+ title: GoodData::Model.title(l),
41
+ type: l[:gd_type] || Model::DEFAULT_TYPE,
42
+ dataType: GoodData::Model.normalize_gd_data_type(l[:gd_data_type]) || Model::DEFAULT_ATTRIBUTE_DATATYPE
43
+ }
63
44
  }
64
- }
65
- payload.tap do |p|
66
- p[:attribute][:description] = GoodData::Model.description(attribute) if GoodData::Model.description(attribute)
45
+ end
46
+ {}.tap do |a|
47
+ a[:attribute] = {}
48
+ a[:attribute][:identifier] = attribute[:id]
49
+ a[:attribute][:title] = Model.title(attribute)
50
+ a[:attribute][:folder] = attribute[:folder] || dataset[:folder] || GoodData::Model.title(dataset)
51
+ a[:attribute][:labels] = labels unless labels.empty?
52
+ a[:attribute][:description] = GoodData::Model.description(attribute) if GoodData::Model.description(attribute)
53
+ default = ls.find { |l| l[:default_label] }
54
+ a[:attribute][:defaultLabel] = (default && default[:id]) || ls.first[:id] unless ls.empty?
67
55
  end
68
56
  end
69
57
 
@@ -75,7 +63,7 @@ module GoodData
75
63
  def self.dataset_to_wire(project, dataset)
76
64
  {
77
65
  dataset: {
78
- identifier: GoodData::Model.identifier_for(dataset),
66
+ identifier: dataset[:id],
79
67
  title: GoodData::Model.title(dataset),
80
68
  anchor: anchor_to_wire(project, dataset),
81
69
  attributes: attributes_to_wire(project, dataset),
@@ -90,13 +78,13 @@ module GoodData
90
78
  # @param project [Hash] Project blueprint hash represenation
91
79
  # @param dataset [Hash] Dataset blueprint hash represenation
92
80
  # @return [Hash] Manifest for a particular reference
93
- def self.date_dimensions_to_wire(_project, dataset)
94
- {
95
- dateDimension: {
96
- name: dataset[:name],
97
- title: GoodData::Model.title(dataset)
98
- }
99
- }
81
+ def self.date_dimension_to_wire(_project, dataset)
82
+ payload = {}.tap do |dd|
83
+ dd[:name] = dataset[:id]
84
+ dd[:urn] = dataset[:urn] if dataset[:urn]
85
+ dd[:title] = GoodData::Model.title(dataset)
86
+ end
87
+ { dateDimension: payload }
100
88
  end
101
89
 
102
90
  # Converts fact to wire format.
@@ -107,10 +95,10 @@ module GoodData
107
95
  def self.fact_to_wire(dataset, fact)
108
96
  payload = {
109
97
  fact: {
110
- identifier: GoodData::Model.identifier_for(dataset, fact),
98
+ identifier: fact[:id],
111
99
  title: GoodData::Model.title(fact),
112
100
  folder: fact[:folder] || dataset[:folder] || GoodData::Model.title(dataset),
113
- dataType: fact[:gd_data_type] || DEFAULT_FACT_DATATYPE
101
+ dataType: GoodData::Model.normalize_gd_data_type(fact[:gd_data_type]) || DEFAULT_FACT_DATATYPE
114
102
  }
115
103
  }
116
104
  payload.tap do |p|
@@ -123,16 +111,9 @@ module GoodData
123
111
  # @param fact [Hash] Project blueprint hash represenation
124
112
  # @param dataset [Hash] Dataset blueprint hash represenation
125
113
  # @return [Hash] Manifest for a particular reference
126
- def self.references_to_wire(project, dataset)
114
+ def self.references_to_wire(_project, dataset)
127
115
  DatasetBlueprint.references(dataset).map do |r|
128
- if ProjectBlueprint.date_dimension?(project, r[:dataset])
129
- ProjectBlueprint.find_date_dimension(project, r[:dataset])[:name]
130
- elsif ProjectBlueprint.dataset?(project, r[:dataset])
131
- ds = ProjectBlueprint.find_dataset(project, r[:dataset])
132
- 'dataset.' + ds[:name]
133
- else
134
- fail 'This dataset does not exist'
135
- end
116
+ r[:dataset]
136
117
  end
137
118
  end
138
119
 
@@ -148,7 +129,7 @@ module GoodData
148
129
  targetModel: {
149
130
  projectModel: {
150
131
  datasets: (what[:datasets] || []).map { |d| dataset_to_wire(what, d) },
151
- dateDimensions: (what[:date_dimensions] || []).map { |d| date_dimensions_to_wire(what, d) }
132
+ dateDimensions: (what[:date_dimensions] || []).map { |d| date_dimension_to_wire(what, d) }
152
133
  }
153
134
  }
154
135
  }
@@ -17,7 +17,7 @@ module GoodData
17
17
  c = client(opts)
18
18
  fail ArgumentError, 'No :client specified' if c.nil?
19
19
 
20
- auth_token = opts[:auth_token]
20
+ auth_token = opts[:auth_token] || opts[:token]
21
21
  fail ArgumentError, 'You have to provide your token for creating projects as :auth_token parameter' if auth_token.nil? || auth_token.empty?
22
22
 
23
23
  title = opts[:title]
@@ -34,7 +34,7 @@ module GoodData
34
34
  res = c.post(CREATE_URL, json)
35
35
 
36
36
  # wait until the instance is created
37
- final_res = c.poll_on_response(res['asyncTask']['links']['poll'], :sleep_interval => 3) do |r|
37
+ final_res = c.poll_on_response(res['asyncTask']['links']['poll'], opts.merge(sleep_interval: 3)) do |r|
38
38
  r['asyncTask']['links']['instance'].nil?
39
39
  end
40
40
 
@@ -97,6 +97,7 @@ module GoodData
97
97
  end
98
98
 
99
99
  def update_user(user_data, options = { client: GoodData.connection })
100
+ user_data = user_data.to_hash if user_data.is_a?(GoodData::Profile)
100
101
  client = client(options)
101
102
  user_data = user_data.to_hash
102
103
  # generated_pass = rand(10E10).to_s
@@ -189,7 +190,7 @@ module GoodData
189
190
  result = []
190
191
  page_limit = opts[:page_limit] || 1000
191
192
  limit = opts[:limit] || Float::INFINITY
192
- offset = opts[:offset]
193
+ offset = opts[:offset] || 0
193
194
  uri = "#{domain.uri}/users?offset=#{offset}&limit=#{page_limit}"
194
195
  loop do
195
196
  tmp = client(opts).get(uri)
@@ -250,7 +251,7 @@ module GoodData
250
251
  # Example
251
252
  #
252
253
  # GoodData.connect 'tomas.korcak@gooddata.com' 'your-password'
253
- # domain = GoodData::Domain['gooddata-tomas-korcak']
254
+ # domain = project.domain('domain-name')
254
255
  # domain.add_user 'joe.doe@example', 'sup3rS3cr3tP4ssW0rtH'
255
256
  #
256
257
  def add_user(data, opts = {})
@@ -89,8 +89,8 @@ module GoodData
89
89
  # Wait for execution result, status different than RUNNING or SCHEDULED
90
90
  #
91
91
  # @return [GoodData::Execution] Execution result
92
- def wait_for_result
93
- res = client.poll_on_response(uri) do |body|
92
+ def wait_for_result(options = {})
93
+ res = client.poll_on_response(uri, options) do |body|
94
94
  body['execution'] && (body['execution']['status'] == 'RUNNING' || body['execution']['status'] == 'SCHEDULED')
95
95
  end
96
96
  @json = res
@@ -24,6 +24,11 @@ module GoodData
24
24
  Time.parse(json['executionDetail']['created'])
25
25
  end
26
26
 
27
+ # Has execution failed?
28
+ def error?
29
+ status == :error
30
+ end
31
+
27
32
  # Timestamp when execution was finished
28
33
  def finished
29
34
  Time.parse(json['executionDetail']['finished'])
@@ -41,7 +46,7 @@ module GoodData
41
46
 
42
47
  # Is execution ok?
43
48
  def ok?
44
- status.downcase == 'ok'
49
+ status == :ok
45
50
  end
46
51
 
47
52
  # Timestamp when execution was started
@@ -51,7 +56,7 @@ module GoodData
51
56
 
52
57
  # Status of execution
53
58
  def status
54
- json['executionDetail']['status']
59
+ json['executionDetail']['status'].downcase.to_sym
55
60
  end
56
61
 
57
62
  # Timestamp when execution was updated
@@ -7,92 +7,84 @@ module GoodData
7
7
  module FromWire
8
8
  # Converts dataset from wire format into an internal blueprint representation
9
9
  #
10
- # @param stuff [Hash] Whatever comes from wire
10
+ # @param dataset [Hash] Whatever comes from wire
11
11
  # @return [Hash] Manifest for a particular reference
12
- def self.dataset_from_wire(stuff)
12
+ def self.dataset_from_wire(dataset)
13
13
  {}.tap do |d|
14
+ id = dataset['dataset']['identifier']
15
+
14
16
  d[:type] = :dataset
15
- d[:title] = stuff['dataset']['title'] if stuff['dataset']['title'] != stuff['dataset']['identifier'].split('.').last.titleize
16
- d[:name] = stuff['dataset']['identifier'].split('.').last
17
- d[:columns] = (parse_anchor(stuff) + parse_attributes(stuff) + parse_facts(stuff) + parse_references(stuff))
17
+ d[:title] = dataset['dataset']['title']
18
+ d[:id] = id
19
+ d[:columns] = (parse_anchor(dataset) + parse_attributes(dataset) + parse_facts(dataset) + parse_references(dataset))
18
20
  end
19
21
  end
20
22
 
21
23
  # Entry method for converting information about project mode from wire
22
24
  # format into an internal blueprint representation
23
25
  #
24
- # @param stuff [Hash] Whatever comes from wire
26
+ # @param wire_model [Hash] Whatever comes from wire
25
27
  # @return [GoodData::Model::ProjectBlueprint] Manifest for a particular reference
26
- def self.from_wire(stuff)
27
- model = stuff['projectModelView']['model']['projectModel']
28
+ def self.from_wire(wire_model)
29
+ model = wire_model['projectModelView']['model']['projectModel']
28
30
  datasets = model['datasets'] || []
29
31
  dims = model['dateDimensions'] || []
32
+
30
33
  ProjectBlueprint.new(
31
34
  datasets: datasets.map { |ds| dataset_from_wire(ds) },
32
35
  date_dimensions: dims.map { |dd| parse_date_dimensions(dd) }
33
36
  )
34
37
  end
35
38
 
36
- # Converts anchor from wire format into an internal blueprint representation
39
+ # Converts attrbutes from wire format into an internal blueprint representation
37
40
  #
38
41
  # @param stuff [Hash] Whatever comes from wire
39
42
  # @return [Hash] Manifest for a particular reference
40
- def self.parse_anchor(stuff)
41
- attribute = stuff['dataset']['anchor']['attribute']
42
- if !attribute.key?('labels')
43
- []
44
- else
45
- labels = attribute['labels'] || []
46
- default_label = attribute['defaultLabel']
47
- primary_label_name = attribute['identifier'].split('.').last
48
- dataset_name = attribute['identifier'].split('.')[1]
49
- primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
50
- primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
51
- dl = primary_labels.map do |label|
52
- parse_label(attribute, label, 'anchor', default_label)
53
- end
54
- rl = regular_labels.map do |label|
55
- parse_label(attribute, label, 'label', default_label)
56
- end
57
- dl + rl
43
+ def self.parse_attributes(stuff)
44
+ dataset = stuff['dataset']
45
+ attributes = dataset['attributes'] || []
46
+ attributes.mapcat do |a|
47
+ parse_attribute(a['attribute'])
58
48
  end
59
49
  end
60
50
 
61
- # Converts attrbutes from wire format into an internal blueprint representation
51
+ # Converts anchor from wire format into an internal blueprint representation
62
52
  #
63
53
  # @param stuff [Hash] Whatever comes from wire
64
54
  # @return [Hash] Manifest for a particular reference
65
- def self.parse_attributes(stuff)
66
- dataset = stuff['dataset']
67
- attributes = dataset['attributes'] || []
68
- attributes.mapcat do |a|
69
- attribute = a['attribute']
70
- labels = attribute['labels'] || []
71
- default_label = attribute['defaultLabel']
72
- primary_label_name = attribute['identifier'].split('.').last
73
- dataset_name = attribute['identifier'].split('.')[1]
74
- primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
75
- primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
76
- dl = primary_labels.map do |label|
77
- parse_label(attribute, label, 'attribute', default_label)
78
- end
79
- rl = regular_labels.map do |label|
80
- parse_label(attribute, label, 'label', default_label)
81
- end
82
- dl + rl
55
+ def self.parse_anchor(stuff)
56
+ anchor = stuff['dataset']['anchor']['attribute']
57
+ parse_attribute(anchor, :anchor)
58
+ end
59
+
60
+ def self.parse_attribute(attribute, type = :attribute)
61
+ labels = attribute['labels'] || []
62
+ default_label_id = attribute['defaultLabel']
63
+ default_label = labels.find { |l| l['label']['identifier'] == default_label_id } || labels.first
64
+ regular_labels = labels - [default_label]
65
+ pl = default_label.nil? ? [] : [parse_label(attribute, default_label, :default_label)]
66
+ rl = regular_labels.map do |label|
67
+ parse_label(attribute, label, :label)
68
+ end
69
+ attribute = {}.tap do |a|
70
+ a[:type] = type
71
+ a[:id] = attribute['identifier']
72
+ a[:title] = attribute['title']
73
+ a[:description] = attribute['description']
74
+ a[:folder] = attribute['folder']
83
75
  end
76
+ [attribute] + pl + rl
84
77
  end
85
78
 
86
79
  # Converts date dimensions from wire format into an internal blueprint representation
87
80
  #
88
81
  # @param stuff [Hash] Whatever comes from wire
89
82
  # @return [Hash] Manifest for a particular reference
90
- def self.parse_date_dimensions(stuff)
83
+ def self.parse_date_dimensions(date_dim)
91
84
  {}.tap do |d|
92
85
  d[:type] = :date_dimension
93
- # d[:urn] = :date_dimension
94
- d[:name] = stuff['dateDimension']['name']
95
- d[:title] = stuff['dateDimension']['title'] if stuff['dateDimension']['title'] != d[:name].titleize
86
+ d[:id] = date_dim['dateDimension']['name']
87
+ d[:title] = date_dim['dateDimension']['title']
96
88
  end
97
89
  end
98
90
 
@@ -105,11 +97,11 @@ module GoodData
105
97
  facts.map do |fact|
106
98
  {}.tap do |f|
107
99
  f[:type] = fact['fact']['identifier'] =~ /^dt\./ ? :date_fact : :fact
108
- f[:name] = fact['fact']['identifier'].split('.').last
109
- f[:title] = fact['fact']['title'] if fact['fact']['title'] != fact['fact']['identifier'].split('.').last.titleize
100
+ f[:id] = fact['fact']['identifier']
101
+ f[:title] = fact['fact']['title']
110
102
  f[:description] = fact['fact']['description'] if fact['fact']['description']
111
- f[:folder] = fact['fact']['folder'] if fact['fact']['folder']
112
- f[:gd_data_type] = fact['fact']['dataType'] if fact['fact'].key?('dataType')
103
+ f[:folder] = fact['fact']['folder']
104
+ f[:gd_data_type] = fact['fact']['dataType'] || GoodData::Model::DEFAULT_FACT_DATATYPE
113
105
  end
114
106
  end
115
107
  end
@@ -118,38 +110,35 @@ module GoodData
118
110
  #
119
111
  # @param stuff [Hash] Whatever comes from wire
120
112
  # @return [Hash] Manifest for a particular reference
121
- def self.parse_label(attribute, label, type, default_label = nil)
113
+ def self.parse_label(attribute, label, type)
122
114
  {}.tap do |l|
123
- l[:type] = type
124
- l[:reference] = attribute['identifier'].split('.').last if type == 'label'
125
- l[:name] = label['label']['identifier'].split('.').last
126
- l[:title] = label['label']['title'] if label['label']['title'] != label['label']['identifier'].split('.').last.titleize
127
- l[:description] = attribute['description'] if %w(attribute anchor).include?(type) && attribute['description']
128
- l[:folder] = attribute['folder'] if attribute['folder'] && (type == 'attribute' || type == 'anchor')
129
- l[:gd_data_type] = label['label']['dataType'] if label['label'].key?('dataType')
130
- l[:gd_type] = label['label']['type'] if label['label'].key?('type')
131
- l[:default_label] = true if default_label == label['label']['identifier']
115
+ l[:type] = :label
116
+ l[:id] = label['label']['identifier']
117
+ l[:reference] = attribute['identifier']
118
+ l[:title] = label['label']['title']
119
+ l[:gd_data_type] = label['label']['dataType'] || GoodData::Model::DEFAULT_ATTRIBUTE_DATATYPE
120
+ l[:gd_type] = label['label']['type'] || GoodData::Model::DEFAULT_TYPE
121
+ l[:default_label] = true if type == :default_label
132
122
  end
133
123
  end
134
124
 
135
125
  # Converts label from wire format into an internal blueprint representation
136
126
  #
137
- # @param stuff [Hash] Whatever comes from wire
127
+ # @param dataset [Hash] Whatever comes from wire
128
+ # @param anchor_hash [Hash] dataset id -> anchor id hash
138
129
  # @return [Hash] Manifest for a particular reference
139
- def self.parse_references(stuff)
140
- references = stuff['dataset']['references'] || []
130
+ def self.parse_references(dataset)
131
+ references = dataset['dataset']['references'] || []
141
132
  references.map do |ref|
142
133
  if ref =~ /^dataset\./
143
134
  {
144
135
  :type => :reference,
145
- :name => ref.gsub(/^dataset\./, ''),
146
- :dataset => ref.gsub(/^dataset\./, '')
136
+ :dataset => ref
147
137
  }
148
138
  else
149
139
  {
150
140
  :type => :date,
151
- :name => ref.gsub(/^dataset\./, ''),
152
- :dataset => ref.gsub(/^dataset\./, '')
141
+ :dataset => ref
153
142
  }
154
143
  end
155
144
  end
@@ -1,125 +1,125 @@
1
- # encoding: UTF-8
2
-
3
- module GoodData
4
- module Model
5
- module FromWire
6
- # Converts anchor from wire format into an internal blueprint representation
7
- #
8
- # @param stuff [Hash] Whatever comes from wire
9
- # @return [Hash] Manifest for a particular reference
10
- def self.parse_anchor(stuff)
11
- attribute = stuff['dataset']['anchor']['attribute']
12
- if !attribute.key?('labels')
13
- []
14
- else
15
- labels = attribute['labels'] || []
16
- default_label = attribute['defaultLabel']
17
- primary_label_name = attribute['identifier'].split('.').last
18
- dataset_name = attribute['identifier'].split('.')[1]
19
- primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
20
- primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
21
- dl = primary_labels.map do |label|
22
- parse_label(attribute, label, 'anchor', default_label)
23
- end
24
- rl = regular_labels.map do |label|
25
- parse_label(attribute, label, 'label', default_label)
26
- end
27
- dl + rl
28
- end
29
- end
30
-
31
- # Converts attrbutes from wire format into an internal blueprint representation
32
- #
33
- # @param stuff [Hash] Whatever comes from wire
34
- # @return [Hash] Manifest for a particular reference
35
- def self.parse_attributes(stuff)
36
- dataset = stuff['dataset']
37
- attributes = dataset['attributes'] || []
38
- attributes.mapcat do |a|
39
- attribute = a['attribute']
40
- labels = attribute['labels'] || []
41
- default_label = attribute['defaultLabel']
42
- primary_label_name = attribute['identifier'].split('.').last
43
- dataset_name = attribute['identifier'].split('.')[1]
44
- primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
45
- primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
46
- dl = primary_labels.map do |label|
47
- parse_label(attribute, label, 'attribute', default_label)
48
- end
49
- rl = regular_labels.map do |label|
50
- parse_label(attribute, label, 'label', default_label)
51
- end
52
- dl + rl
53
- end
54
- end
55
-
56
- # Converts date dimensions from wire format into an internal blueprint representation
57
- #
58
- # @param stuff [Hash] Whatever comes from wire
59
- # @return [Hash] Manifest for a particular reference
60
- def self.parse_date_dimensions(stuff)
61
- {}.tap do |d|
62
- d[:type] = :date_dimension
63
- # d[:urn] = :date_dimension
64
- d[:name] = stuff['dateDimension']['name']
65
- d[:title] = stuff['dateDimension']['title'] if stuff['dateDimension']['title'] != d[:name].titleize
66
- end
67
- end
68
-
69
- # Converts facts from wire format into an internal blueprint representation
70
- #
71
- # @param stuff [Hash] Whatever comes from wire
72
- # @return [Hash] Manifest for a particular reference
73
- def self.parse_facts(stuff)
74
- facts = stuff['dataset']['facts'] || []
75
- facts.map do |fact|
76
- {}.tap do |f|
77
- f[:type] = fact['fact']['identifier'] =~ /^dt\./ ? :date_fact : :fact
78
- f[:name] = fact['fact']['identifier'].split('.').last
79
- f[:title] = fact['fact']['title'] if fact['fact']['title'] != fact['fact']['identifier'].split('.').last.titleize
80
- f[:gd_data_type] = fact['fact']['dataType'] if fact['fact'].key?('dataType')
81
- end
82
- end
83
- end
84
-
85
- # Converts label from wire format into an internal blueprint representation
86
- #
87
- # @param stuff [Hash] Whatever comes from wire
88
- # @return [Hash] Manifest for a particular reference
89
- def self.parse_label(attribute, label, type, default_label = nil)
90
- {}.tap do |l|
91
- l[:type] = type
92
- l[:reference] = attribute['identifier'].split('.').last if type == 'label'
93
- l[:name] = label['label']['identifier'].split('.').last
94
- l[:title] = label['label']['title'] if label['label']['title'] != label['label']['identifier'].split('.').last.titleize
95
- l[:gd_data_type] = label['label']['dataType'] if label['label'].key?('dataType')
96
- l[:gd_type] = label['label']['type'] if label['label'].key?('type')
97
- l[:default_label] = true if default_label == label['label']['identifier']
98
- end
99
- end
100
-
101
- # Converts label from wire format into an internal blueprint representation
102
- #
103
- # @param stuff [Hash] Whatever comes from wire
104
- # @return [Hash] Manifest for a particular reference
105
- def self.parse_references(stuff)
106
- references = stuff['dataset']['references'] || []
107
- references.map do |ref|
108
- if ref =~ /^dataset\./
109
- {
110
- :type => :reference,
111
- :name => ref.gsub(/^dataset\./, ''),
112
- :dataset => ref.gsub(/^dataset\./, '')
113
- }
114
- else
115
- {
116
- :type => :date,
117
- :name => ref.gsub(/^dataset\./, ''),
118
- :dataset => ref.gsub(/^dataset\./, '')
119
- }
120
- end
121
- end
122
- end
123
- end
124
- end
125
- end
1
+ # # encoding: UTF-8
2
+ #
3
+ # module GoodData
4
+ # module Model
5
+ # module FromWire
6
+ # # Converts anchor from wire format into an internal blueprint representation
7
+ # #
8
+ # # @param stuff [Hash] Whatever comes from wire
9
+ # # @return [Hash] Manifest for a particular reference
10
+ # def self.parse_anchor(stuff)
11
+ # attribute = stuff['dataset']['anchor']['attribute']
12
+ # if !attribute.key?('labels')
13
+ # []
14
+ # else
15
+ # labels = attribute['labels'] || []
16
+ # default_label = attribute['defaultLabel']
17
+ # primary_label_name = attribute['identifier'].split('.').last
18
+ # dataset_name = attribute['identifier'].split('.')[1]
19
+ # primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
20
+ # primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
21
+ # dl = primary_labels.map do |label|
22
+ # parse_label(attribute, label, 'anchor', default_label)
23
+ # end
24
+ # rl = regular_labels.map do |label|
25
+ # parse_label(attribute, label, 'label', default_label)
26
+ # end
27
+ # dl + rl
28
+ # end
29
+ # end
30
+ #
31
+ # # Converts attrbutes from wire format into an internal blueprint representation
32
+ # #
33
+ # # @param stuff [Hash] Whatever comes from wire
34
+ # # @return [Hash] Manifest for a particular reference
35
+ # def self.parse_attributes(stuff)
36
+ # dataset = stuff['dataset']
37
+ # attributes = dataset['attributes'] || []
38
+ # attributes.mapcat do |a|
39
+ # attribute = a['attribute']
40
+ # labels = attribute['labels'] || []
41
+ # default_label = attribute['defaultLabel']
42
+ # primary_label_name = attribute['identifier'].split('.').last
43
+ # dataset_name = attribute['identifier'].split('.')[1]
44
+ # primary_label_identifier = GoodData::Model.identifier_for({ name: dataset_name }, type: :primary_label, name: primary_label_name)
45
+ # primary_labels, regular_labels = labels.partition { |x| x['label']['identifier'] == primary_label_identifier }
46
+ # dl = primary_labels.map do |label|
47
+ # parse_label(attribute, label, 'attribute', default_label)
48
+ # end
49
+ # rl = regular_labels.map do |label|
50
+ # parse_label(attribute, label, 'label', default_label)
51
+ # end
52
+ # dl + rl
53
+ # end
54
+ # end
55
+ #
56
+ # # Converts date dimensions from wire format into an internal blueprint representation
57
+ # #
58
+ # # @param stuff [Hash] Whatever comes from wire
59
+ # # @return [Hash] Manifest for a particular reference
60
+ # def self.parse_date_dimensions(stuff)
61
+ # {}.tap do |d|
62
+ # d[:type] = :date_dimension
63
+ # # d[:urn] = :date_dimension
64
+ # d[:name] = stuff['dateDimension']['name']
65
+ # d[:title] = stuff['dateDimension']['title'] if stuff['dateDimension']['title'] != d[:name].titleize
66
+ # end
67
+ # end
68
+ #
69
+ # # Converts facts from wire format into an internal blueprint representation
70
+ # #
71
+ # # @param stuff [Hash] Whatever comes from wire
72
+ # # @return [Hash] Manifest for a particular reference
73
+ # def self.parse_facts(stuff)
74
+ # facts = stuff['dataset']['facts'] || []
75
+ # facts.map do |fact|
76
+ # {}.tap do |f|
77
+ # f[:type] = fact['fact']['identifier'] =~ /^dt\./ ? :date_fact : :fact
78
+ # f[:name] = fact['fact']['identifier'].split('.').last
79
+ # f[:title] = fact['fact']['title'] if fact['fact']['title'] != fact['fact']['identifier'].split('.').last.titleize
80
+ # f[:gd_data_type] = fact['fact']['dataType'] if fact['fact'].key?('dataType')
81
+ # end
82
+ # end
83
+ # end
84
+ #
85
+ # # Converts label from wire format into an internal blueprint representation
86
+ # #
87
+ # # @param stuff [Hash] Whatever comes from wire
88
+ # # @return [Hash] Manifest for a particular reference
89
+ # def self.parse_label(attribute, label, type, default_label = nil)
90
+ # {}.tap do |l|
91
+ # l[:type] = type
92
+ # l[:reference] = attribute['identifier'].split('.').last if type == 'label'
93
+ # l[:name] = label['label']['identifier'].split('.').last
94
+ # l[:title] = label['label']['title'] if label['label']['title'] != label['label']['identifier'].split('.').last.titleize
95
+ # l[:gd_data_type] = label['label']['dataType'] if label['label'].key?('dataType')
96
+ # l[:gd_type] = label['label']['type'] if label['label'].key?('type')
97
+ # l[:default_label] = true if default_label == label['label']['identifier']
98
+ # end
99
+ # end
100
+ #
101
+ # # Converts label from wire format into an internal blueprint representation
102
+ # #
103
+ # # @param stuff [Hash] Whatever comes from wire
104
+ # # @return [Hash] Manifest for a particular reference
105
+ # def self.parse_references(stuff)
106
+ # references = stuff['dataset']['references'] || []
107
+ # references.map do |ref|
108
+ # if ref =~ /^dataset\./
109
+ # {
110
+ # :type => :reference,
111
+ # :name => ref.gsub(/^dataset\./, ''),
112
+ # :dataset => ref.gsub(/^dataset\./, '')
113
+ # }
114
+ # else
115
+ # {
116
+ # :type => :date,
117
+ # :name => ref.gsub(/^dataset\./, ''),
118
+ # :dataset => ref.gsub(/^dataset\./, '')
119
+ # }
120
+ # end
121
+ # end
122
+ # end
123
+ # end
124
+ # end
125
+ # end