Class: GoodData::Report

Inherits:
MdObject show all
Includes:
Mixin::Lockable
Defined in:
lib/gooddata/models/metadata/report.rb

Constant Summary

Constants inherited from MdObject

MdObject::IDENTIFIERS_CFG, MdObject::MD_OBJ_CTG

Constants included from Mixin::MdIdToUri

Mixin::MdIdToUri::IDENTIFIERS_CFG

Constants included from Mixin::MdObjectIndexer

Mixin::MdObjectIndexer::MD_OBJ_CTG

Constants included from Mixin::MdObjectQuery

Mixin::MdObjectQuery::ERROR_MESSAGE_NO_PROJECT

Instance Attribute Summary

Attributes inherited from GoodData::Rest::Object

#client, #json, #project

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::Lockable

#lock, #lock!, #lock_with_dependencies!, #locked?, #unlock, #unlock!, #unlock_with_dependencies!, #unlocked?

Methods inherited from MdObject

#==, #add_tag, #browser_uri, #deprecated, #deprecated=, find_replaceable_values, #get_flag?, #initialize, #listed?, #production, #production=, #project, #reload!, #remove_tag, replace, #replace!, replace_bracketed, replace_quoted, #restricted, #restricted=, #save, #save_as, #set_flag, #tag_set, #unlisted, #unlisted=, #validate

Methods included from Mixin::MdIdToUri

#identifier_to_uri

Methods included from Mixin::MdObjectIndexer

#[]

Methods included from Mixin::MdObjectQuery

#all, #dependency, #dependency?, #query, #usedby, #usedby?, #using, #using?

Methods included from Mixin::MdFinders

#find_by_identifier, #find_by_tag, #find_by_title, #find_first_by_identifier, #find_first_by_title

Methods included from Mixin::MdObjId

#uri_obj_id

Methods included from Mixin::MdGrantees

#change_permission, #grant, #grantees, #revoke

Methods included from Mixin::MdRelations

#dependency, #dependency?, #usedby, #usedby?, #using, #using?

Methods included from Mixin::ObjId

#obj_id

Methods included from Mixin::Links

#links

Methods inherited from GoodData::Rest::Resource

#initialize

Methods inherited from GoodData::Rest::Object

client, default_client, #initialize, #saved?

Methods included from Mixin::DataPropertyReader

#data_property_reader

Methods included from Mixin::DataPropertyWriter

#data_property_writer

Methods included from Mixin::MetaPropertyReader

#metadata_property_reader

Methods included from Mixin::MetaPropertyWriter

#metadata_property_writer

Methods included from Mixin::MetaGetter

#meta

Methods included from Mixin::DataGetter

#data

Methods included from Mixin::RootKeyGetter

#root_key

Methods included from Mixin::ContentGetter

#content

Constructor Details

This class inherits a constructor from GoodData::MdObject

Class Method Details

.all(options = { :client => GoodData.connection, :project => GoodData.project }) ⇒ Array<GoodData::MdObject> | Array<Hash>

Method intended to get all objects of that type in a specified project

to pull in full objects. This is desirable from the usability POV but unfortunately has negative impact on performance so it is not the default.

Parameters:

  • options (Hash) (defaults to: { :client => GoodData.connection, :project => GoodData.project })

    the options hash

Options Hash (options):

  • :full (Boolean)

    if passed true the subclass can decide

Returns:

  • (Array<GoodData::MdObject> | Array<Hash>)

    Return the appropriate metadata objects or their representation



23
24
25
# File 'lib/gooddata/models/metadata/report.rb', line 23

def all(options = { :client => GoodData.connection, :project => GoodData.project })
  query('report', Report, options)
end

.create(options = { :client => GoodData.connection, :project => GoodData.project }) ⇒ Object



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
# File 'lib/gooddata/models/metadata/report.rb', line 27

def create(options = { :client => GoodData.connection, :project => GoodData.project })
  client, project = GoodData.get_client_and_project(options)

  title = options[:title]
  fail 'Report needs a title specified' unless title
  summary = options[:summary] || ''

  options_rd = options.dup
  options_rd.delete(:identifier)

  rd = options[:rd] || ReportDefinition.create(options_rd)
  rd.save

  report = {
    'report' => {
      'content' => {
        'domains' => [],
        'definitions' => [rd.uri]
      },
      'meta' => {
        'tags' => '',
        'deprecated' => '0',
        'summary' => summary,
        'title' => title
      }
    }
  }
  # TODO: write test for report definitions with explicit identifiers
  report['report']['meta']['identifier'] = options[:identifier] if options[:identifier]
  client.create(Report, report, :project => project)
end

.data_result(result, options = {}) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/gooddata/models/metadata/report.rb', line 59

def data_result(result, options = {})
  client = options[:client]
  data_result_uri = result['execResult']['dataResult']
  begin
    result = client.poll_on_response(data_result_uri, options) do |body|
      body && body['taskState'] && body['taskState']['status'] == 'WAIT'
    end
  rescue RestClient::BadRequest => e
    resp = JSON.parse(e.response)
    if GoodData::Helpers.get_path(resp, %w(error component)) == 'MD::DataResult'
      raise GoodData::UncomputableReport
    else
      raise e
    end
  end

  if result.to_s.empty?
    ReportDataResult.new(data: [], top: 0, left: 0)
  else
    ReportDataResult.from_xtab(result)
  end
end

Instance Method Details

#add_definition(report_definition) ⇒ GoodData::Report

Add a report definition to a report. This will show on a UI as a new version.

Parameters:

  • report_definition (GoodData::ReportDefinition | String)

    Report definition to add. Either it can be a URI of a report definition or an actual report definition object.

Returns:



87
88
89
90
91
# File 'lib/gooddata/models/metadata/report.rb', line 87

def add_definition(report_definition)
  rep_def = project.report_definitions(report_definition)
  content['definitions'] = definition_uris << rep_def.uri
  self
end

#add_definition!(report_definition) ⇒ GoodData::Report

Add a report definition to a report. This will show on a UI as a new version.

Parameters:

  • report_definition (GoodData::ReportDefinition | String)

    Report definition to add. Either it can be a URI of a report definition or an actual report definition object.

Returns:



97
98
99
100
# File 'lib/gooddata/models/metadata/report.rb', line 97

def add_definition!(report_definition)
  res = add_definition(report_definition)
  res.save
end

#definitionGoodData::ReportDefinition Also known as: latest_report_definition

Returns the newest (current version) report definition as an object

Returns:



105
106
107
# File 'lib/gooddata/models/metadata/report.rb', line 105

def definition
  project.report_definitions(latest_report_definition_uri)
end

#definition_uriString Also known as: latest_report_definition_uri

Returns the newest (current version) report definition uri

Returns:

  • (String)

    Returns uri of the newest report defintion



114
115
116
# File 'lib/gooddata/models/metadata/report.rb', line 114

def definition_uri
  definition_uris.last
end

#definition_urisArray<String>

Gets list of uris of report definitions (versions) of this report.

Returns:

  • (Array<String>)

    Returns list of report definitions' uris. Oldest comes first



131
132
133
# File 'lib/gooddata/models/metadata/report.rb', line 131

def definition_uris
  content['definitions']
end

#definitionsArray<GoodData::ReportDefinition> Also known as: report_definitions

Gets a report definitions (versions) of this report as objects.

Returns:



123
124
125
# File 'lib/gooddata/models/metadata/report.rb', line 123

def definitions
  content['definitions'].pmap { |uri| project.report_definitions(uri) }
end

#deleteGoodData::Report

Deletes report along with its report definitions.

Returns:



138
139
140
141
142
143
# File 'lib/gooddata/models/metadata/report.rb', line 138

def delete
  defs = definitions
  super
  defs.peach(&:delete)
  self
end

#execute(options = {}) ⇒ GoodData::DataResult

Computes the report and returns the result. If it is not computable returns nil.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :time (Time)

    Force the platform to simutale the result at this time

Returns:

  • (GoodData::DataResult)

    Returns the result



149
150
151
152
153
154
155
156
157
158
# File 'lib/gooddata/models/metadata/report.rb', line 149

def execute(options = {})
  time = options[:time]

  report_req = { 'report' => uri }
  report_req['timestamp'] = time.to_i if time

  fail 'You have to save the report before executing. If you do not want to do that please use GoodData::ReportDefinition' unless saved?
  result = client.post "/gdc/projects/#{project.pid}/execute", 'report_req' => report_req
  GoodData::Report.data_result(result, options.merge(client: client))
end

#export(format, options = {}) ⇒ String

Returns binary data of the exported report in a given format. The format can be either 'csv', 'xls', 'xlsx' or 'pdf'.

Returns:

  • (String)

    Returns data



171
172
173
174
175
# File 'lib/gooddata/models/metadata/report.rb', line 171

def export(format, options = {})
  result = client.post("/gdc/projects/#{project.pid}/execute", 'report_req' => { 'report' => uri })
  result1 = client.post('/gdc/exporter/executor', :result_req => { :format => format, :result => result })
  client.poll_on_code(result1['uri'], options.merge(process: false))
end

#export_raw(filename) ⇒ Net::HTTPResponse

Exports a report too large to be computed on the UI. It executes in raw form. Saves the result into file.

Parameters:

  • filename (String)

    Filename to save into

Returns:

  • (Net::HTTPResponse)

    Returns HTTP status



182
183
184
185
# File 'lib/gooddata/models/metadata/report.rb', line 182

def export_raw(filename)
  result = client.post("/gdc/app/projects/#{project.pid}/execute/raw", 'report_req' => { 'report' => uri })
  client.download(result['uri'], filename, url_encode: false)
end

#exportable?Boolean

Returns true if you can export and object

Returns:

  • (Boolean)

    Returns whether the report is exportable



163
164
165
# File 'lib/gooddata/models/metadata/report.rb', line 163

def exportable?
  true
end

#purge_report_of_unused_definitions!String

Returns the newest (current version) report definition uri

Returns:

  • (String)

    Returns uri of the newest report defintion



190
191
192
193
194
195
196
197
198
# File 'lib/gooddata/models/metadata/report.rb', line 190

def purge_report_of_unused_definitions!
  full_list = definition_uris
  remove_definition_but_latest
  purged_list = definition_uris
  to_remove = full_list - purged_list
  save
  to_remove.each { |uri| client.delete(uri) }
  self
end

#remove_definition(definition) ⇒ GoodData::Report

Removes definition from the report. The definition to remove can be passed in any form that is accepted by GoodData::ReportDefintion[]

Parameters:

Returns:



205
206
207
208
209
210
# File 'lib/gooddata/models/metadata/report.rb', line 205

def remove_definition(definition)
  a_def = GoodData::ReportDefinition[definition, project: project, client: client]
  def_uri = a_def.uri
  content['definitions'] = definition_uris.reject { |x| x == def_uri }
  self
end

#remove_definition_but_latestGoodData::Report

TODO: Cover with test. You would probably need something that will be able to create a report easily from a definition Removes all definitions but the latest from the report. This is useful for cleaning up before you create a template out of a project.

Returns:



217
218
219
220
221
222
223
# File 'lib/gooddata/models/metadata/report.rb', line 217

def remove_definition_but_latest
  to_remove = definition_uris - [latest_report_definition_uri]
  to_remove.each do |uri|
    remove_definition(uri)
  end
  self
end

#replace(mapping) ⇒ GoodData::Report

Method used for replacing values in their state according to mapping. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.

Parameters:

  • Mapping (Array<Array>)

    specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.

Returns:



231
232
233
234
235
236
237
# File 'lib/gooddata/models/metadata/report.rb', line 231

def replace(mapping)
  new_defs = definitions.map do |rep_def|
    rep_def.replace(mapping)
  end
  new_defs.pmap(&:save)
  self
end

#update_definition(opts = { :new_definition => true }, &block) ⇒ GoodData::ReportDefinition

Update report definition and reflect the change in report

Parameters:

  • opts (Hash) (defaults to: { :new_definition => true })

    Options

Options Hash (opts):

  • :new_definition (Boolean) — default: true

    If true then new definition will be created

Returns:



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/gooddata/models/metadata/report.rb', line 244

def update_definition(opts = { :new_definition => true }, &block)
  # TODO: Cache the latest report definition somehow
  repdef = definition.dup

  block.call(repdef, self) if block_given?

  if opts[:new_definition]
    new_def = GoodData::ReportDefinition.create(:client => client, :project => project)

    rd = repdef.json['reportDefinition']
    rd.delete('links')
    %w(author uri created identifier updated contributor).each { |k| rd['meta'].delete(k) }
    new_def.json['reportDefinition'] = rd
    new_def.save

    add_definition!(new_def)
    return new_def
  else
    repdef.save
  end

  repdef
end