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
@@ -9,21 +9,24 @@ module GoodData
9
9
  module Model
10
10
  class ProjectCreator
11
11
  class << self
12
- def migrate(options = {})
13
- spec = options[:spec] || fail('You need to provide spec for migration')
12
+ def migrate(opts = { :client => GoodData.connection, :project => GoodData.project })
13
+ client = opts[:client]
14
+ fail ArgumentError, 'No :client specified' if client.nil?
15
+
16
+ spec = opts[:spec] || fail('You need to provide spec for migration')
14
17
  bp = ProjectBlueprint.new(spec)
15
18
  spec = bp.to_hash
16
19
 
17
20
  fail GoodData::ValidationError, "Blueprint is invalid #{bp.validate.inspect}" unless bp.valid?
18
21
 
19
- token = options[:token]
20
- project = options[:project] || GoodData::Project.create(:title => spec[:title], :auth_token => token)
22
+ token = opts[:token]
23
+ project = opts[:project] || GoodData::Project.create(:title => spec[:title], :auth_token => token, :client => client)
21
24
  fail('You need to specify token for project creation') if token.nil? && project.nil?
22
25
 
23
26
  begin
24
- GoodData.with_project(project) do |p|
27
+ GoodData.with_project(project, opts) do |p|
25
28
  # migrate_date_dimensions(p, spec[:date_dimensions] || [])
26
- migrate_datasets(p, spec)
29
+ migrate_datasets(spec, :project => p, :client => client)
27
30
  load(p, spec)
28
31
  migrate_metrics(p, spec[:metrics] || [])
29
32
  migrate_reports(p, spec[:reports] || [])
@@ -41,40 +44,47 @@ module GoodData
41
44
  end
42
45
  end
43
46
 
44
- def migrate_datasets(project, spec)
47
+ def migrate_datasets(spec, opts = { :client => GoodData.connection })
48
+ client = opts[:client]
49
+ fail ArgumentError, 'No :client specified' if client.nil?
50
+
51
+ p = opts[:project]
52
+ fail ArgumentError, 'No :project specified' if p.nil?
53
+
54
+ project = Project[p, { :client => client }]
55
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
56
+
45
57
  bp = ProjectBlueprint.new(spec)
46
58
  # schema = Schema.load(schema) unless schema.respond_to?(:to_maql_create)
47
59
  # project = GoodData.project unless project
48
- uri = "/gdc/projects/#{GoodData.project.pid}/model/diff"
49
- result = GoodData.post(uri, bp.to_wire)
60
+ uri = "/gdc/projects/#{project.pid}/model/diff"
61
+ result = client.post(uri, bp.to_wire)
62
+
50
63
  link = result['asyncTask']['link']['poll']
51
- response = GoodData.get(link, :process => false)
64
+ response = client.get(link, :process => false)
65
+
52
66
  # pp response
53
67
  while response.code != 200
54
68
  sleep 1
55
- GoodData.connection.retryable(:tries => 3, :on => RestClient::InternalServerError) do
69
+ client.retryable(:tries => 3, :on => RestClient::InternalServerError) do
56
70
  sleep 1
57
- response = GoodData.get(link, :process => false)
71
+ response = client.get(link, :process => false)
58
72
  # pp response
59
73
  end
60
74
  end
61
- response = GoodData.get(link)
62
- ldm_links = GoodData.get project.md[LDM_CTG]
63
- ldm_uri = Links.new(ldm_links)[LDM_MANAGE_CTG]
75
+
76
+ response = client.get(link)
77
+
64
78
  chunks = pick_correct_chunks(response['projectModelDiff']['updateScripts'])
65
79
  chunks['updateScript']['maqlDdlChunks'].each do |chunk|
66
- response = GoodData.post ldm_uri, 'manage' => { 'maql' => chunk }
67
- polling_url = response['entries'].first['link']
68
- polling_result = GoodData.poll_on_response(polling_url) do |body|
69
- body['wTaskStatus']['status'] == 'RUNNING'
70
- end
71
- fail 'Creating dataset failed' if polling_result['wTaskStatus']['status'] == 'ERROR'
80
+ result = project.execute_maql(chunk)
81
+ fail 'Creating dataset failed' if result['wTaskStatus']['status'] == 'ERROR'
72
82
  end
73
83
 
74
84
  bp.datasets.zip(GoodData::Model::ToManifest.to_manifest(bp.to_hash)).each do |ds|
75
85
  dataset = ds[0]
76
86
  manifest = ds[1]
77
- GoodData::ProjectMetadata["manifest_#{dataset.name}"] = manifest.to_json
87
+ GoodData::ProjectMetadata["manifest_#{dataset.name}", :client => client, :project => project] = manifest.to_json
78
88
  end
79
89
  end
80
90
 
@@ -3,21 +3,27 @@
3
3
  module GoodData
4
4
  class ProjectMetadata
5
5
  class << self
6
- def keys
7
- ProjectMetadata[:all].keys
6
+ def keys(opts = { :client => GoodData.connection })
7
+ ProjectMetadata[:all, opts].keys
8
8
  end
9
9
 
10
- def [](key, options = {})
10
+ def [](key, opts = { :client => GoodData.connection })
11
+ client = opts[:client]
12
+ fail ArgumentError, 'No :client specified' if client.nil?
13
+
14
+ project = opts[:project]
15
+ fail ArgumentError, 'No :project specified' if project.nil?
16
+
11
17
  if key == :all
12
- uri = "/gdc/projects/#{GoodData.project.pid}/dataload/metadata"
13
- res = GoodData.get(uri)
18
+ uri = "/gdc/projects/#{project.pid}/dataload/metadata"
19
+ res = client.get(uri)
14
20
  res['metadataItems']['items'].reduce({}) do |memo, i|
15
21
  memo[i['metadataItem']['key']] = i['metadataItem']['value']
16
22
  memo
17
23
  end
18
24
  else
19
- uri = "/gdc/projects/#{GoodData.project.pid}/dataload/metadata/#{key}"
20
- res = GoodData.get(uri)
25
+ uri = "/gdc/projects/#{project.pid}/dataload/metadata/#{key}"
26
+ res = client.get(uri)
21
27
  res['metadataItem']['value']
22
28
  end
23
29
  end
@@ -25,27 +31,33 @@ module GoodData
25
31
  alias_method :get, :[]
26
32
  alias_method :get_key, :[]
27
33
 
28
- def key?(key)
29
- ProjectMetadata[key]
34
+ def key?(key, opts = { :client => GoodData.connection })
35
+ ProjectMetadata[key, opts]
30
36
  true
31
37
  rescue RestClient::ResourceNotFound
32
38
  false
33
39
  end
34
40
 
35
- def []=(key, val)
41
+ def []=(key, opts = { :client => GoodData.connection }, val = nil)
42
+ client = opts[:client]
43
+ fail ArgumentError, 'No :client specified' if client.nil?
44
+
45
+ project = opts[:project]
46
+ fail ArgumentError, 'No :project specified' if project.nil?
47
+
36
48
  data = {
37
49
  :metadataItem => {
38
50
  :key => key,
39
51
  :value => val
40
52
  }
41
53
  }
42
- uri = "/gdc/projects/#{GoodData.project.pid}/dataload/metadata/"
54
+ uri = "/gdc/projects/#{project.pid}/dataload/metadata/"
43
55
  update_uri = uri + key
44
56
 
45
- if key?(key)
46
- GoodData.put(update_uri, data)
57
+ if key?(key, opts)
58
+ client.put(update_uri, data)
47
59
  else
48
- GoodData.post(uri, data)
60
+ client.post(uri, data)
49
61
  end
50
62
  end
51
63
  end
@@ -1,22 +1,21 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'pmap'
4
+
3
5
  require_relative 'profile'
4
6
 
5
- require_relative '../mixins/mixins'
7
+ require_relative '../rest/rest'
8
+
9
+ require_relative '../mixins/rest_resource'
6
10
 
7
11
  module GoodData
8
- class ProjectRole
12
+ class ProjectRole < GoodData::Rest::Object
9
13
  attr_accessor :json
10
14
 
11
- include GoodData::Mixin::RestGetters
12
-
13
- class << self
14
- include GoodData::Mixin::RestResource
15
- end
15
+ include GoodData::Mixin::RestResource
16
16
 
17
- ProjectRole.root_key :projectRole
17
+ root_key :projectRole
18
18
 
19
- include GoodData::Mixin::RootKeyGetter
20
19
  include GoodData::Mixin::Author
21
20
  include GoodData::Mixin::Contributor
22
21
  include GoodData::Mixin::Timestamps
@@ -25,22 +24,21 @@ module GoodData
25
24
  @json = json
26
25
  end
27
26
 
28
- ProjectRole.data_property_reader :permissions
27
+ data_property_reader :permissions
29
28
 
30
- ProjectRole.metadata_property_reader :identifier, :title, :summary
29
+ metadata_property_reader :identifier, :title, :summary
31
30
 
32
31
  # Gets Users with this Role
33
32
  #
34
33
  # @return [Array<GoodData::Profile>] List of users
35
34
  def users
36
- res = []
37
35
  url = data['links']['roleUsers']
38
- tmp = GoodData.get url
39
- tmp['associatedUsers']['users'].each do |user_url|
40
- user = GoodData.get user_url
41
- res << GoodData::Profile.new(user)
36
+ tmp = client.get url
37
+ tmp['associatedUsers']['users'].pmap do |user_url|
38
+ url = user_url
39
+ user = client.get url
40
+ client.create(GoodData::Profile, user)
42
41
  end
43
- res
44
42
  end
45
43
 
46
44
  # Gets Raw object URI
@@ -85,6 +85,10 @@ module GoodData
85
85
  differences
86
86
  end
87
87
 
88
+ def empty?
89
+ false
90
+ end
91
+
88
92
  private
89
93
 
90
94
  def each_level(table, level, children, lookup)
@@ -1,7 +1,10 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require_relative '../rest/resource'
4
+ require_relative '../extensions/hash'
5
+
3
6
  module GoodData
4
- class Schedule
7
+ class Schedule < Rest::Resource
5
8
  attr_reader :dirty, :data
6
9
 
7
10
  alias_method :json, :data
@@ -12,26 +15,44 @@ module GoodData
12
15
  # Looks for schedule
13
16
  # @param id [String] URL, ID of schedule or :all
14
17
  # @return [GoodData::Schedule|Array<GoodData::Schedule>] List of schedules
15
- def [](id, options = {})
18
+ def [](id, opts = { :client => GoodData.connection, :project => GoodData.project })
19
+ c = client(opts)
20
+ fail ArgumentError, 'No :client specified' if c.nil?
21
+
22
+ p = opts[:project]
23
+ fail ArgumentError, 'No :project specified' if p.nil?
24
+
25
+ project = GoodData::Project[p, opts]
26
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
27
+
16
28
  if id == :all
17
- GoodData::Schedule.all
29
+ GoodData::Schedule.all(opts)
18
30
  else
19
31
  if id =~ %r{\/gdc\/projects\/[a-zA-Z\d]+\/schedules\/?[a-zA-Z\d]*}
20
32
  url = id
21
- tmp = GoodData.get url
22
- return GoodData::Schedule.new(tmp)
33
+ tmp = c.get url
34
+ return c.create(GoodData::Schedule, tmp)
23
35
  end
24
36
 
25
- tmp = GoodData.get "/gdc/projects/#{GoodData.project.pid}/schedules/#{id}"
26
- GoodData::Schedule.new(tmp)
37
+ tmp = c.get "/gdc/projects/#{project.pid}/schedules/#{id}"
38
+ c.create(GoodData::Schedule, tmp, project: project)
27
39
  end
28
40
  end
29
41
 
30
42
  # Returns list of all schedules for active project
31
43
  # @return [Array<GoodData::Schedule>] List of schedules
32
- def all
33
- tmp = GoodData.get "/gdc/projects/#{GoodData.project.pid}/schedules"
34
- tmp['schedules']['items'].map { |schedule| GoodData::Schedule.new(schedule) }
44
+ def all(opts = { :client => GoodData.connection, :project => GoodData.project })
45
+ c = client(opts)
46
+ fail ArgumentError, 'No :client specified' if c.nil?
47
+
48
+ p = opts[:project]
49
+ fail ArgumentError, 'No :project specified' if p.nil?
50
+
51
+ project = GoodData::Project[p, opts]
52
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
53
+
54
+ tmp = c.get "/gdc/projects/#{project.pid}/schedules"
55
+ tmp['schedules']['items'].map { |schedule| c.create(GoodData::Schedule, schedule) }
35
56
  end
36
57
 
37
58
  # Creates new schedules from parameters passed
@@ -42,6 +63,15 @@ module GoodData
42
63
  # @param options [Hash] Optional options
43
64
  # @return [GoodData::Schedule] New GoodData::Schedule instance
44
65
  def create(process_id, cron, executable, options = {})
66
+ c = client(options)
67
+ fail ArgumentError, 'No :client specified' if c.nil?
68
+
69
+ p = options[:project]
70
+ fail ArgumentError, 'No :project specified' if p.nil?
71
+
72
+ project = GoodData::Project[p, options]
73
+ fail ArgumentError, 'Wrong :project specified' if project.nil?
74
+
45
75
  default_opts = {
46
76
  :type => 'MSETL',
47
77
  :timezone => 'UTC',
@@ -78,7 +108,7 @@ module GoodData
78
108
  default[:params] = default_params
79
109
 
80
110
  json = {
81
- 'schedule' => default.merge(options)
111
+ 'schedule' => default.merge(options.except(:project, :client))
82
112
  }
83
113
 
84
114
  tmp = json['schedule'][:params]['PROCESS_ID']
@@ -96,13 +126,13 @@ module GoodData
96
126
  tmp = json['schedule'][:type]
97
127
  fail 'Schedule type has to be provided' if tmp.nil? || tmp.empty?
98
128
 
99
- url = "/gdc/projects/#{GoodData.project.pid}/schedules"
100
- res = GoodData.post url, json
129
+ url = "/gdc/projects/#{project.pid}/schedules"
130
+ res = c.post url, json
101
131
 
102
132
  fail 'Unable to create new schedule' if res.nil?
103
133
 
104
- new_obj_json = GoodData.get res['schedule']['links']['self']
105
- GoodData::Schedule.new(new_obj_json)
134
+ new_obj_json = c.get res['schedule']['links']['self']
135
+ c.create(GoodData::Schedule, new_obj_json, client: c, project: p)
106
136
  end
107
137
  end
108
138
 
@@ -111,12 +141,13 @@ module GoodData
111
141
  # @param json [Object] Raw JSON
112
142
  # @return [GoodData::Schedule] New GoodData::Schedule instance
113
143
  def initialize(json)
144
+ super
114
145
  @json = json
115
146
  end
116
147
 
117
148
  # Deletes schedule
118
149
  def delete
119
- GoodData.delete uri
150
+ client.delete uri
120
151
  end
121
152
 
122
153
  # Executes schedule
@@ -126,9 +157,9 @@ module GoodData
126
157
  data = {
127
158
  :execution => {}
128
159
  }
129
- execution = GoodData.post(execution_url, data)
130
- GoodData.poll_on_response(execution['execution']['links']['self']) do |body|
131
- body['execution'] && body['execution']['status'] == 'RUNNING'
160
+ execution = client.post(execution_url, data)
161
+ client.poll_on_response(execution['execution']['links']['self']) do |body|
162
+ body['execution'] && (body['execution']['status'] == 'RUNNING' || body['execution']['status'] == 'SCHEDULED')
132
163
  end
133
164
  end
134
165
 
@@ -239,7 +270,7 @@ module GoodData
239
270
  def executions
240
271
  if @json
241
272
  url = @json['schedule']['links']['executions']
242
- res = GoodData.get url
273
+ res = client.get url
243
274
  res['executions']['items']
244
275
  end
245
276
  end
@@ -199,14 +199,13 @@ module GoodData
199
199
  # datasets with or without anchor
200
200
  #
201
201
  # @return [Boolean]
202
- def count
202
+ def count(project)
203
203
  id = if anchor?
204
204
  GoodData::Model.identifier_for(to_hash, anchor)
205
205
  else
206
206
  GoodData::Model.identifier_for(to_hash, type: :anchor_no_label)
207
207
  end
208
- # binding.pry
209
- attribute = GoodData::Attribute[id]
208
+ attribute = project.attributes(id)
210
209
  attribute.create_metric.execute
211
210
  end
212
211
 
@@ -261,6 +260,13 @@ module GoodData
261
260
  DatasetBlueprint.find_column_by_type(to_hash, type, all)
262
261
  end
263
262
 
263
+ # Returns identifier for dataset
264
+ #
265
+ # @return [String] identifier
266
+ def identifier
267
+ GoodData::Model.identifier_for(to_hash)
268
+ end
269
+
264
270
  # Creates a DatasetBlueprint
265
271
  #
266
272
  # @param dataset [Hash] Dataset blueprint
@@ -0,0 +1,37 @@
1
+ # Rest
2
+
3
+ Proof of Concept of GoodWay of dealing with non-perfect REST Endpoints
4
+
5
+ ## Terminology
6
+
7
+ Terms like 'MUST', 'MUST NOT', 'SHALL', 'SHALL NOT' are used as defined in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt)
8
+
9
+ ## Architecture
10
+
11
+ There are few basic classes.
12
+
13
+ - Connection
14
+ - Client
15
+ - Factory
16
+ - Object
17
+ - Resource
18
+
19
+ ## Connection
20
+
21
+ Low-level network connection
22
+
23
+ ## Client
24
+
25
+ User's interface to GoodData Platform.
26
+
27
+ ## Factory
28
+
29
+ Authority responsible for creating Object bounded to some Connection.
30
+
31
+ ## Object
32
+
33
+ Remote REST-like accessible content.
34
+
35
+ ## Resource
36
+
37
+ Objects which are (at least mimicking to be) first class citizen REST Resource with full CRUD