gooddata 0.6.18 → 0.6.19

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f683852cdcca1c3ac58923b66d2875199f4941ca
4
- data.tar.gz: c439059752871aa8edaaae9578ebb5d8070d055a
3
+ metadata.gz: a4de3a73d002c9131adae8968162b567827d1f67
4
+ data.tar.gz: 3e62ac57287eeafe59581fb23d898eea5bdefc12
5
5
  SHA512:
6
- metadata.gz: 7645abe267313b36bcc9f5d9ae076be9a7b608860db6a7bd27a91919dab47af0e31d3a48a921521d546f28fe822312ff69007826886447ea0dd165b170f7e5bb
7
- data.tar.gz: 319d48cffc079ce239e78ff4b8ab4d2c3911a5fb381a13d47fb8d91f58e7947dab7d7bbed9fbfa44a97d87689f6b1f3340612246a59c8ffcec581109e69c1765
6
+ metadata.gz: 7af60ede0582d91dbdb136e95a530f7a43fe61a721ed08bd78a09705c0d0dac6db2e80d0adfdc70366c6504f869dd8ab7b52e1c6148334a3f8753a7d2745f05f
7
+ data.tar.gz: b5f8f8c12e55ff4a4ca484a8d5b076d317940e8ea9776427366af06a80a90bc81d0ddcf4d3e58103be5314defb1968428137af81df153fa5fe7dac9e2c1b35a5
data/.gitignore CHANGED
@@ -19,7 +19,8 @@ tmtags
19
19
  ## PROJECT::GENERAL
20
20
  .bundle
21
21
  coverage
22
- rdoc
22
+ /rdoc
23
+ /doc
23
24
  pkg
24
25
 
25
26
  ## PROJECT::SPECIFIC
@@ -1,33 +1,22 @@
1
1
  language: ruby
2
-
3
2
  cache: bundler
4
-
5
3
  sudo: false
6
-
7
4
  branches:
8
5
  except:
9
6
  - gh-pages
10
7
  - next_doc_release
11
8
  env:
12
9
  global:
13
- - secure: d/fE2Iuyrf5mfvQPe2nl++a06hpy82mEM5jbmXmS1ttQgMpf955GWTmZ+16VBZa9MU2pJLBXoBXy53tp8P9ADysE4R7YCeI68yE0CZ/OuU+FVADZ9/F6i4nlUESjNNQnlC0mTIjDMO5WI9HbVQiS07HqDHzr6bcS51ZvBzItcn4=
14
10
  - TRAVIS_BUILD=true
15
-
11
+ - secure: XIcBVui9577vRAtz23JoM9ZDSol4sY3XC0GP3kH4/fRnmf/zoYS3OmkfFUZ484RS2YmLPuSQvSfwaobRkYCnuc6iFNCEZD1Bxr7f1BT1rc5Sb9PZTdNBIHORnWimFcanGsTERWJiocCShL8miuTF3l1P0JAsjXoeVWI82oMz7xE=
16
12
  rvm:
17
- - 1.9.3
18
- - jruby-19mode
19
- - 2.1
20
- - 2.2
21
-
13
+ - 1.9.3
14
+ - jruby-19mode
15
+ - 2.1
16
+ - 2.2
22
17
  before_install:
23
- - gem update --system
24
- - gem update bundler
25
-
18
+ - gem update --system
19
+ - gem update bundler
26
20
  before_script:
27
- - cp spec/data/.gooddata ~/
28
-
21
+ - cp spec/data/.gooddata ~/
29
22
  script: bundle exec rake ci
30
-
31
- notifications:
32
- slack:
33
- secure: VIiymls7MDsR+3TeICWA41+uK4WAfe+CaNZhMvC/9Z/uWrPD9EsH7sX/GT2GoPJdjj7wCzTjWMy5fQOwY243cXu17umkTRHKYYhZYPjhGi4X0Diqjdx7A/eKieIUMS2xGb12a40HTPIB5Owc2+8C+sOPRk5AXRR/YrOB5xG61y8=
@@ -0,0 +1,5 @@
1
+ clearing :on
2
+
3
+ guard :rspec, cmd: 'bundle exec rspec' do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ end
data/README.md CHANGED
@@ -5,12 +5,10 @@ It has a CLI client and it is a library which you can integrate into your applic
5
5
 
6
6
  The best documentation for the GoodData API can be found using these resources:
7
7
 
8
- * http://sdk.gooddata.com/gooddata-ruby/
9
- * http://docs.gooddata.apiary.io/
8
+ * http://sdk.gooddata.com/gooddata-ruby-examples/
10
9
  * http://developer.gooddata.com/api
11
10
  * https://secure.gooddata.com/gdc
12
11
  * http://rubydoc.info/gems/gooddata/frames
13
- * http://developer.gooddata.com/ruby-cookbook
14
12
 
15
13
  ## Status
16
14
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "gooddata/cli/cli"
3
+ require_relative '../lib/gooddata/cli/cli'
4
4
 
5
5
  res = GoodData::CLI.main(ARGV)
6
6
 
@@ -29,13 +29,15 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'rake-notes', '~> 0.2', '>= 0.2.0'
30
30
  s.add_development_dependency 'redcarpet', '~> 3.1', '>= 3.1.1' if RUBY_PLATFORM != 'java'
31
31
  s.add_development_dependency 'rspec', '~> 2.14', '>= 2.14.1'
32
- s.add_development_dependency 'rubocop', '~> 0.27', '>= 0.27.0'
32
+ s.add_development_dependency 'rubocop', '~> 0.32.1', '>= 0.32.1'
33
33
  s.add_development_dependency 'simplecov', '~> 0.9', '>= 0.9.1'
34
34
  s.add_development_dependency 'yard', '~> 0.8.7.3'
35
35
  s.add_development_dependency 'yard-rspec', '~> 0.1'
36
36
  s.add_development_dependency 'ZenTest', '~> 4.10', '>= 4.11.0'
37
37
  s.add_development_dependency 'coveralls', '~> 0.7', '>= 0.7.0'
38
-
38
+ s.add_development_dependency 'guard', '~> 2'
39
+ s.add_development_dependency 'guard-rspec', '~> 4'
40
+ s.add_development_dependency 'webmock', '~> 1.21.0'
39
41
  s.add_development_dependency 'debase' if !ENV['TRAVIS_BUILD'] && RUBY_VERSION >= '2.0.0'
40
42
  s.add_development_dependency 'ruby-debug-ide' if !ENV['TRAVIS_BUILD'] && RUBY_VERSION >= '2.0.0'
41
43
 
@@ -52,9 +54,9 @@ Gem::Specification.new do |s|
52
54
  s.add_dependency 'pmap', '~> 1.0', '>= 1.0.1'
53
55
  s.add_dependency 'pry', '~> 0.9.12.6' # '~> 0.10', '>= 0.10.1'
54
56
  s.add_dependency 'restforce', '~> 1.5', '>= 1.5.0'
55
- s.add_dependency 'rest-client', '~> 1.7', '>= 1.7.2'
57
+ s.add_dependency 'rest-client', '~> 1.7.2', '>= 1.7.2'
56
58
  s.add_dependency 'rubyzip', '~> 1.1', '>= 1.1.0'
57
- s.add_dependency 'terminal-table', '~> 1.4', '>= 1.4.5'
59
+ s.add_dependency 'terminal-table', '~> 1.5', '>= 1.5.1'
58
60
  s.add_dependency 'salesforce_bulk_query', '~> 0.0'
59
61
  s.add_dependency 'aws-sdk', '~> 1.45'
60
62
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'pmap'
4
- $pmap_default_thread_count = 100 # rubocop:disable GlobalVars
4
+ $pmap_default_thread_count = 20 # rubocop:disable GlobalVars
5
5
 
6
6
  # GoodData Module
7
7
  module GoodData
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'aws-sdk'
4
+ require_relative 'base_middleware'
5
+
6
+ module GoodData
7
+ module Bricks
8
+ class AWSMiddleware < Bricks::Middleware
9
+ def call(params)
10
+ if params.key?('aws_client')
11
+ puts 'Setting up AWS-S3 connection'
12
+ fail "Unable to connect to AWS. Parameter \"aws_client\" seems to be empty" unless params['aws_client']
13
+ fail "Unable to connect to AWS. Parameter \"access_key_id\" is missing" if params['aws_client']['access_key_id'].blank?
14
+ fail "Unable to connect to AWS. Parameter \"secret_access_key\" is missing" if params['aws_client']['secret_access_key'].blank?
15
+ s3 = AWS::S3.new(params['aws_client'])
16
+ params['aws_client']['s3_client'] = s3
17
+ @app.call(params)
18
+ else
19
+ @app.call(params)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -25,7 +25,7 @@ GoodData::CLI.module_eval do
25
25
  fail ArgumentError, 'Wrong project specified' if project.nil?
26
26
 
27
27
  puts "Use 'exit' to quit the live session. Use 'q' to jump out of displaying a large output."
28
- binding.pry(:quiet => true,
28
+ binding.pry(:quiet => true, # rubocop:disable Lint/Debugger
29
29
  :prompt => [proc do |_target_self, _nest_level, _pry|
30
30
  'sdk_live_session: '
31
31
  end])
@@ -21,22 +21,42 @@ GoodData::CLI.module_eval do
21
21
  # TODO: Move away the ask methods. Provide params
22
22
  c.desc 'Create a gooddata project'
23
23
  c.command :create do |create|
24
+ create.default_value nil
25
+ create.arg_name :driver
26
+ create.flag [:driver]
27
+
28
+ create.default_value nil
29
+ create.arg_name :template
30
+ create.flag [:template]
31
+
32
+ create.default_value nil
33
+ create.arg_name :summary
34
+ create.flag [:summary]
35
+
24
36
  create.action do |global_options, options, args|
25
37
  opts = options.merge(global_options)
26
38
 
27
39
  title = args[0] || ask('Project name')
28
- summary = args[1] || ask('Project summary') { |q| q.default = '' }
29
- template = args[2] || ask('Project template')
30
- token = opts[:token] || ask('token')
40
+ summary = opts[:summary] || args[1] || ask('Project summary') { |q| q.default = '' }
41
+ template = opts[:template] || args[2] || ask('Project template')
42
+ token = opts['token'] || ask('Token')
43
+ driver = opts[:driver] || ask('Driver') { |q| q.default = 'Pg' }
31
44
 
32
45
  opts = options.merge(global_options)
33
46
  client = GoodData.connect(opts)
34
- project = GoodData::Command::Project.create(
35
- :title => title,
36
- :summary => summary,
37
- :template => template,
38
- :token => token,
39
- client: client)
47
+ begin
48
+ project = GoodData::Command::Project.create(
49
+ :title => title,
50
+ :summary => summary,
51
+ :template => template,
52
+ :token => token,
53
+ :driver => driver,
54
+ client: client)
55
+ rescue => e
56
+ puts "Error creating project, reason: #{e.inspect}"
57
+ raise e
58
+ end
59
+
40
60
  puts "Project '#{project.title}' with id #{project.pid} created successfully!"
41
61
  end
42
62
  end
@@ -17,11 +17,17 @@ GoodData::CLI.module_eval do
17
17
 
18
18
  username = creds[:username] if username.nil?
19
19
  password = creds[:password] if password.nil?
20
- token = creds[:auth_token] if token.nil?
20
+ token = creds[:auth_token] || creds[:token] if token.nil?
21
21
 
22
22
  global[:token] = token if global[:token].nil?
23
- global[:login] = username if global[:login].nil?
24
- global[:password] = password if global[:password].nil?
23
+ if global[:login].nil?
24
+ global[:login] = username
25
+ global['login'] = username
26
+ end
27
+ if global[:password].nil?
28
+ global[:password] = password
29
+ global['password'] = password
30
+ end
25
31
  # Pre logic here
26
32
  # Return true to proceed; false to abort and not call the
27
33
  # chosen command
@@ -7,14 +7,8 @@ module GoodData
7
7
  class << self
8
8
  # Create new project based on options supplied
9
9
  def create(options = { client: GoodData.connection })
10
- title = options[:title]
11
10
  description = options[:summary] || options[:description]
12
- token = options[:token] || options[:auth_token]
13
- client = options[:client]
14
- GoodData::DataWarehouse.create(:title => title,
15
- :description => description,
16
- :auth_token => token,
17
- :client => client)
11
+ GoodData::DataWarehouse.create(options.merge(:description => description))
18
12
  end
19
13
  end
20
14
  end
@@ -13,7 +13,8 @@ module GoodData
13
13
  template = options[:template]
14
14
  token = options[:token]
15
15
  client = options[:client]
16
- GoodData::Project.create(:title => title, :summary => summary, :template => template, :auth_token => token, :client => client)
16
+ driver = options[:driver] || 'Pg'
17
+ GoodData::Project.create(:title => title, :summary => summary, :template => template, :auth_token => token, :client => client, :driver => driver)
17
18
  end
18
19
 
19
20
  # Show existing project
@@ -91,7 +92,7 @@ module GoodData
91
92
  client = opts[:client]
92
93
  fail ArgumentError, 'No :client specified' if client.nil?
93
94
 
94
- GoodData::Model::ProjectCreator.migrate(:spec => opts[:spec], :token => opts[:token], :client => client)
95
+ GoodData::Model::ProjectCreator.migrate(opts.merge(:client => client))
95
96
  end
96
97
 
97
98
  # Performs project validation
@@ -124,7 +125,7 @@ module GoodData
124
125
  fail ArgumentError, 'Wrong project specified' if project.nil?
125
126
 
126
127
  puts "Use 'exit' to quit the live session. Use 'q' to jump out of displaying a large output."
127
- binding.pry(:quiet => true,
128
+ binding.pry(:quiet => true, # rubocop:disable Lint/Debugger
128
129
  :prompt => [proc do |_target_self, _nest_level, _pry|
129
130
  'project_live_session: '
130
131
  end])
@@ -13,8 +13,20 @@ module GoodData
13
13
  #
14
14
  # GoodData.logging_on
15
15
  #
16
- def logging_on
16
+ def logging_on(level = nil)
17
17
  @logger = default_logger if logger.is_a? NilLogger
18
+ @logger.level = level if level
19
+ @logger
20
+ end
21
+
22
+ # Turn logging on with HTTP included
23
+ #
24
+ # ### Example
25
+ #
26
+ # GoodData.logging_http_on
27
+ #
28
+ def logging_http_on
29
+ logging_on(Logger::DEBUG)
18
30
  end
19
31
 
20
32
  # Turn logging on
@@ -49,7 +61,7 @@ module GoodData
49
61
  @stats = true
50
62
  end
51
63
 
52
- def stats_on? # rubocop:disable Style/TrivialAccessors
64
+ def stats_on?
53
65
  @stats
54
66
  end
55
67
 
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodData
4
+ class ExecutionLimitExceeded < RuntimeError
5
+ def initialize(msg = 'The time limit #{time_limit} secs for polling on #{link} is over')
6
+ super(msg)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+ require 'restclient/exceptions'
3
+
4
+ module GoodData
5
+ # Project Not Found
6
+ class UncomputableReport < RuntimeError
7
+ end
8
+ end
@@ -3,7 +3,7 @@
3
3
  module GoodData
4
4
  # Project Not Found
5
5
  class ValidationError < RuntimeError
6
- DEFAULT_MSG = 'Validation has failed'
6
+ DEFAULT_MSG = 'Validation has failed. Run validate method on blueprint to learn more about the errors.'
7
7
 
8
8
  def initialize(msg = DEFAULT_MSG)
9
9
  super(msg)
@@ -40,7 +40,11 @@ module GoodData
40
40
  pairs = expression.scan(PARSE_MAQL_OBJECT_REGEXP).pmap do |uri|
41
41
  uri = uri.first
42
42
  if uri =~ /elements/
43
- [uri, Attribute.find_element_value(uri, opts)]
43
+ begin
44
+ [uri, Attribute.find_element_value(uri, opts)]
45
+ rescue AttributeElementNotFound
46
+ [uri, '(empty value)']
47
+ end
44
48
  else
45
49
  [uri, GoodData::MdObject[uri, opts].title]
46
50
  end
@@ -17,6 +17,29 @@ module GoodData
17
17
  @realized = false
18
18
  end
19
19
 
20
+ def realize(params = {})
21
+ @realized = true
22
+ source = @source && @source.to_s
23
+ case source
24
+ when 'ads'
25
+ realize_query(params)
26
+ when 'staging'
27
+ realize_staging(params)
28
+ when 'web'
29
+ realize_link
30
+ when 's3'
31
+ realize_s3(params)
32
+ else
33
+ fail "DataSource does not support type \"#{source}\""
34
+ end
35
+ end
36
+
37
+ def realized?
38
+ @realized == true
39
+ end
40
+
41
+ private
42
+
20
43
  def realize_query(params)
21
44
  query = @options[:query]
22
45
  dwh = params['ads_client']
@@ -65,16 +88,24 @@ module GoodData
65
88
  filename
66
89
  end
67
90
 
68
- def realize(params = {})
69
- @realized = true
70
- case @source.to_s
71
- when 'ads'
72
- realize_query(params)
73
- when 'staging'
74
- realize_staging(params)
75
- when 'web'
76
- realize_link
91
+ def realize_s3(params)
92
+ s3_client = params['aws_client'] && params['aws_client']['s3_client']
93
+ fail 'AWS client not present. Perhaps S3Middleware is missing in the brick definition?' if !s3_client || !s3_client.respond_to?(:buckets)
94
+ bucket_name = @options[:bucket]
95
+ key = @options[:key]
96
+ fail "Key \"bucket\" is missing in S3 datasource" if bucket_name.blank?
97
+ fail "Key \"key\" is missing in S3 datasource" if key.blank?
98
+ puts "Realizing download from S3. Bucket #{bucket_name}, object with key #{key}."
99
+ filename = Digest::SHA256.new.hexdigest(@options.to_json)
100
+ bucket = s3_client.buckets[bucket_name]
101
+ obj = bucket.objects[key]
102
+ File.open(filename, 'wb') do |file|
103
+ obj.read do |chunk|
104
+ file.write(chunk)
105
+ end
77
106
  end
107
+ puts 'Done downloading file.'
108
+ filename
78
109
  end
79
110
  end
80
111
  end
@@ -3,6 +3,36 @@
3
3
  module GoodData
4
4
  module Mixin
5
5
  module MdFinders
6
+ # Finds a specific type of the object by identifier. Returns first match. Returns full object.
7
+ #
8
+ # @param title [String] identifier that has to match exactly
9
+ # @param title [Regexp] regular expression that has to match
10
+ # @return [Array<GoodData::MdObject>] Array of MdObject
11
+ def find_first_by_identifier(identifier, options = { :client => GoodData.connection, :project => GoodData.project })
12
+ all = self[:all, options.merge(full: false)]
13
+ item = if identifier.is_a?(Regexp)
14
+ all.find { |r| r['identifier'] =~ identifier }
15
+ else
16
+ all.find { |r| r['identifier'] == identifier }
17
+ end
18
+ self[item['link'], options] unless item.nil?
19
+ end
20
+
21
+ # Finds a specific type of the object by identifier. Returns all matches. Returns full object.
22
+ #
23
+ # @param title [String] identifier that has to match exactly
24
+ # @param title [Regexp] regular expression that has to match
25
+ # @return [Array<GoodData::MdObject>] Array of MdObject
26
+ def find_by_identifier(identifier, options = { :client => GoodData.connection, :project => GoodData.project })
27
+ all = self[:all, options.merge(full: false)]
28
+ items = if identifier.is_a?(Regexp)
29
+ all.select { |r| r['title'] =~ identifier }
30
+ else
31
+ all.select { |r| r['title'] == identifier }
32
+ end
33
+ items.pmap { |item| self[item['link'], options] unless item.nil? }
34
+ end
35
+
6
36
  def find_by_tag(tag, opts = { :client => GoodData.connection, :project => GoodData.project })
7
37
  c = client || opts[:client]
8
38
 
@@ -15,6 +45,11 @@ module GoodData
15
45
  self[:all, client: c, project: project].select { |r| r.tags.split(',').include?(tag) }
16
46
  end
17
47
 
48
+ # Finds a specific type of the object by title. Returns first match. Returns full object.
49
+ #
50
+ # @param title [String] title that has to match exactly
51
+ # @param title [Regexp] regular expression that has to match
52
+ # @return [Array<GoodData::MdObject>] Array of MdObject
18
53
  def find_first_by_title(title, options = { :client => GoodData.connection, :project => GoodData.project })
19
54
  all = self[:all, options.merge(full: false)]
20
55
  item = if title.is_a?(Regexp)