gooddata 0.6.10 → 0.6.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +6 -0
- data/README.md +1 -0
- data/gooddata.gemspec +38 -40
- data/lib/gooddata/bricks/base_downloader.rb +1 -1
- data/lib/gooddata/bricks/middleware/base_middleware.rb +36 -0
- data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +8 -38
- data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +14 -0
- data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +7 -6
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +7 -5
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +1 -1
- data/lib/gooddata/bricks/middleware/restforce_middleware.rb +20 -14
- data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +33 -0
- data/lib/gooddata/cli/commands/api_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/auth_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/console_cmd.rb +2 -2
- data/lib/gooddata/cli/commands/process_cmd.rb +54 -7
- data/lib/gooddata/cli/commands/project_cmd.rb +9 -9
- data/lib/gooddata/cli/commands/projects_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/run_ruby_cmd.rb +24 -7
- data/lib/gooddata/cli/commands/scaffold_cmd.rb +2 -2
- data/lib/gooddata/cli/commands/user_cmd.rb +1 -1
- data/lib/gooddata/cli/hooks.rb +3 -3
- data/lib/gooddata/commands/datasets.rb +1 -1
- data/lib/gooddata/commands/project.rb +2 -2
- data/lib/gooddata/commands/role.rb +1 -1
- data/lib/gooddata/commands/runners.rb +2 -2
- data/lib/gooddata/connection.rb +2 -2
- data/lib/gooddata/core/nil_logger.rb +1 -1
- data/lib/gooddata/core/rest.rb +12 -8
- data/lib/gooddata/data/guesser.rb +1 -1
- data/lib/gooddata/exceptions/attr_element_not_found.rb +1 -1
- data/lib/gooddata/extensions/enumerable.rb +1 -1
- data/lib/gooddata/extensions/hash.rb +20 -0
- data/lib/gooddata/helpers/csv_helper.rb +1 -1
- data/lib/gooddata/helpers/global_helpers.rb +59 -1
- data/lib/gooddata/mixins/md_lock.rb +83 -0
- data/lib/gooddata/mixins/md_object_indexer.rb +1 -1
- data/lib/gooddata/mixins/md_object_query.rb +1 -1
- data/lib/gooddata/mixins/md_relations.rb +0 -9
- data/lib/gooddata/models/dashboard_builder.rb +1 -1
- data/lib/gooddata/models/domain.rb +2 -2
- data/lib/gooddata/models/empty_result.rb +5 -5
- data/lib/gooddata/models/execution.rb +74 -0
- data/lib/gooddata/models/execution_detail.rb +74 -0
- data/lib/gooddata/models/membership.rb +1 -1
- data/lib/gooddata/models/metadata/attribute.rb +4 -6
- data/lib/gooddata/models/metadata/dashboard.rb +2 -0
- data/lib/gooddata/models/metadata/fact.rb +2 -2
- data/lib/gooddata/models/metadata/metric.rb +4 -1
- data/lib/gooddata/models/metadata/report.rb +84 -34
- data/lib/gooddata/models/metadata/report_definition.rb +28 -17
- data/lib/gooddata/models/metadata.rb +1 -1
- data/lib/gooddata/models/model.rb +1 -1
- data/lib/gooddata/models/process.rb +70 -54
- data/lib/gooddata/models/profile.rb +47 -10
- data/lib/gooddata/models/project.rb +74 -30
- data/lib/gooddata/models/project_blueprint.rb +9 -10
- data/lib/gooddata/models/project_builder.rb +2 -2
- data/lib/gooddata/models/project_creator.rb +4 -4
- data/lib/gooddata/models/report_data_result.rb +1 -1
- data/lib/gooddata/models/schedule.rb +39 -32
- data/lib/gooddata/models/to_manifest.rb +5 -5
- data/lib/gooddata/models/to_wire.rb +3 -3
- data/lib/gooddata/rest/client.rb +64 -31
- data/lib/gooddata/rest/connection.rb +7 -7
- data/lib/gooddata/rest/connections/dummy_connection.rb +5 -5
- data/lib/gooddata/rest/connections/rest_client_connection.rb +106 -44
- data/lib/gooddata/rest/object.rb +1 -1
- data/lib/gooddata/version.rb +1 -1
- data/spec/bricks/bricks_spec.rb +67 -0
- data/spec/bricks/default-config.json +8 -0
- data/spec/data/gooddata_version_process/gooddata_version.rb +3 -0
- data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
- data/spec/data/ruby_params_process/ruby_params.rb +3 -0
- data/spec/helpers/process_helper.rb +12 -0
- data/spec/helpers/schedule_helper.rb +21 -0
- data/spec/integration/create_project_spec.rb +19 -0
- data/spec/integration/full_process_schedule_spec.rb +129 -8
- data/spec/integration/full_project_spec.rb +52 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/core/rest_spec.rb +76 -3
- data/spec/unit/helpers_spec.rb +43 -0
- data/spec/unit/models/metric_spec.rb +33 -0
- data/spec/unit/models/params_spec.rb +96 -0
- data/spec/unit/models/profile_spec.rb +16 -0
- data/spec/unit/models/schedule_spec.rb +12 -3
- metadata +350 -187
- data/lib/gooddata/helper/class_helper.rb +0 -1
- data/lib/gooddata/helper/helpers.rb +0 -8
@@ -24,15 +24,15 @@ module GoodData
|
|
24
24
|
alias_method :to_table, :table
|
25
25
|
alias_method :without_column_headers, :table
|
26
26
|
|
27
|
-
def ==(
|
27
|
+
def ==(_other)
|
28
28
|
false
|
29
29
|
end
|
30
30
|
|
31
|
-
def diff(
|
31
|
+
def diff(_otherDataResult)
|
32
32
|
['empty']
|
33
33
|
end
|
34
34
|
|
35
|
-
def [](index,
|
35
|
+
def [](index, _options = {})
|
36
36
|
to_table[index]
|
37
37
|
end
|
38
38
|
|
@@ -46,11 +46,11 @@ module GoodData
|
|
46
46
|
table[index]
|
47
47
|
end
|
48
48
|
|
49
|
-
def include_row?(
|
49
|
+
def include_row?(_row = nil)
|
50
50
|
false
|
51
51
|
end
|
52
52
|
|
53
|
-
def include_column?(
|
53
|
+
def include_column?(_row = nil)
|
54
54
|
false
|
55
55
|
end
|
56
56
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative '../rest/resource'
|
4
|
+
require_relative '../extensions/hash'
|
5
|
+
|
6
|
+
module GoodData
|
7
|
+
class Execution < Rest::Resource
|
8
|
+
attr_reader :dirty, :json
|
9
|
+
|
10
|
+
alias_method :data, :json
|
11
|
+
alias_method :raw_data, :json
|
12
|
+
alias_method :to_hash, :json
|
13
|
+
|
14
|
+
# Initializes object instance from raw wire JSON
|
15
|
+
#
|
16
|
+
# @param json Json used for initialization
|
17
|
+
def initialize(json)
|
18
|
+
super
|
19
|
+
@json = json
|
20
|
+
end
|
21
|
+
|
22
|
+
# Timestamp when execution was created
|
23
|
+
def created
|
24
|
+
Time.parse(json['execution']['createdTime'])
|
25
|
+
end
|
26
|
+
|
27
|
+
# Data for execution
|
28
|
+
def data
|
29
|
+
@client.get(json['execution']['data'])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Has execution failed?
|
33
|
+
def error?
|
34
|
+
status == :error
|
35
|
+
end
|
36
|
+
|
37
|
+
# Timestamp when execution was finished
|
38
|
+
def finished
|
39
|
+
Time.parse(json['execution']['endTime'])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Log for execution
|
43
|
+
def log
|
44
|
+
@client.get(json['execution']['log'])
|
45
|
+
end
|
46
|
+
|
47
|
+
# Is execution ok?
|
48
|
+
def ok?
|
49
|
+
status == :ok
|
50
|
+
end
|
51
|
+
|
52
|
+
# Timestamp when execution was started
|
53
|
+
def started
|
54
|
+
Time.parse(json['execution']['startTime'])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Status of execution
|
58
|
+
def status
|
59
|
+
json['execution']['status'].downcase.to_sym
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns URL
|
63
|
+
#
|
64
|
+
# @return [String] Schedule URL
|
65
|
+
def uri
|
66
|
+
@json['execution']['links']['self'] if @json && @json['execution'] && @json['execution']['links']
|
67
|
+
end
|
68
|
+
|
69
|
+
# Compares two executions - based on their URI
|
70
|
+
def ==(other)
|
71
|
+
other.respond_to?(:uri) && other.uri == uri && other.respond_to?(:to_hash) && other.to_hash == to_hash
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative '../rest/resource'
|
4
|
+
require_relative '../extensions/hash'
|
5
|
+
|
6
|
+
module GoodData
|
7
|
+
class ExecutionDetail < Rest::Resource
|
8
|
+
attr_reader :dirty, :json
|
9
|
+
|
10
|
+
alias_method :data, :json
|
11
|
+
alias_method :raw_data, :json
|
12
|
+
alias_method :to_hash, :json
|
13
|
+
|
14
|
+
# Initializes object instance from raw wire JSON
|
15
|
+
#
|
16
|
+
# @param json Json used for initialization
|
17
|
+
def initialize(json)
|
18
|
+
super
|
19
|
+
@json = json
|
20
|
+
end
|
21
|
+
|
22
|
+
# Timestamp when execution was created
|
23
|
+
def created
|
24
|
+
Time.parse(json['executionDetail']['created'])
|
25
|
+
end
|
26
|
+
|
27
|
+
# Timestamp when execution was finished
|
28
|
+
def finished
|
29
|
+
Time.parse(json['executionDetail']['finished'])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Log for execution
|
33
|
+
def log
|
34
|
+
@client.get(json['executionDetail']['links']['log'])
|
35
|
+
end
|
36
|
+
|
37
|
+
# Filename of log
|
38
|
+
def log_filename
|
39
|
+
@client.get(json['executionDetail']['logFileName'])
|
40
|
+
end
|
41
|
+
|
42
|
+
# Is execution ok?
|
43
|
+
def ok?
|
44
|
+
status.downcase == 'ok'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Timestamp when execution was started
|
48
|
+
def started
|
49
|
+
Time.parse(json['executionDetail']['started'])
|
50
|
+
end
|
51
|
+
|
52
|
+
# Status of execution
|
53
|
+
def status
|
54
|
+
json['executionDetail']['status']
|
55
|
+
end
|
56
|
+
|
57
|
+
# Timestamp when execution was updated
|
58
|
+
def updated
|
59
|
+
Time.parse(json['executionDetail']['updated'])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns URL
|
63
|
+
#
|
64
|
+
# @return [String] Schedule URL
|
65
|
+
def uri
|
66
|
+
@json['executionDetail']['links']['self'] if @json && @json['executionDetail'] && @json['executionDetail']['links']
|
67
|
+
end
|
68
|
+
|
69
|
+
# Compares two executions - based on their URI
|
70
|
+
def ==(other)
|
71
|
+
other.respond_to?(:uri) && other.uri == uri && other.respond_to?(:to_hash) && other.to_hash == to_hash
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -56,12 +56,12 @@ module GoodData
|
|
56
56
|
def create_metric(options = {})
|
57
57
|
an_attribute = options[:attribute]
|
58
58
|
a_type = options[:type] || :count
|
59
|
-
fail "Suggested aggreagtion function (#{a_type}) does not exist for base metric created out of attribute. You can use only one of #{ATTRIBUTE_BASE_AGGREGATIONS.map { |x|
|
59
|
+
fail "Suggested aggreagtion function (#{a_type}) does not exist for base metric created out of attribute. You can use only one of #{ATTRIBUTE_BASE_AGGREGATIONS.map { |x| ':' + x.to_s }.join(',')}" unless ATTRIBUTE_BASE_AGGREGATIONS.include?(a_type)
|
60
60
|
a_title = options[:title] || "#{a_type} of #{title}"
|
61
61
|
if an_attribute
|
62
|
-
|
62
|
+
project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}], [#{an_attribute.uri}])", title: a_title, extended_notation: false)
|
63
63
|
else
|
64
|
-
|
64
|
+
project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}])", title: a_title, extended_notation: false)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -80,9 +80,7 @@ module GoodData
|
|
80
80
|
# @option options [Number] :limit limits the number of values to certain number. Default is 100
|
81
81
|
# @return [Array]
|
82
82
|
def values
|
83
|
-
results = labels.map
|
84
|
-
label.values
|
85
|
-
end
|
83
|
+
results = labels.map(&:values)
|
86
84
|
results.first.zip(*results[1..-1])
|
87
85
|
end
|
88
86
|
|
@@ -32,9 +32,9 @@ module GoodData
|
|
32
32
|
# @return [GoodData::Metric]
|
33
33
|
def create_metric(options = { :type => :sum })
|
34
34
|
a_type = options[:type] || :sum
|
35
|
-
fail "Suggested aggreagtion function (#{a_type}) does not exist for base metric created out of fact. You can use only one of #{FACT_BASE_AGGREGATIONS.map { |x|
|
35
|
+
fail "Suggested aggreagtion function (#{a_type}) does not exist for base metric created out of fact. You can use only one of #{FACT_BASE_AGGREGATIONS.map { |x| ':' + x.to_s }.join(',')}" unless FACT_BASE_AGGREGATIONS.include?(a_type)
|
36
36
|
a_title = options[:title] || "#{a_type} of #{title}"
|
37
|
-
|
37
|
+
project.create_metric("SELECT #{a_type.to_s.upcase}([#{uri}])", title: a_title, extended_notation: false)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -10,6 +10,8 @@ module GoodData
|
|
10
10
|
class Metric < MdObject
|
11
11
|
attr_reader :json
|
12
12
|
|
13
|
+
include GoodData::Mixin::Lockable
|
14
|
+
|
13
15
|
alias_method :to_hash, :json
|
14
16
|
|
15
17
|
include GoodData::Mixin::RestResource
|
@@ -28,7 +30,7 @@ module GoodData
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def xcreate(metric, options = { :client => GoodData.connection, :project => GoodData.project })
|
31
|
-
create(metric,
|
33
|
+
create(metric, { extended_notation: true }.merge(options))
|
32
34
|
end
|
33
35
|
|
34
36
|
def create(metric, options = { :client => GoodData.connection, :project => GoodData.project })
|
@@ -47,6 +49,7 @@ module GoodData
|
|
47
49
|
title = options[:title]
|
48
50
|
summary = options[:summary]
|
49
51
|
else
|
52
|
+
metric ||= options
|
50
53
|
title = metric[:title] || options[:title]
|
51
54
|
summary = metric[:summary] || options[:summary]
|
52
55
|
expression = metric[:expression] || options[:expression] || fail('Metric has to have its expression defined')
|
@@ -7,6 +7,8 @@ module GoodData
|
|
7
7
|
class Report < GoodData::MdObject
|
8
8
|
root_key :report
|
9
9
|
|
10
|
+
include GoodData::Mixin::Lockable
|
11
|
+
|
10
12
|
class << self
|
11
13
|
# Method intended to get all objects of that type in a specified project
|
12
14
|
#
|
@@ -63,51 +65,33 @@ module GoodData
|
|
63
65
|
self
|
64
66
|
end
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
# Gets a report definitions (versions) of this report as objects.
|
69
|
+
#
|
70
|
+
# @return [Array<GoodData::ReportDefinition>] Returns list of report definitions. Oldest comes first
|
70
71
|
def definitions
|
71
72
|
content['definitions'].pmap { |uri| project.report_definitions(uri) }
|
72
73
|
end
|
73
74
|
|
75
|
+
# Gets list of uris of report definitions (versions) of this report.
|
76
|
+
#
|
77
|
+
# @return [Array<String>] Returns list of report definitions' uris. Oldest comes first
|
74
78
|
def definition_uris
|
75
79
|
content['definitions']
|
76
80
|
end
|
77
81
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
def remove_definition(definition)
|
87
|
-
def_uri = is_a?(GoodData::ReportDefinition) ? definition.uri : definition
|
88
|
-
content['definitions'] = definition_uris.reject { |x| x == def_uri }
|
89
|
-
self
|
90
|
-
end
|
91
|
-
|
92
|
-
# TODO: Cover with test. You would probably need something that will be able to create a report easily from a definition
|
93
|
-
def remove_definition_but_latest
|
94
|
-
to_remove = definition_uris - [latest_report_definition_uri]
|
95
|
-
to_remove.each do |uri|
|
96
|
-
remove_definition(uri)
|
97
|
-
end
|
98
|
-
self
|
99
|
-
end
|
100
|
-
|
101
|
-
def purge_report_of_unused_definitions!
|
102
|
-
full_list = definition_uris
|
103
|
-
remove_definition_but_latest
|
104
|
-
purged_list = definition_uris
|
105
|
-
to_remove = full_list - purged_list
|
106
|
-
save
|
107
|
-
to_remove.each { |uri| client.delete(uri) }
|
82
|
+
# Deletes report along with its report definitions.
|
83
|
+
#
|
84
|
+
# @return [GoodData::Report] Returns self
|
85
|
+
def delete
|
86
|
+
defs = definitions
|
87
|
+
super
|
88
|
+
defs.peach(&:delete)
|
108
89
|
self
|
109
90
|
end
|
110
91
|
|
92
|
+
# Computes the report and returns the result. If it is not computable returns nil.
|
93
|
+
#
|
94
|
+
# @return [GoodData::DataResult] Returns the result
|
111
95
|
def execute
|
112
96
|
fail 'You have to save the report before executing. If you do not want to do that please use GoodData::ReportDefinition' unless saved?
|
113
97
|
result = client.post '/gdc/xtab2/executor3', 'report_req' => { 'report' => uri }
|
@@ -124,21 +108,87 @@ module GoodData
|
|
124
108
|
end
|
125
109
|
end
|
126
110
|
|
111
|
+
# Returns true if you can export and object
|
112
|
+
#
|
113
|
+
# @return [Boolean] Returns whether the report is exportable
|
127
114
|
def exportable?
|
128
115
|
true
|
129
116
|
end
|
130
117
|
|
118
|
+
# Returns binary data of the exported report in a given format. The format can be
|
119
|
+
# either 'csv', 'xls', 'xlsx' or 'pdf'.
|
120
|
+
#
|
121
|
+
# @return [String] Returns data
|
131
122
|
def export(format)
|
132
123
|
result = GoodData.post('/gdc/xtab2/executor3', 'report_req' => { 'report' => uri })
|
133
124
|
result1 = GoodData.post('/gdc/exporter/executor', :result_req => { :format => format, :result => result })
|
134
125
|
GoodData.poll_on_code(result1['uri'], process: false)
|
135
126
|
end
|
136
127
|
|
128
|
+
# Returns the newest (current version) report definition uri
|
129
|
+
#
|
130
|
+
# @return [String] Returns uri of the newest report defintion
|
131
|
+
def latest_report_definition_uri
|
132
|
+
definition_uris.last
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns the newest (current version) report definition as an object
|
136
|
+
#
|
137
|
+
# @return [GoodData::ReportDefinition] Returns the newest report defintion
|
138
|
+
def latest_report_definition
|
139
|
+
project.report_definitions(latest_report_definition_uri)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns the newest (current version) report definition uri
|
143
|
+
#
|
144
|
+
# @return [String] Returns uri of the newest report defintion
|
145
|
+
def purge_report_of_unused_definitions!
|
146
|
+
full_list = definition_uris
|
147
|
+
remove_definition_but_latest
|
148
|
+
purged_list = definition_uris
|
149
|
+
to_remove = full_list - purged_list
|
150
|
+
save
|
151
|
+
to_remove.each { |uri| client.delete(uri) }
|
152
|
+
self
|
153
|
+
end
|
154
|
+
|
155
|
+
# Removes definition from the report. The definition to remove can be passed in any form that is accepted by
|
156
|
+
# GoodData::ReportDefintion[]
|
157
|
+
#
|
158
|
+
# @param definition [String | GoodData::ReportDefinition] Report defintion to remove
|
159
|
+
# @return [GoodData::Report] Returns report with removed definition
|
160
|
+
def remove_definition(definition)
|
161
|
+
a_def = GoodData::ReportDefinition(definition, project: project, client: client)
|
162
|
+
def_uri = a_def.uri
|
163
|
+
content['definitions'] = definition_uris.reject { |x| x == def_uri }
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
# TODO: Cover with test. You would probably need something that will be able to create a report easily from a definition
|
168
|
+
# Removes all definitions but the latest from the report. This is useful for cleaning up before you create
|
169
|
+
# a template out of a project.
|
170
|
+
#
|
171
|
+
# @return [GoodData::Report] Returns report with removed definitions
|
172
|
+
def remove_definition_but_latest
|
173
|
+
to_remove = definition_uris - [latest_report_definition_uri]
|
174
|
+
to_remove.each do |uri|
|
175
|
+
remove_definition(uri)
|
176
|
+
end
|
177
|
+
self
|
178
|
+
end
|
179
|
+
|
180
|
+
# Replaces all occurences of something with something else. This is just a convenience method. The
|
181
|
+
# real work is done under the hood in report definition. This is just deferring to those
|
182
|
+
#
|
183
|
+
# @param what [Object] What you would like to have changed
|
184
|
+
# @param for_what [Object] What you would like to have changed this for
|
185
|
+
# @return [GoodData::Report] Returns report with removed definition
|
137
186
|
def replace(what, for_what)
|
138
187
|
new_defs = definitions.map do |rep_def|
|
139
188
|
rep_def.replace(what, for_what)
|
140
189
|
end
|
141
190
|
new_defs.pmap(&:save)
|
191
|
+
self
|
142
192
|
end
|
143
193
|
end
|
144
194
|
end
|
@@ -72,7 +72,10 @@ module GoodData
|
|
72
72
|
fail "Object given by id \"#{item}\" could not be found" if x.nil?
|
73
73
|
case x.raw_data.keys.first.to_s
|
74
74
|
when 'attribute'
|
75
|
-
GoodData::Attribute.new(x.json)
|
75
|
+
attr = GoodData::Attribute.new(x.json)
|
76
|
+
attr.client = client
|
77
|
+
attr.project = opts[:project]
|
78
|
+
attr.display_forms.first
|
76
79
|
when 'attributeDisplayForm'
|
77
80
|
GoodData::Label.new(x.json)
|
78
81
|
when 'metric'
|
@@ -117,11 +120,11 @@ module GoodData
|
|
117
120
|
|
118
121
|
metrics = (left + top).select { |item| item.respond_to?(:metric?) && item.metric? }
|
119
122
|
|
120
|
-
unsaved_metrics = metrics.reject
|
123
|
+
unsaved_metrics = metrics.reject(&:saved?)
|
121
124
|
unsaved_metrics.each { |m| m.title = 'Untitled metric' unless m.title }
|
122
125
|
|
123
126
|
begin
|
124
|
-
unsaved_metrics.each
|
127
|
+
unsaved_metrics.each(&:save)
|
125
128
|
rd = GoodData::ReportDefinition.create(options)
|
126
129
|
data_result(execute_inline(rd, options), options)
|
127
130
|
ensure
|
@@ -131,13 +134,7 @@ module GoodData
|
|
131
134
|
|
132
135
|
def execute_inline(rd, opts = { :client => GoodData.connection, :project => GoodData.project })
|
133
136
|
client = opts[:client]
|
134
|
-
|
135
|
-
|
136
|
-
p = opts[:project]
|
137
|
-
fail ArgumentError, 'No :project specified' if p.nil?
|
138
|
-
|
139
|
-
project = GoodData::Project[p, opts]
|
140
|
-
fail ArgumentError, 'Wrong :project specified' if project.nil?
|
137
|
+
project = opts[:project]
|
141
138
|
|
142
139
|
rd = rd.respond_to?(:json) ? rd.json : rd
|
143
140
|
data = {
|
@@ -191,7 +188,7 @@ module GoodData
|
|
191
188
|
|
192
189
|
# TODO: Put somewhere for i18n
|
193
190
|
fail_msg = 'All metrics in report definition must be saved'
|
194
|
-
fail fail_msg unless (left + top).all?
|
191
|
+
fail fail_msg unless (left + top).all?(&:saved?)
|
195
192
|
|
196
193
|
pars = {
|
197
194
|
'reportDefinition' => {
|
@@ -231,7 +228,16 @@ module GoodData
|
|
231
228
|
end
|
232
229
|
|
233
230
|
def attributes
|
234
|
-
labels.map
|
231
|
+
labels.map(&:attribute)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Removes the color mapping from report definition
|
235
|
+
#
|
236
|
+
# @return [GoodData::ReportDefinition] Returns self
|
237
|
+
def reset_color_mapping!
|
238
|
+
global_chart_options = GoodData::Helpers.get_path(content, %w(chart styles global))
|
239
|
+
global_chart_options['colorMapping'] = [] if global_chart_options
|
240
|
+
self
|
235
241
|
end
|
236
242
|
|
237
243
|
def labels
|
@@ -247,16 +253,21 @@ module GoodData
|
|
247
253
|
end
|
248
254
|
|
249
255
|
def execute(opts = { :client => GoodData.connection, :project => GoodData.project })
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
256
|
+
client = opts[:client]
|
257
|
+
fail ArgumentError, 'No :client specified' if client.nil?
|
258
|
+
|
259
|
+
p = opts[:project]
|
260
|
+
fail ArgumentError, 'No :project specified' if p.nil?
|
261
|
+
|
262
|
+
project = client.projects(p)
|
263
|
+
fail ArgumentError, 'Wrong :project specified' if project.nil?
|
254
264
|
|
265
|
+
opts = { client: client, project: project }
|
255
266
|
result = if saved?
|
256
267
|
pars = {
|
257
268
|
'report_req' => { 'reportDefinition' => uri }
|
258
269
|
}
|
259
|
-
client.post '/gdc/xtab2/
|
270
|
+
client.post '/gdc/xtab2/executor3', pars
|
260
271
|
else
|
261
272
|
ReportDefinition.execute_inline(self, opts)
|
262
273
|
end
|
@@ -120,7 +120,7 @@ module GoodData
|
|
120
120
|
body['taskStatus'] == 'RUNNING' || body['taskStatus'] == 'PREPARED'
|
121
121
|
end
|
122
122
|
|
123
|
-
if res['taskStatus'] == 'ERROR'
|
123
|
+
if res['taskStatus'] == 'ERROR' # rubocop:disable Style/GuardClause
|
124
124
|
s = StringIO.new
|
125
125
|
client.download_from_user_webdav(File.basename(dir) + '/upload_status.json', s)
|
126
126
|
js = MultiJson.load(s.string)
|