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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +8 -19
- data/Guardfile +5 -0
- data/README.md +1 -3
- data/bin/gooddata +1 -1
- data/gooddata.gemspec +6 -4
- data/lib/gooddata.rb +1 -1
- data/lib/gooddata/bricks/middleware/aws_middleware.rb +24 -0
- data/lib/gooddata/cli/commands/console_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/project_cmd.rb +29 -9
- data/lib/gooddata/cli/hooks.rb +9 -3
- data/lib/gooddata/commands/datawarehouse.rb +1 -7
- data/lib/gooddata/commands/project.rb +4 -3
- data/lib/gooddata/core/logging.rb +14 -2
- data/lib/gooddata/exceptions/execution_limit_exceeded.rb +9 -0
- data/lib/gooddata/exceptions/uncomputable_report.rb +8 -0
- data/lib/gooddata/exceptions/validation_error.rb +1 -1
- data/lib/gooddata/goodzilla/goodzilla.rb +5 -1
- data/lib/gooddata/helpers/data_helper.rb +40 -9
- data/lib/gooddata/mixins/md_finders.rb +35 -0
- data/lib/gooddata/models/blueprint/anchor_field.rb +46 -0
- data/lib/gooddata/models/blueprint/attribute_field.rb +25 -0
- data/lib/gooddata/models/blueprint/blueprint.rb +7 -0
- data/lib/gooddata/models/blueprint/blueprint_field.rb +66 -0
- data/lib/gooddata/models/{dashboard_builder.rb → blueprint/dashboard_builder.rb} +0 -0
- data/lib/gooddata/models/{schema_blueprint.rb → blueprint/dataset_blueprint.rb} +176 -117
- data/lib/gooddata/models/blueprint/date_dimension.rb +10 -0
- data/lib/gooddata/models/blueprint/fact_field.rb +16 -0
- data/lib/gooddata/models/blueprint/label_field.rb +39 -0
- data/lib/gooddata/models/{project_blueprint.rb → blueprint/project_blueprint.rb} +366 -168
- data/lib/gooddata/models/blueprint/project_builder.rb +79 -0
- data/lib/gooddata/models/blueprint/reference_field.rb +39 -0
- data/lib/gooddata/models/blueprint/schema_blueprint.rb +156 -0
- data/lib/gooddata/models/blueprint/schema_builder.rb +85 -0
- data/lib/gooddata/models/{to_manifest.rb → blueprint/to_manifest.rb} +25 -20
- data/lib/gooddata/models/{to_wire.rb → blueprint/to_wire.rb} +33 -52
- data/lib/gooddata/models/datawarehouse.rb +2 -2
- data/lib/gooddata/models/domain.rb +3 -2
- data/lib/gooddata/models/execution.rb +2 -2
- data/lib/gooddata/models/execution_detail.rb +7 -2
- data/lib/gooddata/models/from_wire.rb +60 -71
- data/lib/gooddata/models/from_wire_parse.rb +125 -125
- data/lib/gooddata/models/metadata.rb +14 -0
- data/lib/gooddata/models/metadata/dashboard.rb +2 -2
- data/lib/gooddata/models/metadata/label.rb +1 -1
- data/lib/gooddata/models/metadata/report.rb +6 -5
- data/lib/gooddata/models/metadata/report_definition.rb +44 -59
- data/lib/gooddata/models/model.rb +131 -43
- data/lib/gooddata/models/process.rb +13 -11
- data/lib/gooddata/models/profile.rb +12 -1
- data/lib/gooddata/models/project.rb +223 -19
- data/lib/gooddata/models/project_creator.rb +4 -15
- data/lib/gooddata/models/schedule.rb +1 -0
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +2 -2
- data/lib/gooddata/rest/client.rb +18 -18
- data/lib/gooddata/rest/connection.rb +113 -94
- data/lib/gooddata/version.rb +1 -1
- data/lib/templates/project/model/model.rb.erb +15 -16
- data/spec/data/blueprints/additional_dataset_module.json +32 -0
- data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
- data/spec/data/blueprints/invalid_blueprint.json +103 -0
- data/spec/data/blueprints/m_n_model.json +104 -0
- data/spec/data/blueprints/model_module.json +25 -0
- data/spec/data/blueprints/test_blueprint.json +38 -0
- data/spec/data/blueprints/test_project_model_spec.json +106 -0
- data/spec/data/gd_gse_data_manifest.json +34 -34
- data/spec/data/manifests/test_blueprint.json +32 -0
- data/spec/data/{manifest_test_project.json → manifests/test_project.json} +9 -18
- data/spec/data/wire_models/test_blueprint.json +63 -0
- data/spec/data/wire_test_project.json +5 -5
- data/spec/environment/default.rb +33 -0
- data/spec/environment/develop.rb +26 -0
- data/spec/environment/environment.rb +14 -0
- data/spec/environment/hotfix.rb +17 -0
- data/spec/environment/production.rb +31 -0
- data/spec/environment/release.rb +17 -0
- data/spec/helpers/blueprint_helper.rb +10 -7
- data/spec/helpers/cli_helper.rb +24 -22
- data/spec/helpers/connection_helper.rb +27 -25
- data/spec/helpers/crypto_helper.rb +7 -5
- data/spec/helpers/csv_helper.rb +5 -3
- data/spec/helpers/process_helper.rb +15 -10
- data/spec/helpers/project_helper.rb +40 -33
- data/spec/helpers/schedule_helper.rb +15 -9
- data/spec/helpers/spec_helper.rb +11 -0
- data/spec/integration/blueprint_updates_spec.rb +93 -0
- data/spec/integration/command_datawarehouse_spec.rb +2 -1
- data/spec/integration/command_projects_spec.rb +9 -8
- data/spec/integration/create_from_template_spec.rb +1 -1
- data/spec/integration/create_project_spec.rb +1 -1
- data/spec/integration/full_process_schedule_spec.rb +1 -1
- data/spec/integration/full_project_spec.rb +91 -30
- data/spec/integration/over_to_user_filters_spec.rb +24 -28
- data/spec/integration/partial_md_export_import_spec.rb +4 -4
- data/spec/integration/project_spec.rb +1 -1
- data/spec/integration/rest_spec.rb +1 -1
- data/spec/integration/user_filters_spec.rb +19 -24
- data/spec/integration/variables_spec.rb +7 -9
- data/spec/logging_in_logging_out_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -1
- data/spec/unit/bricks/middleware/aws_middelware_spec.rb +47 -0
- data/spec/unit/core/connection_spec.rb +2 -2
- data/spec/unit/core/logging_spec.rb +12 -4
- data/spec/unit/helpers/data_helper_spec.rb +60 -0
- data/spec/unit/models/blueprint/attributes_spec.rb +24 -0
- data/spec/unit/models/blueprint/dataset_spec.rb +116 -0
- data/spec/unit/models/blueprint/labels_spec.rb +39 -0
- data/spec/unit/models/blueprint/project_blueprint_spec.rb +643 -0
- data/spec/unit/models/blueprint/reference_spec.rb +24 -0
- data/spec/unit/models/{schema_builder_spec.rb → blueprint/schema_builder_spec.rb} +12 -4
- data/spec/unit/models/blueprint/to_wire_spec.rb +169 -0
- data/spec/unit/models/domain_spec.rb +13 -2
- data/spec/unit/models/from_wire_spec.rb +277 -98
- data/spec/unit/models/metadata_spec.rb +22 -4
- data/spec/unit/models/model_spec.rb +49 -39
- data/spec/unit/models/profile_spec.rb +1 -0
- data/spec/unit/models/project_spec.rb +7 -7
- data/spec/unit/models/schedule_spec.rb +20 -0
- data/spec/unit/models/to_manifest_spec.rb +31 -11
- data/spec/unit/rest/polling_spec.rb +86 -0
- metadata +102 -30
- data/lib/gooddata/models/project_builder.rb +0 -136
- data/lib/gooddata/models/schema_builder.rb +0 -77
- data/out.txt +0 -0
- data/spec/data/additional_dataset_module.json +0 -18
- data/spec/data/blueprint_invalid.json +0 -38
- data/spec/data/m_n_model/blueprint.json +0 -76
- data/spec/data/model_module.json +0 -18
- data/spec/data/test_project_model_spec.json +0 -76
- data/spec/unit/models/attribute_column_spec.rb +0 -7
- data/spec/unit/models/project_blueprint_spec.rb +0 -239
- 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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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:
|
|
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.
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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:
|
|
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(
|
|
114
|
+
def self.references_to_wire(_project, dataset)
|
|
127
115
|
DatasetBlueprint.references(dataset).map do |r|
|
|
128
|
-
|
|
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|
|
|
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'], :
|
|
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 =
|
|
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
|
|
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
|
|
10
|
+
# @param dataset [Hash] Whatever comes from wire
|
|
11
11
|
# @return [Hash] Manifest for a particular reference
|
|
12
|
-
def self.dataset_from_wire(
|
|
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] =
|
|
16
|
-
d[:
|
|
17
|
-
d[:columns] = (parse_anchor(
|
|
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
|
|
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(
|
|
27
|
-
model =
|
|
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
|
|
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.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
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.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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(
|
|
83
|
+
def self.parse_date_dimensions(date_dim)
|
|
91
84
|
{}.tap do |d|
|
|
92
85
|
d[:type] = :date_dimension
|
|
93
|
-
|
|
94
|
-
d[:
|
|
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[:
|
|
109
|
-
f[:title] = fact['fact']['title']
|
|
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']
|
|
112
|
-
f[:gd_data_type] = fact['fact']['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
|
|
113
|
+
def self.parse_label(attribute, label, type)
|
|
122
114
|
{}.tap do |l|
|
|
123
|
-
l[:type] =
|
|
124
|
-
l[:
|
|
125
|
-
l[:
|
|
126
|
-
l[:title] = label['label']['title']
|
|
127
|
-
l[:
|
|
128
|
-
l[:
|
|
129
|
-
l[:
|
|
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
|
|
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(
|
|
140
|
-
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
|
-
:
|
|
146
|
-
:dataset => ref.gsub(/^dataset\./, '')
|
|
136
|
+
:dataset => ref
|
|
147
137
|
}
|
|
148
138
|
else
|
|
149
139
|
{
|
|
150
140
|
:type => :date,
|
|
151
|
-
:
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|