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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -1
- data/README.md +10 -2
- data/TODO.md +32 -0
- data/gooddata.gemspec +5 -0
- data/lib/gooddata.rb +4 -0
- data/lib/gooddata/app/app.rb +12 -0
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +4 -3
- data/lib/gooddata/bricks/middleware/restforce_middleware.rb +2 -1
- data/lib/gooddata/cli/commands/console_cmd.rb +23 -5
- data/lib/gooddata/cli/commands/domain_cmd.rb +9 -10
- data/lib/gooddata/cli/commands/process_cmd.rb +11 -9
- data/lib/gooddata/cli/commands/project_cmd.rb +25 -27
- data/lib/gooddata/cli/commands/projects_cmd.rb +2 -2
- data/lib/gooddata/cli/commands/run_ruby_cmd.rb +1 -1
- data/lib/gooddata/cli/commands/user_cmd.rb +2 -2
- data/lib/gooddata/cli/hooks.rb +4 -2
- data/lib/gooddata/cli/shared.rb +1 -1
- data/lib/gooddata/cli/terminal.rb +1 -1
- data/lib/gooddata/commands/api.rb +1 -1
- data/lib/gooddata/commands/auth.rb +4 -28
- data/lib/gooddata/commands/domain.rb +9 -4
- data/lib/gooddata/commands/process.rb +26 -23
- data/lib/gooddata/commands/project.rb +74 -50
- data/lib/gooddata/commands/projects.rb +3 -2
- data/lib/gooddata/commands/role.rb +9 -3
- data/lib/gooddata/commands/user.rb +6 -4
- data/lib/gooddata/connection.rb +11 -45
- data/lib/gooddata/core/logging.rb +0 -1
- data/lib/gooddata/core/project.rb +22 -22
- data/lib/gooddata/core/rest.rb +9 -8
- data/lib/gooddata/core/user.rb +0 -11
- data/lib/gooddata/exceptions/project_not_found.rb +1 -0
- data/lib/gooddata/extensions/enumerable.rb +10 -0
- data/lib/gooddata/extensions/hash.rb +25 -0
- data/lib/gooddata/goodzilla/goodzilla.rb +4 -4
- data/lib/gooddata/helper/class_helper.rb +1 -0
- data/lib/gooddata/helper/helpers.rb +8 -0
- data/lib/gooddata/helpers/auth_helpers.rb +41 -0
- data/lib/gooddata/mixins/author.rb +1 -1
- data/lib/gooddata/mixins/contributor.rb +1 -1
- data/lib/gooddata/mixins/data_property_reader.rb +2 -0
- data/lib/gooddata/mixins/data_property_writer.rb +2 -0
- data/lib/gooddata/mixins/inspector.rb +49 -0
- data/lib/gooddata/mixins/md_finders.rb +16 -8
- data/lib/gooddata/mixins/md_id_to_uri.rb +12 -4
- data/lib/gooddata/mixins/md_object_indexer.rb +15 -4
- data/lib/gooddata/mixins/md_object_query.rb +42 -20
- data/lib/gooddata/mixins/md_relations.rb +21 -12
- data/lib/gooddata/mixins/meta_getter.rb +2 -0
- data/lib/gooddata/mixins/meta_property_reader.rb +2 -0
- data/lib/gooddata/mixins/meta_property_writer.rb +2 -0
- data/lib/gooddata/mixins/rest_resource.rb +32 -10
- data/lib/gooddata/mixins/root_key_getter.rb +1 -1
- data/lib/gooddata/models/data_result.rb +3 -1
- data/lib/gooddata/models/domain.rb +31 -22
- data/lib/gooddata/models/empty_result.rb +22 -0
- data/lib/gooddata/models/invitation.rb +11 -9
- data/lib/gooddata/models/links.rb +5 -3
- data/lib/gooddata/models/membership.rb +23 -28
- data/lib/gooddata/models/metadata.rb +35 -35
- data/lib/gooddata/models/metadata/attribute.rb +10 -8
- data/lib/gooddata/models/metadata/dashboard.rb +1 -1
- data/lib/gooddata/models/metadata/fact.rb +3 -3
- data/lib/gooddata/models/metadata/label.rb +4 -4
- data/lib/gooddata/models/metadata/metric.rb +76 -38
- data/lib/gooddata/models/metadata/report.rb +52 -17
- data/lib/gooddata/models/metadata/report_definition.rb +178 -28
- data/lib/gooddata/models/model.rb +13 -6
- data/lib/gooddata/models/process.rb +93 -30
- data/lib/gooddata/models/profile.rb +18 -20
- data/lib/gooddata/models/project.rb +344 -127
- data/lib/gooddata/models/project_creator.rb +32 -22
- data/lib/gooddata/models/project_metadata.rb +26 -14
- data/lib/gooddata/models/project_role.rb +15 -17
- data/lib/gooddata/models/report_data_result.rb +4 -0
- data/lib/gooddata/models/schedule.rb +51 -20
- data/lib/gooddata/models/schema_blueprint.rb +9 -3
- data/lib/gooddata/rest/README.md +37 -0
- data/lib/gooddata/rest/client.rb +318 -0
- data/lib/gooddata/rest/connection.rb +235 -0
- data/lib/gooddata/rest/connections/connections.rb +8 -0
- data/lib/gooddata/rest/connections/dummy_connection.rb +52 -0
- data/lib/gooddata/rest/connections/rest_client_connection.rb +177 -0
- data/lib/gooddata/rest/object.rb +32 -0
- data/lib/gooddata/rest/object_factory.rb +67 -0
- data/lib/gooddata/rest/resource.rb +17 -0
- data/lib/gooddata/rest/rest.rb +20 -0
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/cc/data/source/commits.csv +4 -0
- data/spec/data/cc/data/source/devs.csv +4 -0
- data/spec/data/cc/data/source/repos.csv +3 -0
- data/spec/data/cc/devel.prm +0 -0
- data/spec/data/cc/graph/graph.grf +11 -0
- data/spec/data/cc/workspace.prm +19 -0
- data/spec/data/hello_world_process/hello_world.rb +1 -0
- data/spec/data/hello_world_process/hello_world.zip +0 -0
- data/spec/data/users.csv +12 -12
- data/spec/helpers/connection_helper.rb +6 -0
- data/spec/helpers/process_helper.rb +12 -0
- data/spec/helpers/project_helper.rb +2 -2
- data/spec/integration/command_projects_spec.rb +11 -9
- data/spec/integration/create_from_template_spec.rb +6 -2
- data/spec/integration/full_process_schedule_spec.rb +49 -36
- data/spec/integration/full_project_spec.rb +221 -256
- data/spec/integration/partial_md_export_import_spec.rb +18 -17
- data/spec/logging_in_logging_out_spec.rb +17 -8
- data/spec/spec_helper.rb +4 -2
- data/spec/unit/cli/commands/cmd_api_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_auth_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_domain_spec.rb +29 -3
- data/spec/unit/cli/commands/cmd_process_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_project_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_role_spec.rb +13 -2
- data/spec/unit/cli/commands/cmd_run_ruby_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_scaffold_spec.rb +1 -1
- data/spec/unit/cli/commands/cmd_user_spec.rb +1 -1
- data/spec/unit/commands/command_api_spec.rb +0 -19
- data/spec/unit/commands/command_auth_spec.rb +20 -13
- data/spec/unit/commands/command_dataset_spec.rb +2 -2
- data/spec/unit/commands/command_process_spec.rb +24 -21
- data/spec/unit/commands/command_projects_spec.rb +2 -2
- data/spec/unit/commands/command_scaffold_spec.rb +2 -2
- data/spec/unit/commands/command_user_spec.rb +3 -3
- data/spec/unit/core/connection_spec.rb +9 -10
- data/spec/unit/core/project_spec.rb +8 -4
- data/spec/unit/core/rest_spec.rb +6 -6
- data/spec/unit/models/domain_spec.rb +14 -7
- data/spec/unit/models/invitation_spec.rb +2 -2
- data/spec/unit/models/membership_spec.rb +5 -5
- data/spec/unit/models/metric_spec.rb +92 -0
- data/spec/unit/models/profile_spec.rb +25 -21
- data/spec/unit/models/project_blueprint_spec.rb +6 -6
- data/spec/unit/models/project_role_spec.rb +3 -5
- data/spec/unit/models/project_spec.rb +43 -37
- data/spec/unit/models/schedule_spec.rb +58 -107
- data/spec/unit/rest/resource_spec.rb +6 -0
- metadata +87 -10
- data/lib/gooddata/cli/commands/role_cmd.rb +0 -28
- data/lib/gooddata/core/connection.rb +0 -392
- data/lib/gooddata/core/threaded.rb +0 -14
- data/lib/gooddata/models/md_object.rb +0 -25
- data/lib/gooddata/models/metadata/folder.rb +0 -24
- data/spec/unit/models/md_object_spec.rb +0 -55
- 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
|
-
|
|
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.
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
28
|
-
fail
|
|
29
|
-
|
|
30
|
-
options[:
|
|
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
|
-
|
|
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,
|
|
62
|
-
|
|
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
|
-
|
|
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,
|
|
17
|
-
|
|
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
|
-
|
|
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,19 +1,41 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
-
require_relative '
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
@@ -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
|
|
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 =
|
|
83
|
+
response = c.post(url, :accountSetting => data)
|
|
77
84
|
|
|
78
|
-
|
|
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
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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 =
|
|
122
|
+
tmp = client(opts).get(uri)
|
|
115
123
|
tmp['accountSettings']['items'].each do |account|
|
|
116
|
-
result << GoodData::Profile
|
|
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 =>
|
|
142
|
-
: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)
|