gooddata 0.6.7 → 0.6.8

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 (145) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/README.md +10 -2
  4. data/TODO.md +32 -0
  5. data/gooddata.gemspec +5 -0
  6. data/lib/gooddata.rb +4 -0
  7. data/lib/gooddata/app/app.rb +12 -0
  8. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +4 -3
  9. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +2 -1
  10. data/lib/gooddata/cli/commands/console_cmd.rb +23 -5
  11. data/lib/gooddata/cli/commands/domain_cmd.rb +9 -10
  12. data/lib/gooddata/cli/commands/process_cmd.rb +11 -9
  13. data/lib/gooddata/cli/commands/project_cmd.rb +25 -27
  14. data/lib/gooddata/cli/commands/projects_cmd.rb +2 -2
  15. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +1 -1
  16. data/lib/gooddata/cli/commands/user_cmd.rb +2 -2
  17. data/lib/gooddata/cli/hooks.rb +4 -2
  18. data/lib/gooddata/cli/shared.rb +1 -1
  19. data/lib/gooddata/cli/terminal.rb +1 -1
  20. data/lib/gooddata/commands/api.rb +1 -1
  21. data/lib/gooddata/commands/auth.rb +4 -28
  22. data/lib/gooddata/commands/domain.rb +9 -4
  23. data/lib/gooddata/commands/process.rb +26 -23
  24. data/lib/gooddata/commands/project.rb +74 -50
  25. data/lib/gooddata/commands/projects.rb +3 -2
  26. data/lib/gooddata/commands/role.rb +9 -3
  27. data/lib/gooddata/commands/user.rb +6 -4
  28. data/lib/gooddata/connection.rb +11 -45
  29. data/lib/gooddata/core/logging.rb +0 -1
  30. data/lib/gooddata/core/project.rb +22 -22
  31. data/lib/gooddata/core/rest.rb +9 -8
  32. data/lib/gooddata/core/user.rb +0 -11
  33. data/lib/gooddata/exceptions/project_not_found.rb +1 -0
  34. data/lib/gooddata/extensions/enumerable.rb +10 -0
  35. data/lib/gooddata/extensions/hash.rb +25 -0
  36. data/lib/gooddata/goodzilla/goodzilla.rb +4 -4
  37. data/lib/gooddata/helper/class_helper.rb +1 -0
  38. data/lib/gooddata/helper/helpers.rb +8 -0
  39. data/lib/gooddata/helpers/auth_helpers.rb +41 -0
  40. data/lib/gooddata/mixins/author.rb +1 -1
  41. data/lib/gooddata/mixins/contributor.rb +1 -1
  42. data/lib/gooddata/mixins/data_property_reader.rb +2 -0
  43. data/lib/gooddata/mixins/data_property_writer.rb +2 -0
  44. data/lib/gooddata/mixins/inspector.rb +49 -0
  45. data/lib/gooddata/mixins/md_finders.rb +16 -8
  46. data/lib/gooddata/mixins/md_id_to_uri.rb +12 -4
  47. data/lib/gooddata/mixins/md_object_indexer.rb +15 -4
  48. data/lib/gooddata/mixins/md_object_query.rb +42 -20
  49. data/lib/gooddata/mixins/md_relations.rb +21 -12
  50. data/lib/gooddata/mixins/meta_getter.rb +2 -0
  51. data/lib/gooddata/mixins/meta_property_reader.rb +2 -0
  52. data/lib/gooddata/mixins/meta_property_writer.rb +2 -0
  53. data/lib/gooddata/mixins/rest_resource.rb +32 -10
  54. data/lib/gooddata/mixins/root_key_getter.rb +1 -1
  55. data/lib/gooddata/models/data_result.rb +3 -1
  56. data/lib/gooddata/models/domain.rb +31 -22
  57. data/lib/gooddata/models/empty_result.rb +22 -0
  58. data/lib/gooddata/models/invitation.rb +11 -9
  59. data/lib/gooddata/models/links.rb +5 -3
  60. data/lib/gooddata/models/membership.rb +23 -28
  61. data/lib/gooddata/models/metadata.rb +35 -35
  62. data/lib/gooddata/models/metadata/attribute.rb +10 -8
  63. data/lib/gooddata/models/metadata/dashboard.rb +1 -1
  64. data/lib/gooddata/models/metadata/fact.rb +3 -3
  65. data/lib/gooddata/models/metadata/label.rb +4 -4
  66. data/lib/gooddata/models/metadata/metric.rb +76 -38
  67. data/lib/gooddata/models/metadata/report.rb +52 -17
  68. data/lib/gooddata/models/metadata/report_definition.rb +178 -28
  69. data/lib/gooddata/models/model.rb +13 -6
  70. data/lib/gooddata/models/process.rb +93 -30
  71. data/lib/gooddata/models/profile.rb +18 -20
  72. data/lib/gooddata/models/project.rb +344 -127
  73. data/lib/gooddata/models/project_creator.rb +32 -22
  74. data/lib/gooddata/models/project_metadata.rb +26 -14
  75. data/lib/gooddata/models/project_role.rb +15 -17
  76. data/lib/gooddata/models/report_data_result.rb +4 -0
  77. data/lib/gooddata/models/schedule.rb +51 -20
  78. data/lib/gooddata/models/schema_blueprint.rb +9 -3
  79. data/lib/gooddata/rest/README.md +37 -0
  80. data/lib/gooddata/rest/client.rb +318 -0
  81. data/lib/gooddata/rest/connection.rb +235 -0
  82. data/lib/gooddata/rest/connections/connections.rb +8 -0
  83. data/lib/gooddata/rest/connections/dummy_connection.rb +52 -0
  84. data/lib/gooddata/rest/connections/rest_client_connection.rb +177 -0
  85. data/lib/gooddata/rest/object.rb +32 -0
  86. data/lib/gooddata/rest/object_factory.rb +67 -0
  87. data/lib/gooddata/rest/resource.rb +17 -0
  88. data/lib/gooddata/rest/rest.rb +20 -0
  89. data/lib/gooddata/version.rb +1 -1
  90. data/spec/data/cc/data/source/commits.csv +4 -0
  91. data/spec/data/cc/data/source/devs.csv +4 -0
  92. data/spec/data/cc/data/source/repos.csv +3 -0
  93. data/spec/data/cc/devel.prm +0 -0
  94. data/spec/data/cc/graph/graph.grf +11 -0
  95. data/spec/data/cc/workspace.prm +19 -0
  96. data/spec/data/hello_world_process/hello_world.rb +1 -0
  97. data/spec/data/hello_world_process/hello_world.zip +0 -0
  98. data/spec/data/users.csv +12 -12
  99. data/spec/helpers/connection_helper.rb +6 -0
  100. data/spec/helpers/process_helper.rb +12 -0
  101. data/spec/helpers/project_helper.rb +2 -2
  102. data/spec/integration/command_projects_spec.rb +11 -9
  103. data/spec/integration/create_from_template_spec.rb +6 -2
  104. data/spec/integration/full_process_schedule_spec.rb +49 -36
  105. data/spec/integration/full_project_spec.rb +221 -256
  106. data/spec/integration/partial_md_export_import_spec.rb +18 -17
  107. data/spec/logging_in_logging_out_spec.rb +17 -8
  108. data/spec/spec_helper.rb +4 -2
  109. data/spec/unit/cli/commands/cmd_api_spec.rb +1 -1
  110. data/spec/unit/cli/commands/cmd_auth_spec.rb +1 -1
  111. data/spec/unit/cli/commands/cmd_domain_spec.rb +29 -3
  112. data/spec/unit/cli/commands/cmd_process_spec.rb +1 -1
  113. data/spec/unit/cli/commands/cmd_project_spec.rb +1 -1
  114. data/spec/unit/cli/commands/cmd_role_spec.rb +13 -2
  115. data/spec/unit/cli/commands/cmd_run_ruby_spec.rb +1 -1
  116. data/spec/unit/cli/commands/cmd_scaffold_spec.rb +1 -1
  117. data/spec/unit/cli/commands/cmd_user_spec.rb +1 -1
  118. data/spec/unit/commands/command_api_spec.rb +0 -19
  119. data/spec/unit/commands/command_auth_spec.rb +20 -13
  120. data/spec/unit/commands/command_dataset_spec.rb +2 -2
  121. data/spec/unit/commands/command_process_spec.rb +24 -21
  122. data/spec/unit/commands/command_projects_spec.rb +2 -2
  123. data/spec/unit/commands/command_scaffold_spec.rb +2 -2
  124. data/spec/unit/commands/command_user_spec.rb +3 -3
  125. data/spec/unit/core/connection_spec.rb +9 -10
  126. data/spec/unit/core/project_spec.rb +8 -4
  127. data/spec/unit/core/rest_spec.rb +6 -6
  128. data/spec/unit/models/domain_spec.rb +14 -7
  129. data/spec/unit/models/invitation_spec.rb +2 -2
  130. data/spec/unit/models/membership_spec.rb +5 -5
  131. data/spec/unit/models/metric_spec.rb +92 -0
  132. data/spec/unit/models/profile_spec.rb +25 -21
  133. data/spec/unit/models/project_blueprint_spec.rb +6 -6
  134. data/spec/unit/models/project_role_spec.rb +3 -5
  135. data/spec/unit/models/project_spec.rb +43 -37
  136. data/spec/unit/models/schedule_spec.rb +58 -107
  137. data/spec/unit/rest/resource_spec.rb +6 -0
  138. metadata +87 -10
  139. data/lib/gooddata/cli/commands/role_cmd.rb +0 -28
  140. data/lib/gooddata/core/connection.rb +0 -392
  141. data/lib/gooddata/core/threaded.rb +0 -14
  142. data/lib/gooddata/models/md_object.rb +0 -25
  143. data/lib/gooddata/models/metadata/folder.rb +0 -24
  144. data/spec/unit/models/md_object_spec.rb +0 -55
  145. data/spec/unit/models/metric.rb +0 -92
@@ -0,0 +1,49 @@
1
+ # encoding: UTF-8
2
+
3
+ # See https://gist.github.com/ubermajestix/3644301
4
+
5
+ module GoodData
6
+ module Mixin
7
+ # When an RSpec test like this fails,
8
+ #
9
+ # @my_array.should == [@some_model, @some_model2]
10
+ #
11
+ # RSpec will call inspect on each of the objects to "help" you figure out
12
+ # what went wrong. Well, inspect will usually dump a TON OF SHIT and make trying
13
+ # to figure out why `@my_array` is not made up of `@some_model` and `@some_model2`.
14
+ #
15
+ # This little module and technique helps get around that. It will redefine `inspect`
16
+ # if you include it in your model object.
17
+ #
18
+ # You can define a whitelist of methods that inspect will dump.
19
+ # It will always provide `object_id` at a minimum.
20
+ #
21
+ # To use it, drop it in spec/support/inspector.rb and class_eval the models to
22
+ # override `inspect`.
23
+ module Inspector
24
+ def inspect
25
+ string = "#<#{self.class.name}:#{object_id} "
26
+ fields = self.class.inspector_fields.map { |field| "#{field}: #{send(field)}" }
27
+ string << fields.join(', ') << '>'
28
+ end
29
+
30
+ def self.inspected
31
+ @inspected ||= []
32
+ end
33
+
34
+ def self.included(source)
35
+ # $stdout.puts "Overriding inspect on #{source}"
36
+ inspected << source
37
+ source.class_eval do
38
+ def self.inspector(*fields)
39
+ @inspector_fields = *fields
40
+ end
41
+
42
+ def self.inspector_fields
43
+ @inspector_fields ||= []
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -3,18 +3,26 @@
3
3
  module GoodData
4
4
  module Mixin
5
5
  module MdFinders
6
- def find_by_tag(tag)
7
- self[:all].select { |r| r['tags'].split(',').include?(tag) }
6
+ def find_by_tag(tag, opts = { :client => GoodData.connection, :project => GoodData.project })
7
+ c = client || opts[:client]
8
+
9
+ p = opts[:project]
10
+ fail ArgumentError, 'No :project specified' if p.nil?
11
+
12
+ project = GoodData::Project[p, opts]
13
+ fail ArgumentError 'Wrong :project specified' if project.nil?
14
+
15
+ self[:all, client: c, project: project].select { |r| r.tags.split(',').include?(tag) }
8
16
  end
9
17
 
10
- def find_first_by_title(title)
11
- all = self[:all]
18
+ def find_first_by_title(title, options = { :client => GoodData.connection, :project => GoodData.project })
19
+ all = self[:all, options.merge(full: false)]
12
20
  item = if title.is_a?(Regexp)
13
21
  all.find { |r| r['title'] =~ title }
14
22
  else
15
23
  all.find { |r| r['title'] == title }
16
24
  end
17
- self[item['link']] unless item.nil?
25
+ self[item['link'], options] unless item.nil?
18
26
  end
19
27
 
20
28
  # Finds a specific type of the object by title. Returns all matches. Returns full object.
@@ -22,14 +30,14 @@ module GoodData
22
30
  # @param title [String] title that has to match exactly
23
31
  # @param title [Regexp] regular expression that has to match
24
32
  # @return [Array<GoodData::MdObject>] Array of MdObject
25
- def find_by_title(title)
26
- all = self[:all]
33
+ def find_by_title(title, options = { :client => GoodData.connection, :project => GoodData.project })
34
+ all = self[:all, options.merge(full: false)]
27
35
  items = if title.is_a?(Regexp)
28
36
  all.select { |r| r['title'] =~ title }
29
37
  else
30
38
  all.select { |r| r['title'] == title }
31
39
  end
32
- items.map { |item| self[item['link']] unless item.nil? }
40
+ items.pmap { |item| self[item['link'], options] unless item.nil? }
33
41
  end
34
42
  end
35
43
  end
@@ -6,10 +6,18 @@ module GoodData
6
6
  IDENTIFIERS_CFG = 'instance-identifiers'
7
7
 
8
8
  # TODO: Add test
9
- def identifier_to_uri(*ids)
10
- fail(NoProjectError, 'Connect to a project before searching for an object') unless GoodData.project
11
- uri = GoodData.project.md[IDENTIFIERS_CFG]
12
- response = GoodData.post uri, 'identifierToUri' => ids
9
+ def identifier_to_uri(opts = { :client => GoodData.connection, :project => GoodData.project }, *ids)
10
+ client = opts[:client]
11
+ fail ArgumentError, 'No :client specified' if client.nil?
12
+
13
+ p = opts[:project]
14
+ fail ArgumentError, 'No :project specified' if p.nil?
15
+
16
+ project = GoodData::Project[p, opts]
17
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
18
+
19
+ uri = project.md[IDENTIFIERS_CFG]
20
+ response = client.post uri, 'identifierToUri' => ids
13
21
  if response['identifiers'].empty?
14
22
  nil
15
23
  else
@@ -11,8 +11,15 @@ module GoodData
11
11
  # @option options [Boolean] :full if passed true the subclass can decide 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
12
12
  # @return [MdObject] if id is a String or number single object is returned
13
13
  # @return [Array] if :all was provided as an id, list of objects should be returned. Note that this is implemented only in the subclasses. MdObject does not support this since API has no means to return list of all types of objects
14
- def [](id, options = {})
15
- project = options[:project] || GoodData.project
14
+ def [](id, options = { :client => GoodData.connection, :project => GoodData.project })
15
+ client = options[:client]
16
+ fail ArgumentError, 'No :client specified' if client.nil?
17
+
18
+ p = options[:project]
19
+ fail ArgumentError, 'No :project specified' if p.nil?
20
+
21
+ project = GoodData::Project[p, :client => client]
22
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
16
23
 
17
24
  fail "You have to provide an \"id\" to be searched for." unless id
18
25
  fail(NoProjectError, 'Connect to a project before searching for an object') unless project
@@ -21,13 +28,17 @@ module GoodData
21
28
  uri = if id.is_a?(Integer) || id =~ /^\d+$/
22
29
  "#{project.md[MD_OBJ_CTG]}/#{id}"
23
30
  elsif id !~ /\//
24
- identifier_to_uri id
31
+ identifier_to_uri options, id
25
32
  elsif id =~ /^\//
26
33
  id
27
34
  else
28
35
  fail 'Unexpected object id format: expected numeric ID, identifier with no slashes or an URI starting with a slash'
29
36
  end
30
- new(GoodData.get uri) unless uri.nil?
37
+ # new(GoodData.get uri) unless uri.nil?
38
+ if uri
39
+ raw = client.get(uri)
40
+ client.create(self, raw, client: client, project: project)
41
+ end
31
42
  end
32
43
 
33
44
  alias_method :get_by_id, :[]
@@ -8,8 +8,8 @@ module GoodData
8
8
  # @param options [Hash] the options hash
9
9
  # @option options [Boolean] :full if passed true the subclass can decide 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
10
10
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
11
- def all(options = {})
12
- fail NotImplementedError, 'Method should be implemented in subclass. Currently there is no way hoe to get all metadata objects on API.'
11
+ def all(options = { :client => GoodData.connection, :project => GoodData.project })
12
+ fail NotImplementedError, 'Method should be implemented in subclass. Currently there is no way how to get all metadata objects on API.'
13
13
  end
14
14
 
15
15
  # Method intended to be called by individual classes in their all
@@ -23,15 +23,25 @@ module GoodData
23
23
  # @param options [Hash] the options hash
24
24
  # @option options [Boolean] :full if passed true the subclass can decide 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
25
25
  # @return [Array<GoodData::MdObject> | Array<Hash>] Return the appropriate metadata objects or their representation
26
- def query(query_obj_type, klass, options = {})
27
- project = options[:project] || GoodData.project
28
- fail(NoProjectError, 'Connect to a project before searching for an object') unless project
29
- query_result = GoodData.get(project.md['query'] + "/#{query_obj_type}/")['query']['entries']
30
- options[:full] ? query_result.map { |item| klass[item['link']] } : query_result
26
+ def query(query_obj_type, klass, options = { :client => GoodData.connection, :project => GoodData.project })
27
+ client = options[:client]
28
+ fail ArgumentError, 'No :client specified' if client.nil?
29
+
30
+ p = options[:project]
31
+ fail ArgumentError, 'No :project specified' if p.nil?
32
+
33
+ project = GoodData::Project[p, options]
34
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
35
+
36
+ query_result = client.get(project.md['query'] + "/#{query_obj_type}/")['query']['entries']
37
+ options[:full] == false ? query_result : query_result.pmap { |item| klass[item['link'], options] }
31
38
  end
32
39
 
33
- def dependency(uri, key = nil)
34
- result = GoodData.get(uri)['entries']
40
+ def dependency(uri, key = nil, opts = { :client => GoodData.connection })
41
+ c = opts[:client]
42
+ fail ArgumentError, 'No :client specified' if c.nil?
43
+
44
+ result = c.get(uri)['entries']
35
45
  if key.nil?
36
46
  result
37
47
  elsif key.respond_to?(:category)
@@ -42,13 +52,13 @@ module GoodData
42
52
  end
43
53
 
44
54
  # Checks for dependency
45
- def dependency?(type, uri, target_uri)
55
+ def dependency?(type, uri, target_uri, opts = { :client => GoodData.connection, :project => GoodData.project })
46
56
  uri = uri.respond_to?(:uri) ? uri.uri : uri
47
57
  objs = case type
48
58
  when :usedby
49
- usedby(uri)
59
+ usedby(uri, nil, opts)
50
60
  when :using
51
- using(uri)
61
+ using(uri, nil, opts)
52
62
  end
53
63
 
54
64
  target_uri = target_uri.respond_to?(:uri) ? target_uri.uri : target_uri
@@ -58,26 +68,38 @@ module GoodData
58
68
  end
59
69
 
60
70
  # Returns which objects uses this MD resource
61
- def usedby(uri, key = nil, project = GoodData.project)
62
- dependency("#{project.md['usedby2']}/#{obj_id(uri)}", key)
71
+ def usedby(uri, key = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
72
+ p = opts[:project]
73
+ fail ArgumentError, 'No :project specified' if p.nil?
74
+
75
+ project = GoodData::Project[p, opts]
76
+ fail ArgumentError, 'No :project specified' if project.nil?
77
+
78
+ dependency("#{project.md['usedby2']}/#{obj_id(uri)}", key, opts)
63
79
  end
64
80
 
65
81
  alias_method :used_by, :usedby
66
82
 
67
83
  # Returns which objects this MD resource uses
68
- def using(uri, key = nil)
69
- dependency("#{GoodData.project.md['using2']}/#{obj_id(uri)}", key)
84
+ def using(uri, key = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
85
+ p = opts[:project]
86
+ fail ArgumentError, 'No :project specified' if p.nil?
87
+
88
+ project = GoodData::Project[p, opts]
89
+ fail ArgumentError, 'No :project specified' if project.nil?
90
+
91
+ dependency("#{project.md['using2']}/#{obj_id(uri)}", key, opts)
70
92
  end
71
93
 
72
- def usedby?(uri, target_uri)
73
- dependency?(:usedby, uri, target_uri)
94
+ def usedby?(uri, target_uri, opts = { :client => GoodData.connection, :project => GoodData.project })
95
+ dependency?(:usedby, uri, target_uri, opts)
74
96
  end
75
97
 
76
98
  alias_method :used_by?, :usedby?
77
99
 
78
100
  # Checks if obj is using this MD resource
79
- def using?(uri, target_uri)
80
- dependency?(:using, uri, target_uri)
101
+ def using?(uri, target_uri, opts = { :client => GoodData.connection, :project => GoodData.project })
102
+ dependency?(:using, uri, target_uri, opts)
81
103
  end
82
104
  end
83
105
  end
@@ -3,36 +3,45 @@
3
3
  module GoodData
4
4
  module Mixin
5
5
  module MdRelations
6
- def dependency(uri, key = nil)
7
- GoodData::MdObject.dependency(uri, key)
6
+ def dependency(uri, key = nil, opts = { :client => client, :project => project })
7
+ GoodData::MdObject.dependency(uri, key, opts)
8
8
  end
9
9
 
10
10
  # Checks for dependency
11
- def dependency?(type, obj)
12
- GoodData::MdObject.dependency?(type, self, obj)
11
+ def dependency?(type, obj, opts = { :client => client, :project => project })
12
+ GoodData::MdObject.dependency?(type, self, obj, opts)
13
13
  end
14
14
 
15
15
  # Returns which objects uses this MD resource
16
- def usedby(key = nil, project = GoodData.project)
17
- dependency("#{project.md['usedby2']}/#{obj_id}", key)
16
+ def usedby(key = nil, opts = { :client => client, :project => project })
17
+ p = opts[:project]
18
+ fail ArgumentError, 'No :project specified' if p.nil?
19
+
20
+ project = GoodData::Project[p, opts]
21
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
22
+
23
+ dependency("#{project.md['usedby2']}/#{obj_id}", key, opts)
18
24
  end
19
25
 
20
26
  alias_method :used_by, :usedby
21
27
 
22
28
  # Returns which objects this MD resource uses
23
- def using(key = nil)
24
- dependency("#{GoodData.project.md['using2']}/#{obj_id}", key)
29
+ def using(key = nil, opts = { :client => client, :project => project })
30
+ project = opts[:project]
31
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
32
+
33
+ dependency("#{project.md['using2']}/#{obj_id}", key, opts)
25
34
  end
26
35
 
27
- def usedby?(obj)
28
- GoodData::MdObject.used_by?(self, obj)
36
+ def usedby?(obj, opts = { :client => client, :project => project })
37
+ GoodData::MdObject.used_by?(self, obj, opts)
29
38
  end
30
39
 
31
40
  alias_method :used_by?, :usedby?
32
41
 
33
42
  # Checks if obj is using this MD resource
34
- def using?(obj)
35
- dependency?(:using, obj)
43
+ def using?(obj, opts = { :client => client, :project => project })
44
+ dependency?(:using, obj, opts)
36
45
  end
37
46
  end
38
47
  end
@@ -1,5 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require_relative 'data_getter'
4
+
3
5
  module GoodData
4
6
  module Mixin
5
7
  module MetaGetter
@@ -1,5 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require_relative 'meta_getter'
4
+
3
5
  module GoodData
4
6
  module Mixin
5
7
  module MetaPropertyReader
@@ -1,5 +1,7 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require_relative 'meta_getter'
4
+
3
5
  module GoodData
4
6
  module Mixin
5
7
  module MetaPropertyWriter
@@ -1,19 +1,41 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require_relative 'root_key_setter'
4
- require_relative 'data_property_reader'
5
- require_relative 'data_property_writer'
6
- require_relative 'meta_property_reader'
7
- require_relative 'meta_property_reader'
3
+ require_relative 'mixins'
8
4
 
9
5
  module GoodData
10
6
  module Mixin
11
7
  module RestResource
12
- include GoodData::Mixin::RootKeySetter
13
- include GoodData::Mixin::DataPropertyReader
14
- include GoodData::Mixin::DataPropertyWriter
15
- include GoodData::Mixin::MetaPropertyReader
16
- include GoodData::Mixin::MetaPropertyWriter
8
+ def self.included(base)
9
+ # Core REST Object Stuff
10
+ base.extend GoodData::Mixin::RootKeySetter
11
+ base.send :include, GoodData::Mixin::RootKeyGetter
12
+ base.send :include, GoodData::Mixin::DataGetter
13
+ base.send :include, GoodData::Mixin::MetaGetter
14
+ base.send :include, GoodData::Mixin::ObjId
15
+ base.send :include, GoodData::Mixin::ContentGetter
16
+ base.send :include, GoodData::Mixin::Timestamps
17
+ base.send :include, GoodData::Mixin::Links
18
+
19
+ base.extend GoodData::Mixin::DataPropertyReader
20
+ base.extend GoodData::Mixin::DataPropertyWriter
21
+ base.extend GoodData::Mixin::MetaPropertyReader
22
+ base.extend GoodData::Mixin::MetaPropertyWriter
23
+
24
+ # MdObject Stuff
25
+ base.send :include, GoodData::Mixin::MdJson
26
+ base.send :include, GoodData::Mixin::NotAttribute
27
+ base.send :include, GoodData::Mixin::NotExportable
28
+ base.send :include, GoodData::Mixin::NotFact
29
+ base.send :include, GoodData::Mixin::NotMetric
30
+ base.send :include, GoodData::Mixin::NotLabel
31
+ base.send :include, GoodData::Mixin::MdRelations
32
+
33
+ base.extend GoodData::Mixin::MdObjId
34
+ base.extend GoodData::Mixin::MdObjectQuery
35
+ base.extend GoodData::Mixin::MdObjectIndexer
36
+ base.extend GoodData::Mixin::MdFinders
37
+ base.extend GoodData::Mixin::MdIdToUri
38
+ end
17
39
  end
18
40
  end
19
41
  end
@@ -4,7 +4,7 @@ module GoodData
4
4
  module Mixin
5
5
  module RootKeyGetter
6
6
  def root_key
7
- raw_data.keys.first
7
+ json.keys.first
8
8
  end
9
9
  end
10
10
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  require_relative '../extensions/big_decimal'
4
4
 
5
+ require_relative '../rest/object'
6
+
5
7
  module GoodData
6
- class DataResult
8
+ class DataResult < Rest::Object
7
9
  attr_reader :data
8
10
 
9
11
  def initialize(data)
@@ -1,9 +1,13 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'cgi'
4
+
3
5
  require_relative 'profile'
4
6
 
7
+ require_relative '../rest/object'
8
+
5
9
  module GoodData
6
- class Domain
10
+ class Domain < GoodData::Rest::Object
7
11
  attr_reader :name
8
12
 
9
13
  USERS_OPTIONS = { :offset => 0, :limit => 1000 }
@@ -13,9 +17,10 @@ module GoodData
13
17
  #
14
18
  # @param domain_name [String] Domain name
15
19
  # @return [String] Domain object instance
16
- def [](domain_name, options = {})
20
+ def [](domain_name, options = { :client => GoodData.connection })
21
+ c = client(options)
17
22
  fail "Using pseudo-id 'all' is not supported by GoodData::Domain" if domain_name.to_s == 'all'
18
- GoodData::Domain.new(domain_name)
23
+ c.create(GoodData::Domain, domain_name)
19
24
  end
20
25
 
21
26
  # Adds user to domain
@@ -71,17 +76,20 @@ module GoodData
71
76
  tmp = opts[:timezone]
72
77
  data[:timezone] = tmp if tmp && !tmp.empty?
73
78
 
79
+ c = client(opts)
80
+
74
81
  # TODO: It will be nice if the API will return us user just newly created
75
82
  url = "/gdc/account/domains/#{opts[:domain]}/users"
76
- response = GoodData.post(url, :accountSetting => data)
83
+ response = c.post(url, :accountSetting => data)
77
84
 
78
- raw = GoodData.get response['uri']
85
+ url = response['uri']
86
+ raw = c.get url
79
87
 
80
88
  # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
81
89
  raw['accountSetting']['links'] = {} unless raw['accountSetting']['links']
82
90
  raw['accountSetting']['links']['self'] = response['uri'] unless raw['accountSetting']['links']['self']
83
91
 
84
- GoodData::Profile.new(raw)
92
+ c.create(GoodData::Profile, raw)
85
93
  end
86
94
 
87
95
  # Finds user in domain by login
@@ -89,12 +97,13 @@ module GoodData
89
97
  # @param domain [String] Domain name
90
98
  # @param login [String] User login
91
99
  # @return [GoodData::Profile] User profile
92
- def find_user_by_login(domain, login)
93
- url = "/gdc/account/domains/#{domain}/users?login=#{login}"
94
- tmp = GoodData.get url
100
+ def find_user_by_login(domain, login, opts = {})
101
+ c = client(opts)
102
+ escaped_login = CGI.escape(login)
103
+ url = "/gdc/account/domains/#{domain}/users?login=#{escaped_login}"
104
+ tmp = c.get url
95
105
  items = tmp['accountSettings']['items'] if tmp['accountSettings']
96
- return GoodData::Profile.new(items.first) if items && items.length > 0
97
- nil
106
+ items && items.length > 0 ? c.factory.create(GoodData::Profile, items.first) : nil
98
107
  end
99
108
 
100
109
  # Returns list of users for domain specified
@@ -103,17 +112,16 @@ module GoodData
103
112
  # @option opts [Number] :offset The subject
104
113
  # @option opts [Number] :limit From address
105
114
  # TODO: Review opts[:limit] functionality
106
- def users(domain, opts = USERS_OPTIONS)
115
+ def users(domain, opts = USERS_OPTIONS.merge(:client => GoodData.connection))
107
116
  result = []
108
117
 
109
- options = USERS_OPTIONS.merge(opts)
110
- offset = 0 || options[:offset]
111
- uri = "/gdc/account/domains/#{domain}/users?offset=#{offset}&limit=#{options[:limit]}"
118
+ offset = 0 || opts[:offset]
119
+ uri = "/gdc/account/domains/#{domain}/users?offset=#{offset}&limit=#{opts[:limit]}"
112
120
  loop do
113
121
  break unless uri
114
- tmp = GoodData.get(uri)
122
+ tmp = client(opts).get(uri)
115
123
  tmp['accountSettings']['items'].each do |account|
116
- result << GoodData::Profile.new(account)
124
+ result << client(opts).create(GoodData::Profile, account)
117
125
  end
118
126
  uri = tmp['accountSettings']['paging']['next']
119
127
  end
@@ -125,7 +133,7 @@ module GoodData
125
133
  # @param [Array<GoodData::Membership>] list List of users
126
134
  # @param [String] default_domain_name Default domain name used when no specified in user
127
135
  # @return [Array<GoodData::User>] List of users created
128
- def users_create(list, default_domain = nil)
136
+ def users_create(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
129
137
  default_domain_name = default_domain.respond_to?(:name) ? default_domain.name : default_domain
130
138
  domains = {}
131
139
  list.map do |user|
@@ -137,9 +145,10 @@ module GoodData
137
145
 
138
146
  # Get domain info from REST, add to cache
139
147
  if domain.nil?
148
+ d = GoodData::Domain[domain_name, opts]
140
149
  domain = {
141
- :domain => GoodData::Domain[domain_name],
142
- :users => GoodData::Domain[domain_name].users
150
+ :domain => d,
151
+ :users => d.users(opts)
143
152
  }
144
153
 
145
154
  domain[:users_map] = Hash[domain[:users].map { |u| [u.email, u] }]
@@ -170,7 +179,7 @@ module GoodData
170
179
  user_data[:authentication_modes] = tmp && !tmp.empty?
171
180
 
172
181
  # Add created user to cache
173
- domain_user = domain[:domain].add_user(user_data)
182
+ domain_user = domain[:domain].add_user(opts.merge(user_data))
174
183
  domain[:users] << domain_user
175
184
  domain[:users_map][user.email] = domain_user
176
185
  end
@@ -222,7 +231,7 @@ module GoodData
222
231
  # pp domain.users
223
232
  #
224
233
  def users(opts = USERS_OPTIONS)
225
- GoodData::Domain.users(name, opts)
234
+ GoodData::Domain.users(name, opts.merge(client: client))
226
235
  end
227
236
 
228
237
  def users_create(list)