gooddata 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/CHANGELOG.markdown +6 -0
  4. data/README.md +1 -0
  5. data/gooddata.gemspec +2 -1
  6. data/lib/gooddata.rb +4 -1
  7. data/lib/gooddata/bricks/base_downloader.rb +33 -19
  8. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +49 -25
  9. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +36 -33
  10. data/lib/gooddata/cli/commands/project_cmd.rb +6 -4
  11. data/lib/gooddata/client.rb +1 -1
  12. data/lib/gooddata/commands/api.rb +1 -1
  13. data/lib/gooddata/commands/auth.rb +1 -1
  14. data/lib/gooddata/connection.rb +13 -10
  15. data/lib/gooddata/core/connection.rb +1 -1
  16. data/lib/gooddata/core/user.rb +11 -3
  17. data/lib/gooddata/exceptions/validation_error.rb +12 -0
  18. data/lib/gooddata/extensions/extensions.rb +6 -0
  19. data/lib/gooddata/goodzilla/goodzilla.rb +2 -2
  20. data/lib/gooddata/helpers/csv_helper.rb +57 -0
  21. data/lib/gooddata/{helpers.rb → helpers/global_helpers.rb} +0 -0
  22. data/lib/gooddata/helpers/helpers.rb +6 -0
  23. data/lib/gooddata/models/domain.rb +134 -24
  24. data/lib/gooddata/models/membership.rb +402 -0
  25. data/lib/gooddata/models/metadata.rb +64 -7
  26. data/lib/gooddata/models/metadata/attribute.rb +27 -12
  27. data/lib/gooddata/models/metadata/column.rb +1 -1
  28. data/lib/gooddata/models/metadata/dashboard.rb +7 -6
  29. data/lib/gooddata/models/metadata/display_form.rb +17 -2
  30. data/lib/gooddata/models/metadata/fact.rb +13 -7
  31. data/lib/gooddata/models/metadata/metric.rb +9 -9
  32. data/lib/gooddata/models/metadata/report.rb +7 -8
  33. data/lib/gooddata/models/metadata/report_definition.rb +10 -11
  34. data/lib/gooddata/models/metadata/schema.rb +1 -1
  35. data/lib/gooddata/models/model.rb +1 -1
  36. data/lib/gooddata/models/process.rb +44 -25
  37. data/lib/gooddata/models/profile.rb +365 -13
  38. data/lib/gooddata/models/project.rb +245 -35
  39. data/lib/gooddata/models/project_blueprint.rb +42 -18
  40. data/lib/gooddata/models/project_creator.rb +4 -1
  41. data/lib/gooddata/models/project_role.rb +7 -7
  42. data/lib/gooddata/models/schedule.rb +17 -1
  43. data/lib/gooddata/models/schema_blueprint.rb +19 -2
  44. data/lib/gooddata/version.rb +1 -1
  45. data/out.txt +0 -0
  46. data/spec/data/users.csv +12 -0
  47. data/spec/helpers/connection_helper.rb +1 -0
  48. data/spec/helpers/csv_helper.rb +12 -0
  49. data/spec/helpers/project_helper.rb +1 -1
  50. data/spec/integration/full_project_spec.rb +136 -3
  51. data/spec/spec_helper.rb +9 -0
  52. data/spec/unit/commands/command_user_spec.rb +1 -1
  53. data/spec/unit/extensions/hash_spec.rb +19 -0
  54. data/spec/unit/godzilla/goodzilla_spec.rb +15 -0
  55. data/spec/unit/helpers/csv_helper_spec.rb +18 -0
  56. data/spec/unit/models/domain_spec.rb +47 -4
  57. data/spec/unit/models/md_object_spec.rb +8 -0
  58. data/spec/unit/models/membership_spec.rb +128 -0
  59. data/spec/unit/models/metadata_spec.rb +38 -0
  60. data/spec/unit/models/profile_spec.rb +212 -0
  61. data/spec/unit/models/project_blueprint_spec.rb +35 -8
  62. data/spec/unit/models/project_role_spec.rb +6 -6
  63. data/spec/unit/models/project_spec.rb +226 -13
  64. data/spec/unit/models/schedule_spec.rb +58 -0
  65. data/tmp/.gitkeepme +0 -0
  66. metadata +36 -11
  67. data/lib/gooddata/models/account_settings.rb +0 -124
  68. data/lib/gooddata/models/user.rb +0 -165
  69. data/spec/unit/models/account_settings_spec.rb +0 -28
  70. data/spec/unit/models/user_spec.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a5821b611d4899bf0ec0a279e73bbfc3b0e5e9b
4
- data.tar.gz: deafc64492f11e9c7c130d2e75e06e7c593382f9
3
+ metadata.gz: 215639f8217dd917939a3b1d6174b99fb72c8b95
4
+ data.tar.gz: 2adebe715e73ba4391123a4c61495130d79ae409
5
5
  SHA512:
6
- metadata.gz: 8b3fe636b75acba1cdd646e3a4080b80a6c62804192be997c6ae3a0c61431bc6027804b3487c191d3bd5d2773f65e9615c30bba89579ee8fc6dad427fe865a36
7
- data.tar.gz: b289c6b6c77ed47b2bf8c023a187b99b72cf2215977bb608d4d733b7e46a9e1f2b217f3c2ce921437cd7432474080c18b2de3d1c2e72a25feb9327b1e35ab886
6
+ metadata.gz: cc87893e984b96990174e8dbd257361e3ee86d16ffda17d199d635bc66b6070665decd5bc0ed6d64e1730185130d97b9d814f23479158864eadbbeea250ad582
7
+ data.tar.gz: ebcdbeca2dc7ccb94a5a36a6e718277e9bfcf40ac9bc0ae23bc8280ff402868931d941076f64e9e35631a9983df380a6ed07bbe11586e526df5c49490866f943
@@ -10,8 +10,10 @@ env:
10
10
 
11
11
  rvm:
12
12
  - 1.9.3
13
- - ruby-head
13
+ # - ruby-head
14
14
  - jruby-19mode
15
+ # - rbx-2.2.9
16
+ - 2.1
15
17
 
16
18
  before_install:
17
19
  - gem update --system
@@ -0,0 +1,6 @@
1
+ # GoodData Ruby SDK Changelog
2
+
3
+ ## 0.6.3
4
+ - Able to do save_as on metadata objects (Report, Metric, Dashboard)
5
+ - Model is now not created through build and update if it is not passing validations
6
+ - Added a setter for identifier on Metadata Object
data/README.md CHANGED
@@ -9,6 +9,7 @@ The best documentation for the GoodData API can be found using these resources:
9
9
  * http://docs.gooddata.apiary.io/
10
10
  * http://developer.gooddata.com/api
11
11
  * https://secure.gooddata.com/gdc
12
+ * http://rubydoc.info/gems/gooddata/frames
12
13
 
13
14
  ## Status
14
15
 
@@ -52,5 +52,6 @@ Gem::Specification.new do |s|
52
52
  s.add_dependency "restforce", "~> 1.4.3"
53
53
  s.add_dependency "rest-client", "~> 1.6.7"
54
54
  s.add_dependency "rubyzip", "~> 1.1.0"
55
- s.add_dependency "salesforce_bulk", "~> 1.0.3"
55
+ s.add_dependency "salesforce_bulk_query", "~> 0.0"
56
+ s.add_dependency "aws-sdk", "~> 1.45"
56
57
  end
@@ -10,11 +10,14 @@ require_relative 'gooddata/commands/commands'
10
10
  require_relative 'gooddata/core/core'
11
11
  require_relative 'gooddata/data/data'
12
12
  require_relative 'gooddata/exceptions/exceptions'
13
+ require_relative 'gooddata/helpers/helpers'
13
14
  require_relative 'gooddata/models/models'
14
15
 
15
16
  # Files
16
17
  require_relative 'gooddata/client'
17
18
  require_relative 'gooddata/connection'
18
19
  require_relative 'gooddata/extract'
19
- require_relative 'gooddata/helpers'
20
20
  require_relative 'gooddata/version'
21
+
22
+ # Extensions
23
+ require_relative 'gooddata/extensions/extensions'
@@ -1,12 +1,14 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'pathname'
4
+ require 'aws'
4
5
 
5
6
  module GoodData
6
7
  module Bricks
7
8
  class BaseDownloader
8
9
  def initialize(params)
9
10
  @params = params
11
+ @logger = @params['GDC_LOGGER']
10
12
  end
11
13
 
12
14
  def pre_process(meta)
@@ -14,34 +16,40 @@ module GoodData
14
16
  end
15
17
 
16
18
  def download
17
- puts 'would download data'
19
+ @logger.info 'would download data' if @logger
18
20
  []
19
21
  end
20
22
 
21
23
  def backup(meta)
22
- puts 'would send a backup list of files to backup'
23
- files = meta.reduce([]) do |a, e|
24
- a << e[:filename]
24
+ @logger.info 'would send a backup list of files to backup' if @logger
25
+
26
+ files = meta['objects'].map { |k, o| o }.reduce([]) do |a, e|
27
+ a + e['filenames']
25
28
  end
26
29
 
27
- bucket_name = @params[:s3_backup_bucket_name]
30
+ bucket_name = @params['s3_backup_bucket_name']
28
31
 
29
32
  s3 = AWS::S3.new(
30
- :access_key_id => @params[:aws_access_key_id],
31
- :secret_access_key => @params[:aws_secret_access_key])
33
+ :access_key_id => @params['aws_access_key_id'],
34
+ :secret_access_key => @params['aws_secret_access_key']
35
+ )
32
36
 
33
37
  bucket = s3.buckets[bucket_name]
34
38
  bucket = s3.buckets.create(bucket_name) unless bucket.exists?
35
39
 
36
40
  files.each do |file|
37
- obj = bucket.objects[file]
38
- obj.write(Pathname.new(file))
41
+ file_path = Pathname.new(file)
42
+ target_path = Pathname.new(@params['s3_backup_path'] || '') + file_path.basename
43
+ obj = bucket.objects[target_path]
44
+ obj.write(file_path)
45
+ @logger.info "Backed up file #{file_path} to s3 #{target_path}" if @logger
39
46
  end
47
+
40
48
  meta
41
49
  end
42
50
 
43
51
  def post_process(meta)
44
- puts 'Maybe some postprocessing'
52
+ @logger.info 'Maybe some postprocessing' if @logger
45
53
  meta
46
54
  end
47
55
 
@@ -49,19 +57,25 @@ module GoodData
49
57
  def run
50
58
  downloaded_data = download
51
59
  downloaded_data = pre_process(downloaded_data)
52
- backup(downloaded_data)
60
+ backup(downloaded_data) unless @params['skip_backup']
61
+
53
62
  downloaded_data = post_process(downloaded_data)
54
63
 
55
- accumulated_state = downloaded_data.reduce([]) do |memo, item|
56
- item.key?(:state) ? memo.concat(item[:state]) : memo
57
- end
58
- accumulated_state.each do |item|
59
- key = item[:key]
60
- val = item[:value]
64
+ # save the state - whatever is in the return value of #download in the :persist key .. to project metadata
65
+ if downloaded_data[:persist]
66
+ accumulated_state = downloaded_data[:persist].reduce([]) do |memo, item|
67
+ item.key?(:state) ? memo.concat(item[:state]) : memo
68
+ end
69
+ accumulated_state.each do |item|
70
+ key = item[:key]
71
+ val = item[:value]
61
72
 
62
- puts "Saving metadata #{key} => #{val}"
63
- GoodData::ProjectMetadata[key] = val
73
+ @logger.info "Saving metadata #{key} => #{val}" if @logger
74
+ GoodData::ProjectMetadata[key] = val
75
+ end
64
76
  end
77
+
78
+ post_process(downloaded_data)
65
79
  end
66
80
  end
67
81
  end
@@ -1,37 +1,61 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'salesforce_bulk'
3
+ require 'salesforce_bulk_query'
4
4
 
5
5
  require_relative 'base_middleware'
6
6
 
7
7
  module GoodData
8
8
  module Bricks
9
9
  class BulkSalesforceMiddleware < Bricks::Middleware
10
+ DEFAULT_VERSION = '29.0'
11
+
10
12
  def call(params)
11
- username = params[:salesforce_username]
12
- password = params[:salesforce_password]
13
- token = params[:salesforce_token]
14
- client_id = params[:salesforce_client_id]
15
- client_secret = params[:salesforce_client_secret]
16
- host = params[:salesforce_host]
17
-
18
- credentials = if username && password && token
19
- {
20
- :username => username,
21
- :password => password,
22
- :security_token => token
23
- }
24
- end
25
-
26
- client = if credentials
27
- credentials.merge!(
28
- :client_id => client_id,
29
- :client_secret => client_secret
30
- )
31
- credentials[:host] = host unless host.nil?
32
- SalesforceBulk::Api.new(credentials[:username], credentials[:password] + credentials[:security_token])
33
- end
34
- @app.call(params.merge(:salesforce_bulk_client => client))
13
+ username = params['salesforce_username']
14
+ password = params['salesforce_password']
15
+ token = params['salesforce_token']
16
+ oauth_refresh_token = params['salesforce_oauth_refresh_token']
17
+
18
+ client_id = params['salesforce_client_id']
19
+ client_secret = params['salesforce_client_secret']
20
+ host = params['salesforce_host']
21
+ version = params['salesforce_api_version'] || DEFAULT_VERSION
22
+
23
+ app_info = {
24
+ :client_id => client_id,
25
+ :client_secret => client_secret
26
+ }
27
+ app_info[:host] = host unless host.nil?
28
+ salesforce = nil
29
+ client_params = nil
30
+
31
+ if username && password && token
32
+ # use basic auth
33
+ client_params = {
34
+ :username => username,
35
+ :password => password,
36
+ :security_token => token
37
+ }.merge(app_info)
38
+
39
+ elsif oauth_refresh_token
40
+ # use oauth
41
+ client_params = {
42
+ :refresh_token => oauth_refresh_token
43
+ }.merge(app_info)
44
+ end
45
+
46
+ if client_params
47
+
48
+ client_params[:api_version] = version
49
+
50
+ client = params['salesforce_client'] || Restforce.new(client_params)
51
+ client.authenticate!
52
+
53
+ salesforce = SalesforceBulkQuery::Api.new(client, :logger => params['GDC_LOGGER'])
54
+ # SalesforceBulkQuery adds its own Restforce logging so turn it off
55
+ Restforce.log = false if params['GDC_LOGGER']
56
+ end
57
+
58
+ @app.call(params.merge('salesforce_bulk_client' => salesforce))
35
59
  end
36
60
  end
37
61
  end
@@ -7,40 +7,43 @@ require_relative 'base_middleware'
7
7
  module GoodData
8
8
  module Bricks
9
9
  class RestForceMiddleware < Bricks::Middleware
10
+ DEFAULT_VERSION = '29.0'
11
+
10
12
  def call(params)
11
- username = params[:salesforce_username]
12
- password = params[:salesforce_password]
13
- token = params[:salesforce_token]
14
- client_id = params[:salesforce_client_id]
15
- client_secret = params[:salesforce_client_secret]
16
- oauth_token = params[:salesforce_oauth_token]
17
- refresh_token = params[:salesforce_refresh_token]
18
- host = params[:salesforce_host]
19
-
20
- if username && password && token
21
- credentials = {
22
- :username => username,
23
- :password => password,
24
- :security_token => token
25
- }
26
- elsif oauth_token && refresh_token
27
- {
28
- :oauth_token => oauth_token,
29
- :refresh_token => refresh_token
30
- }
31
- end
32
-
33
- if credentials
34
- client = credentials.merge!(
35
- :client_id => client_id,
36
- :client_secret => client_secret
37
- )
38
- credentials[:host] = host unless host.nil?
39
-
40
- Restforce.log = true if params[:salesforce_client_logger]
41
- Restforce.new(credentials)
42
- end
43
- @app.call(params.merge(:salesforce_client => client))
13
+ username = params['salesforce_username']
14
+ password = params['salesforce_password']
15
+ token = params['salesforce_token']
16
+ client_id = params['salesforce_client_id']
17
+ client_secret = params['salesforce_client_secret']
18
+ oauth_refresh_token = params['salesforce_oauth_refresh_token']
19
+ host = params['salesforce_host']
20
+ version = params['salesforce_api_version'] || DEFAULT_VERSION
21
+
22
+ credentials = if username && password && token
23
+ {
24
+ :username => username,
25
+ :password => password,
26
+ :security_token => token
27
+ }
28
+ elsif (oauth_refresh_token) && (!oauth_refresh_token.empty?)
29
+ {
30
+ :refresh_token => oauth_refresh_token
31
+ }
32
+ end
33
+
34
+ client = if credentials
35
+ credentials.merge!(
36
+ :client_id => client_id,
37
+ :client_secret => client_secret
38
+ )
39
+ credentials[:host] = host unless host.nil?
40
+ credentials[:api_version] = version
41
+
42
+ Restforce.log = true if params['salesforce_client_logger']
43
+
44
+ Restforce.new(credentials)
45
+ end
46
+ @app.call(params.merge('salesforce_client' => client))
44
47
  end
45
48
  end
46
49
  end
@@ -53,10 +53,12 @@ GoodData::CLI.module_eval do
53
53
  c.desc 'Create a gooddata project'
54
54
  c.command :create do |create|
55
55
  create.action do |global_options, options, args|
56
- title = ask 'Project name'
57
- summary = ask('Project summary') { |q| q.default = '' }
58
- template = ask('Project template')
59
- token = ask('token')
56
+ opts = options.merge(global_options)
57
+
58
+ title = args[0] || ask('Project name')
59
+ summary = args[1] || ask('Project summary') { |q| q.default = '' }
60
+ template = args[2] || ask('Project template')
61
+ token = opts[:token] || ask('token')
60
62
 
61
63
  opts = options.merge(global_options)
62
64
  GoodData.connect(opts)
@@ -4,7 +4,7 @@ require 'csv'
4
4
 
5
5
  require_relative 'version'
6
6
  require_relative 'connection'
7
- require_relative 'helpers'
7
+ require_relative 'helpers/helpers'
8
8
 
9
9
  FasterCSV = CSV
10
10
 
@@ -25,7 +25,7 @@ module GoodData
25
25
  # Test of login
26
26
  def test
27
27
  if GoodData.test_login
28
- puts "Succesfully logged in as #{GoodData.profile.user}"
28
+ puts "Succesfully logged in as #{GoodData.profile.email}"
29
29
  else
30
30
  puts 'Unable to log in to GoodData server!'
31
31
  end
@@ -4,7 +4,7 @@ require 'highline/import'
4
4
  require 'multi_json'
5
5
 
6
6
  require_relative '../cli/terminal'
7
- require_relative '../helpers'
7
+ require_relative '../helpers/helpers'
8
8
 
9
9
  module GoodData
10
10
  module Command
@@ -21,16 +21,19 @@ module GoodData
21
21
  #
22
22
  def connect(options = nil, second_options = nil, third_options = {})
23
23
  GoodData.logger.debug 'GoodData#connect'
24
-
25
- if options.is_a? Hash
26
- fail 'You have to provide login and password' if (options[:login].nil? || options[:login].empty?) && (options[:password].nil? || options[:password].empty?)
27
- threaded[:connection] = Connection.new(options[:login], options[:password], options)
28
- GoodData.project = options[:project] if options[:project]
29
- elsif options.is_a?(String) && second_options.is_a?(String)
30
- fail 'You have to provide login and password' if (options.nil? || options.empty?) && (second_options.nil? || second_options.empty?)
31
- threaded[:connection] = Connection.new(options, second_options, third_options)
32
- end
33
-
24
+ threaded[:connection] = if options.is_a? Hash
25
+ fail 'You have to provide login and password' if (options[:login].nil? || options[:login].empty?) && (options[:password].nil? || options[:password].empty?)
26
+ Connection.new(options[:login], options[:password], options)
27
+ conn = Connection.new(options[:login], options[:password], options)
28
+ GoodData.project = options[:project] if options[:project]
29
+ conn
30
+ elsif options.is_a?(String) && second_options.is_a?(String)
31
+ fail 'You have to provide login and password' if (options.nil? || options.empty?) && (second_options.nil? || second_options.empty?)
32
+ Connection.new(options, second_options, third_options)
33
+ elsif options.nil? && second_options.nil?
34
+ p = GoodData::Command::Auth.read_credentials
35
+ Connection.new(p[:login] || p[:username], p[:password], p)
36
+ end
34
37
  threaded[:connection]
35
38
  end
36
39
 
@@ -377,7 +377,7 @@ module GoodData
377
377
  def scrub_params(params, keys)
378
378
  keys = keys.reduce([]) { |a, e| a.concat([e.to_s, e.to_sym]) }
379
379
 
380
- new_params = Marshal.load(Marshal.dump(params))
380
+ new_params = params.deep_dup
381
381
  GoodData::Helpers.hash_dfs(new_params) do |k, key|
382
382
  keys.each do |key_to_scrub|
383
383
  k[key_to_scrub] = ('*' * k[key_to_scrub].length) if k && k.key?(key_to_scrub) && k[key_to_scrub]
@@ -3,17 +3,25 @@
3
3
  require_relative 'connection'
4
4
  require_relative 'threaded'
5
5
 
6
+ require_relative '../models/profile'
7
+
6
8
  module GoodData
7
9
  class << self
8
10
  # Attempts to log in
11
+ #
12
+ # @return [Boolean] True if logged in else false
9
13
  def test_login
10
14
  connection.connect!
11
15
  connection.logged_in?
12
16
  end
13
17
 
14
- # Returns the currently logged in user Profile.
15
- def profile
16
- threaded[:profile] ||= Profile.load
18
+ # Gets currently logged user
19
+ #
20
+ # @return [GoodData::Profile] User Profile
21
+ def user
22
+ GoodData::Profile.current
17
23
  end
24
+
25
+ alias_method :profile, :user
18
26
  end
19
27
  end