gooddata 0.6.6 → 0.6.7

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGELOG.markdown → CHANGELOG.md} +6 -1
  3. data/lib/gooddata/cli/commands/project_cmd.rb +6 -29
  4. data/lib/gooddata/commands/project.rb +36 -44
  5. data/lib/gooddata/connection.rb +7 -0
  6. data/lib/gooddata/core/connection.rb +3 -0
  7. data/lib/gooddata/core/rest.rb +38 -19
  8. data/lib/gooddata/mixins/md_object_query.rb +3 -2
  9. data/lib/gooddata/models/metadata/dashboard.rb +3 -8
  10. data/lib/gooddata/models/metadata/report.rb +1 -6
  11. data/lib/gooddata/models/model.rb +5 -4
  12. data/lib/gooddata/models/process.rb +10 -14
  13. data/lib/gooddata/models/project.rb +34 -26
  14. data/lib/gooddata/models/project_blueprint.rb +14 -7
  15. data/lib/gooddata/models/project_creator.rb +2 -6
  16. data/lib/gooddata/models/schedule.rb +13 -2
  17. data/lib/gooddata/version.rb +1 -1
  18. data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
  19. data/spec/data/ruby_process/process.rb +2 -0
  20. data/spec/data/ruby_process/stuff.txt +1 -0
  21. data/spec/integration/full_process_schedule_spec.rb +69 -0
  22. data/spec/integration/full_project_spec.rb +14 -5
  23. data/spec/unit/models/schedule_spec.rb +7 -30
  24. metadata +7 -66
  25. data/doc/.gitignore +0 -1
  26. data/doc/css/.gitkeepme +0 -1
  27. data/doc/images/.gitkeepme +0 -1
  28. data/doc/images/background.png +0 -0
  29. data/doc/images/bg-callout-button.png +0 -0
  30. data/doc/images/header-logo.png +0 -0
  31. data/doc/images/logo-image.png +0 -0
  32. data/doc/js/.gitkeepme +0 -1
  33. data/doc/pages/GET_STARTED.md +0 -310
  34. data/doc/pages/HOMEPAGE.md +0 -77
  35. data/doc/pages/TUTORIALS.md +0 -52
  36. data/doc/pages/tutorial/BRICKS.md +0 -260
  37. data/doc/pages/tutorial/CREATING_A_MODEL.md +0 -81
  38. data/doc/pages/tutorial/CRUNCHING_NUMBERS.md +0 -231
  39. data/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md +0 -120
  40. data/doc/pages/tutorial/YOUR_FIRST_PROJECT.md +0 -53
  41. data/doc/templates/default/class/dot/setup.rb +0 -6
  42. data/doc/templates/default/class/dot/superklass.erb +0 -3
  43. data/doc/templates/default/class/setup.rb +0 -37
  44. data/doc/templates/default/class/text/setup.rb +0 -11
  45. data/doc/templates/default/class/text/subclasses.erb +0 -5
  46. data/doc/templates/default/constant/text/header.erb +0 -11
  47. data/doc/templates/default/constant/text/setup.rb +0 -3
  48. data/doc/templates/default/docstring/setup.rb +0 -51
  49. data/doc/templates/default/docstring/text/abstract.erb +0 -2
  50. data/doc/templates/default/docstring/text/deprecated.erb +0 -2
  51. data/doc/templates/default/docstring/text/index.erb +0 -2
  52. data/doc/templates/default/docstring/text/note.erb +0 -4
  53. data/doc/templates/default/docstring/text/private.erb +0 -2
  54. data/doc/templates/default/docstring/text/returns_void.erb +0 -1
  55. data/doc/templates/default/docstring/text/text.erb +0 -1
  56. data/doc/templates/default/docstring/text/todo.erb +0 -4
  57. data/doc/templates/default/layout/dot/header.erb +0 -6
  58. data/doc/templates/default/layout/dot/setup.rb +0 -14
  59. data/doc/templates/default/method/setup.rb +0 -3
  60. data/doc/templates/default/method/text/header.erb +0 -1
  61. data/doc/templates/default/method_details/setup.rb +0 -11
  62. data/doc/templates/default/method_details/text/header.erb +0 -10
  63. data/doc/templates/default/method_details/text/method_signature.erb +0 -12
  64. data/doc/templates/default/method_details/text/setup.rb +0 -10
  65. data/doc/templates/default/module/dot/child.erb +0 -1
  66. data/doc/templates/default/module/dot/dependencies.erb +0 -3
  67. data/doc/templates/default/module/dot/header.erb +0 -6
  68. data/doc/templates/default/module/dot/info.erb +0 -14
  69. data/doc/templates/default/module/dot/setup.rb +0 -14
  70. data/doc/templates/default/module/setup.rb +0 -164
  71. data/doc/templates/default/module/text/children.erb +0 -10
  72. data/doc/templates/default/module/text/class_meths_list.erb +0 -8
  73. data/doc/templates/default/module/text/extends.erb +0 -8
  74. data/doc/templates/default/module/text/header.erb +0 -7
  75. data/doc/templates/default/module/text/includes.erb +0 -8
  76. data/doc/templates/default/module/text/instance_meths_list.erb +0 -8
  77. data/doc/templates/default/module/text/setup.rb +0 -12
  78. data/doc/templates/default/root/dot/child.erb +0 -3
  79. data/doc/templates/default/root/dot/setup.rb +0 -5
  80. data/doc/templates/default/tags/setup.rb +0 -55
  81. data/doc/templates/default/tags/text/example.erb +0 -12
  82. data/doc/templates/default/tags/text/index.erb +0 -1
  83. data/doc/templates/default/tags/text/option.erb +0 -20
  84. data/doc/templates/default/tags/text/overload.erb +0 -19
  85. data/doc/templates/default/tags/text/see.erb +0 -11
  86. data/doc/templates/default/tags/text/tag.erb +0 -13
@@ -10,15 +10,22 @@ module GoodData
10
10
  #
11
11
  # @param spec [String | Hash] value of an label you are looking for
12
12
  # @return [GoodData::Model::ProjectBlueprint]
13
- def self.from_json(spec)
14
- if spec.is_a?(String)
15
- if File.file?(spec)
16
- ProjectBlueprint.new(MultiJson.load(File.read(spec), :symbolize_keys => true))
13
+ class << self
14
+ def from_json(spec)
15
+ if spec.is_a?(String)
16
+ if File.file?(spec)
17
+ ProjectBlueprint.new(MultiJson.load(File.read(spec), :symbolize_keys => true))
18
+ else
19
+ ProjectBlueprint.new(MultiJson.load(spec, :symbolize_keys => true))
20
+ end
17
21
  else
18
- ProjectBlueprint.new(MultiJson.load(spec, :symbolize_keys => true))
22
+ ProjectBlueprint.new(spec)
19
23
  end
20
- else
21
- ProjectBlueprint.new(spec)
24
+ end
25
+
26
+ def build(title, &block)
27
+ pb = ProjectBuilder.create(title, &block)
28
+ pb.to_blueprint
22
29
  end
23
30
  end
24
31
 
@@ -65,14 +65,10 @@ module GoodData
65
65
  chunks['updateScript']['maqlDdlChunks'].each do |chunk|
66
66
  response = GoodData.post ldm_uri, 'manage' => { 'maql' => chunk }
67
67
  polling_url = response['entries'].first['link']
68
-
69
- polling_result = GoodData.get(polling_url)
70
- while polling_result['wTaskStatus']['status'] == 'RUNNING'
71
- sleep(3)
72
- polling_result = GoodData.get(polling_url)
68
+ polling_result = GoodData.poll_on_response(polling_url) do |body|
69
+ body['wTaskStatus']['status'] == 'RUNNING'
73
70
  end
74
71
  fail 'Creating dataset failed' if polling_result['wTaskStatus']['status'] == 'ERROR'
75
-
76
72
  end
77
73
 
78
74
  bp.datasets.zip(GoodData::Model::ToManifest.to_manifest(bp.to_hash)).each do |ds|
@@ -2,7 +2,11 @@
2
2
 
3
3
  module GoodData
4
4
  class Schedule
5
- attr_reader :dirty
5
+ attr_reader :dirty, :data
6
+
7
+ alias_method :json, :data
8
+ alias_method :raw_data, :data
9
+ alias_method :to_hash, :data
6
10
 
7
11
  class << self
8
12
  # Looks for schedule
@@ -122,7 +126,10 @@ module GoodData
122
126
  data = {
123
127
  :execution => {}
124
128
  }
125
- GoodData.post execution_url, data
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'
132
+ end
126
133
  end
127
134
 
128
135
  # Returns execution URL
@@ -296,5 +303,9 @@ module GoodData
296
303
  def uri
297
304
  @json['schedule']['links']['self'] if @json && @json['schedule'] && @json['schedule']['links']
298
305
  end
306
+
307
+ def ==(other)
308
+ other.respond_to?(:uri) && other.uri == uri && other.respond_to?(:to_hash) && other.to_hash == to_hash
309
+ end
299
310
  end
300
311
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # GoodData Module
4
4
  module GoodData
5
- VERSION = '0.6.6'
5
+ VERSION = '0.6.7'
6
6
 
7
7
  class << self
8
8
  # Version
@@ -0,0 +1 @@
1
+ Hello Ruby from the deep
@@ -0,0 +1,2 @@
1
+ puts File.read('./stuff.txt')
2
+ puts File.read('./deep_files/deep_stuff.txt')
@@ -0,0 +1 @@
1
+ Hello Ruby executors
@@ -0,0 +1,69 @@
1
+ require 'gooddata'
2
+
3
+ describe "Full process and schedule exercise", :constraint => 'slow' do
4
+ before(:all) do
5
+ ConnectionHelper::create_default_connection
6
+ @project = GoodData::Project.create(title: 'Project for schedule testing', auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
7
+ @process = GoodData::Process.with_deploy('./spec/data/ruby_process',
8
+ type: 'RUBY',
9
+ project: @project,
10
+ name: 'Test ETL Process')
11
+ end
12
+
13
+ after(:all) do
14
+ @process.delete if @process
15
+ @project.delete if @project
16
+ end
17
+
18
+ it "should be able to execute a process" do
19
+ pending('Account cannot execute Ruby')
20
+ GoodData.with_project(@project) do |project|
21
+ result = @process.execute(@process.executables.first)
22
+ log = GoodData.get(result['executionDetail']['links']['log'])
23
+ expect(log.index('Hello Ruby executors')).not_to eq nil
24
+ expect(log.index('Hello Ruby from the deep')).not_to eq nil
25
+ end
26
+ end
27
+
28
+ it "should be able to grab executables" do
29
+ pending('Account cannot execute Ruby')
30
+ expect(@process.executables).to eq ['./process.rb']
31
+ end
32
+
33
+ it "should have empty schedules on deploy" do
34
+ pending('Account cannot execute Ruby')
35
+ GoodData.with_project(@project) do |project|
36
+ expect(@process.schedules).to eq []
37
+ end
38
+ end
39
+
40
+ it "should be able to schedule" do
41
+ pending('Account cannot execute Ruby')
42
+ GoodData.with_project(@project) do |project|
43
+ schedule = @process.create_schedule('0 15 27 7 *', @process.executables.first)
44
+ expect(@process.schedules.count).to eq 1
45
+ expect(@process.schedules).to eq [schedule]
46
+ schedule.delete
47
+ end
48
+ end
49
+
50
+ it "should be possible to read status of schedule" do
51
+ pending('Account cannot execute Ruby')
52
+ GoodData.with_project(@project) do |project|
53
+ schedule = @process.create_schedule('0 15 27 7 *', @process.executables.first)
54
+ expect(schedule.state).to eq 'ENABLED'
55
+ schedule.delete
56
+ end
57
+ end
58
+
59
+ it "should be possible to execute schedule" do
60
+ pending('Account cannot execute Ruby')
61
+ GoodData.with_project(@project) do |project|
62
+ schedule = @process.create_schedule('0 15 27 7 *', @process.executables.first)
63
+ result = schedule.execute
64
+ log = GoodData.get(result['execution']['log'])
65
+ expect(log.index('Hello Ruby executors')).not_to eq nil
66
+ expect(log.index('Hello Ruby from the deep')).not_to eq nil
67
+ end
68
+ end
69
+ end
@@ -2,10 +2,10 @@ require 'gooddata'
2
2
 
3
3
  describe "Full project implementation", :constraint => 'slow' do
4
4
  before(:all) do
5
- @spec = JSON.parse(File.read("./spec/data/test_project_model_spec.json"), :symbolize_names => true)
6
- @invalid_spec = JSON.parse(File.read("./spec/data/blueprint_invalid.json"), :symbolize_names => true)
5
+ @spec = JSON.parse(File.read('./spec/data/test_project_model_spec.json'), :symbolize_names => true)
6
+ @invalid_spec = JSON.parse(File.read('./spec/data/blueprint_invalid.json'), :symbolize_names => true)
7
7
  ConnectionHelper::create_default_connection
8
- @project = GoodData::Model::ProjectCreator.migrate({:spec => @spec, :token => ConnectionHelper::GD_PROJECT_TOKEN})
8
+ @project = GoodData::Model::ProjectCreator.migrate(:spec => @spec, :token => ConnectionHelper::GD_PROJECT_TOKEN)
9
9
  end
10
10
 
11
11
  after(:all) do
@@ -282,8 +282,8 @@ describe "Full project implementation", :constraint => 'slow' do
282
282
  l = attribute.primary_label
283
283
  value = l.values.first[:value]
284
284
  l.find_element_value(l.find_value_uri(value)).should == value
285
- expect(l.value?(value)).should == true
286
- expect(l.value?("DEFINITELY NON EXISTENT VALUE HOPEFULLY")).should == false
285
+ expect(l.value?(value)).to eq true
286
+ expect(l.value?("DEFINITELY NON EXISTENT VALUE HOPEFULLY")).to eq false
287
287
  end
288
288
  end
289
289
 
@@ -385,4 +385,13 @@ describe "Full project implementation", :constraint => 'slow' do
385
385
  m_cloned.execute.should == cloned.execute
386
386
  end
387
387
  end
388
+
389
+ it "should be able to clone a project" do
390
+ GoodData.with_project(@project) do |p|
391
+ title = 'My new clone proejct'
392
+ cloned_project = p.clone(title: title, auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
393
+ expect(cloned_project.title).to eq title
394
+ cloned_project.delete
395
+ end
396
+ end
388
397
  end
@@ -1,6 +1,6 @@
1
1
  require 'gooddata/models/schedule'
2
2
 
3
- describe GoodData::Schedule, :broken => true do
3
+ describe GoodData::Schedule do
4
4
 
5
5
  TEST_CRON = '0 15 27 7 *'
6
6
 
@@ -16,10 +16,10 @@ describe GoodData::Schedule, :broken => true do
16
16
  }
17
17
 
18
18
 
19
- TEST_PROCESS_ID = 'f12975d2-5958-4248-9c3d-4c8f2e1f067d'
19
+ TEST_PROCESS_ID = 'dc143d80-58a1-4acd-96b6-8d11fc4571de'
20
20
 
21
- SCHEDULE_ID = '53642303e4b0ae3190e464a8'
22
- SCHEDULE_URL = '/gdc/projects/wgqhml3se0035s8n5byqdq0j0ob5jam4/schedules/53642303e4b0ae3190e464a8'
21
+ SCHEDULE_ID = '53e03c25e4b0c7f987a2f6fd'
22
+ SCHEDULE_URL = '/gdc/projects/we1vvh4il93r0927r809i3agif50d7iz/schedules/53e03c25e4b0c7f987a2f6fd'
23
23
 
24
24
  before(:each) do
25
25
  ConnectionHelper.create_default_connection
@@ -27,7 +27,7 @@ describe GoodData::Schedule, :broken => true do
27
27
  GoodData.project = ProjectHelper::PROJECT_ID
28
28
 
29
29
  @project = GoodData.project
30
- @project_executable = "#{@project.title}/graph/graph.grf"
30
+ @project_executable = "./graph/graph.grf"
31
31
  end
32
32
 
33
33
  after(:each) do
@@ -399,25 +399,9 @@ describe GoodData::Schedule, :broken => true do
399
399
  end
400
400
 
401
401
  it 'Should save a schedule' do
402
- saved = false
403
- url = "/gdc/projects/#{ProjectHelper::PROJECT_ID}/schedules"
404
- req = GoodData.get url
405
- schedules = req['schedules']['items']
406
- schedules.each do |schedule|
407
- schedule_self = schedule['schedule']['links']['self']
408
- if schedule_self == @schedule.uri
409
- saved = true
410
- end
411
- end
412
-
413
- @schedule.timezone = 'UTC'
414
-
415
- @schedule.save
416
-
417
- expect(saved).to be(true)
418
-
402
+ expect(GoodData::Schedule[@schedule.uri]).to eq @schedule
403
+ expect(GoodData::Project[ProjectHelper::PROJECT_ID].schedules).to include(@schedule)
419
404
  end
420
-
421
405
  end
422
406
 
423
407
  describe '#state' do
@@ -519,12 +503,8 @@ describe GoodData::Schedule, :broken => true do
519
503
  it 'Should return reschedule as integer' do
520
504
  res = @schedule.reschedule
521
505
  res.should_not be_nil
522
- res.should_not be_empty
523
506
  res.should be_a_kind_of(Integer)
524
507
  end
525
-
526
-
527
-
528
508
  end
529
509
 
530
510
  describe '#reschedule=' do
@@ -544,7 +524,4 @@ describe GoodData::Schedule, :broken => true do
544
524
  expect(@schedule.dirty).to eq(true)
545
525
  end
546
526
  end
547
-
548
-
549
-
550
527
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gooddata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Kolesnikov
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-08-04 00:00:00.000000000 Z
14
+ date: 2014-08-05 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -394,76 +394,13 @@ files:
394
394
  - ".rubocop.yml"
395
395
  - ".travis.yml"
396
396
  - ".yardopts"
397
- - CHANGELOG.markdown
397
+ - CHANGELOG.md
398
398
  - CLI.md
399
399
  - Gemfile
400
400
  - LICENSE
401
401
  - README.md
402
402
  - Rakefile
403
403
  - bin/gooddata
404
- - doc/.gitignore
405
- - doc/css/.gitkeepme
406
- - doc/html/.gitkeepme
407
- - doc/images/.gitkeepme
408
- - doc/images/background.png
409
- - doc/images/bg-callout-button.png
410
- - doc/images/header-logo.png
411
- - doc/images/logo-image.png
412
- - doc/js/.gitkeepme
413
- - doc/pages/GET_STARTED.md
414
- - doc/pages/HOMEPAGE.md
415
- - doc/pages/TUTORIALS.md
416
- - doc/pages/tutorial/BRICKS.md
417
- - doc/pages/tutorial/CREATING_A_MODEL.md
418
- - doc/pages/tutorial/CRUNCHING_NUMBERS.md
419
- - doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md
420
- - doc/pages/tutorial/YOUR_FIRST_PROJECT.md
421
- - doc/templates/default/class/dot/setup.rb
422
- - doc/templates/default/class/dot/superklass.erb
423
- - doc/templates/default/class/setup.rb
424
- - doc/templates/default/class/text/setup.rb
425
- - doc/templates/default/class/text/subclasses.erb
426
- - doc/templates/default/constant/text/header.erb
427
- - doc/templates/default/constant/text/setup.rb
428
- - doc/templates/default/docstring/setup.rb
429
- - doc/templates/default/docstring/text/abstract.erb
430
- - doc/templates/default/docstring/text/deprecated.erb
431
- - doc/templates/default/docstring/text/index.erb
432
- - doc/templates/default/docstring/text/note.erb
433
- - doc/templates/default/docstring/text/private.erb
434
- - doc/templates/default/docstring/text/returns_void.erb
435
- - doc/templates/default/docstring/text/text.erb
436
- - doc/templates/default/docstring/text/todo.erb
437
- - doc/templates/default/layout/dot/header.erb
438
- - doc/templates/default/layout/dot/setup.rb
439
- - doc/templates/default/method/setup.rb
440
- - doc/templates/default/method/text/header.erb
441
- - doc/templates/default/method_details/setup.rb
442
- - doc/templates/default/method_details/text/header.erb
443
- - doc/templates/default/method_details/text/method_signature.erb
444
- - doc/templates/default/method_details/text/setup.rb
445
- - doc/templates/default/module/dot/child.erb
446
- - doc/templates/default/module/dot/dependencies.erb
447
- - doc/templates/default/module/dot/header.erb
448
- - doc/templates/default/module/dot/info.erb
449
- - doc/templates/default/module/dot/setup.rb
450
- - doc/templates/default/module/setup.rb
451
- - doc/templates/default/module/text/children.erb
452
- - doc/templates/default/module/text/class_meths_list.erb
453
- - doc/templates/default/module/text/extends.erb
454
- - doc/templates/default/module/text/header.erb
455
- - doc/templates/default/module/text/includes.erb
456
- - doc/templates/default/module/text/instance_meths_list.erb
457
- - doc/templates/default/module/text/setup.rb
458
- - doc/templates/default/root/dot/child.erb
459
- - doc/templates/default/root/dot/setup.rb
460
- - doc/templates/default/tags/setup.rb
461
- - doc/templates/default/tags/text/example.erb
462
- - doc/templates/default/tags/text/index.erb
463
- - doc/templates/default/tags/text/option.erb
464
- - doc/templates/default/tags/text/overload.erb
465
- - doc/templates/default/tags/text/see.erb
466
- - doc/templates/default/tags/text/tag.erb
467
404
  - examples.rb
468
405
  - gooddata
469
406
  - gooddata.gemspec
@@ -627,6 +564,9 @@ files:
627
564
  - spec/data/manifest_test_project.json
628
565
  - spec/data/model_module.json
629
566
  - spec/data/model_view.json
567
+ - spec/data/ruby_process/deep_files/deep_stuff.txt
568
+ - spec/data/ruby_process/process.rb
569
+ - spec/data/ruby_process/stuff.txt
630
570
  - spec/data/superfluous_titles_view.json
631
571
  - spec/data/test-ci-data.csv
632
572
  - spec/data/test_project_model_spec.json
@@ -640,6 +580,7 @@ files:
640
580
  - spec/helpers/project_helper.rb
641
581
  - spec/integration/command_projects_spec.rb
642
582
  - spec/integration/create_from_template_spec.rb
583
+ - spec/integration/full_process_schedule_spec.rb
643
584
  - spec/integration/full_project_spec.rb
644
585
  - spec/integration/partial_md_export_import_spec.rb
645
586
  - spec/logging_in_logging_out_spec.rb
@@ -1 +0,0 @@
1
- html/
@@ -1 +0,0 @@
1
- KEEP THIS FILE !!!
@@ -1 +0,0 @@
1
- KEEP THIS FILE !!!
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- KEEP THIS FILE !!!
@@ -1,310 +0,0 @@
1
- # @title Get Started
2
-
3
- <div class="container-narrow">
4
-
5
- <h1>Get Started</h1>
6
-
7
- <p>
8
- You just installed the Ruby GEM and want to start playing around, right? Follow this guide to learn more about the
9
- basics and most common use cases.
10
- </p>
11
-
12
- <p>
13
- And what you will learn? You will learn how to:<br/><br/>
14
- <a class="topics" href="#login">Login to GoodData with gem</a><br/>
15
- <a class="topics" href="#direct">Direct Post Requests</a><br/>
16
- <a class="topics" href="#retrieve">Retrieving Objects</a><br/>
17
- <a class="topics" href="#metrics">Metrics (not only) Creation</a><br/>
18
- <a class="topics" href="#reports">Report Handling</a><br/>
19
- <a class="topics" href="#dashboards">Dashboard Operations</a><br/>
20
- </p>
21
-
22
- <h2>Install</h2>
23
-
24
- <p>If you are using bundler. Add</p>
25
- <pre>
26
- gem "gooddata"
27
- </pre>
28
- <p>into Gemfile and run</p>
29
- <pre>
30
- bundle install
31
- </pre>
32
- <p>If you are using gems just</p>
33
- <pre>
34
- gem install gooddata --version0.6.0.pre9
35
- </pre>
36
-
37
- <a name="login"></a>
38
-
39
- <h2>Logging in</h2>
40
-
41
- <pre>
42
- GoodData.connect( :login => 'svarovsky@gooddata.com',
43
- :password => 'pass',
44
- :server => "https://na1.secure.gooddata.com",
45
- :webdav_server => "https://na1-di.gooddata.com",
46
- :token => "asdasdas")
47
- </pre>
48
-
49
- <p>Picking project to work with. There are several ways how to do it.</p>
50
-
51
- <pre>
52
- GoodData.connect( :login => 'svarovsky@gooddata.com',
53
- :password => 'pass',
54
- :project => 'project_pid')
55
-
56
- GoodData.project = 'project_pid'
57
-
58
- GoodData.use = 'project_pid'
59
- </pre>
60
-
61
- <p>This will let you work with the project in a block. The project has the value you picked only inside the block
62
- afterwards it will reset the project value to whatever it was before.</p>
63
-
64
- <pre>
65
- GoodData.with_project('project_pid') do |project|
66
- puts project.uri
67
- end
68
- </pre>
69
-
70
- <a name="direct"></a>
71
-
72
- <h2>Directly accessing API</h2>
73
-
74
- <p>This is the most crude method and while you can do anything with it is also most cumbersome. It is needed sometimes
75
- though so we are mentioneing it here. Gem will make sure that it does the plumbing like keeping you logged in etc
76
- and you can just use the HTTP methods you are used to</p>
77
-
78
- <pre>
79
- GoodData.get("uri")
80
- GoodData.post("uri", {:name => "John Doe"})
81
- GoodData.put("uri", {:name => "John Doe"})
82
- GoodData.delete("uri")
83
- </pre>
84
-
85
- <p>Nothing surprising</p>
86
-
87
- <a name="retrieve"></a>
88
-
89
- <h2>Retrieving objects</h2>
90
-
91
- <p>There are several wrappers for different types of objects. There are some common things you can do with them.</p>
92
-
93
- <p>You can retrieve all objects of that type.</p>
94
-
95
- <pre>
96
- reports = GoodData::Report[:all]
97
- </pre>
98
-
99
- <p>You can retrieve specific one</p>
100
-
101
- <pre>
102
- report = GoodData::Report["/gdc/md/pid/12"]
103
- report = GoodData::Report[12]
104
- </pre>
105
-
106
-
107
- <p>You can retrieve reports based on tags</p>
108
-
109
- <pre>
110
- reports = GoodData::Report.find_by_tag("some_tag")
111
- </pre>
112
-
113
- <p>You can retrieve an object based on a title</p>
114
-
115
- <pre>
116
- report = GoodData::Report.find_first_by_title('My first report')
117
- </pre>
118
-
119
- <p>You can set some basic things like summary and title</p>
120
-
121
- <pre>
122
- report.title = "New title"
123
- report.summary = "This is some fancy description"
124
- </pre>
125
-
126
- <p>You can also save the object back to the server</p>
127
-
128
- <pre>report.save</pre>
129
-
130
- <p>And then you can delete it</p>
131
-
132
- <pre>
133
- report.delete
134
- </pre>
135
-
136
- <p>Since metadata about project is one big tree you can also ask which object are used by or using other objects. For
137
- example what reports are on a dashboard</p>
138
-
139
- <pre>
140
- report.get_used_by
141
- report.get_using
142
- </pre>
143
-
144
- <p>What we just showed you can be done with all Metadata objects. These include Report, Dashboard, Metric, Attribute,
145
- Fact</p>
146
-
147
- <a name="metrics"></a>
148
-
149
- <h2>Metrics</h2>
150
-
151
- <p>Probably the most useful and complex obect is a metric. For its definition we are using language called MAQL. There
152
- is one big drawback to current MAQL definition and that is how it reffers to another object. If you imagine a simple
153
- metric definition like 'sum of all amounts' it could be described like this "SELECT SUM(Amount)". The problem is
154
- that the proper maql definition is as follows
155
-
156
- <pre>SELECT SUM([/gdc/md/project_id/obj/123])</pre>
157
-
158
- </p>As you can see the reference to Amount fact is done via an URI. This has a big advantage of being unambiguous but it
159
- has a bg drawback that t cannot be written buy hand and also it is not transferable between projects without some
160
- translation.</p>
161
-
162
- <p>Here we introduce eXtended MAQL which tries to mitigate some of the drawbacks. The implementation acurrently relies
163
- on titles of objects and might change. In XMAQL there are only 4 additions<br/>
164
- 1) fact is referenced like #"Amount"<br/>
165
- 2) attribute like @"User Name"<br/>
166
- 3) metric like ?"My metric"<br/>
167
- 4) attribute value like $"United States"<br/>
168
- </p>
169
-
170
- <p>The aforementioned metric could be then expressed like this 'SELECT SUM(#"Amount")'. This allows to be explicit in
171
- what type you are reffering to since MAQL is fairly complex and allows you to write them by hand. Also transfering
172
- metrics nbetween objects is more transpoarent.</p>
173
-
174
- <p>You can create a metric</p>
175
-
176
- <pre>
177
- m = Metric.create(:title => "My metric", :expression => 'SELECT SUM(["/gdc/md/1231231/obj/12"])')
178
- m.save
179
- </pre>
180
-
181
- <p>If you want to use eXtended notation use xcreate or pass :extended => true option to the create method</p>
182
-
183
- <pre>
184
- m = Metric.create(:title => "My metric", :expression => 'SELECT SUM(#"Amount")', :extended => true)
185
- m = Metric.xcreate(:title => "My metric", :expression => 'SELECT SUM(#"Amount")')
186
- </pre>
187
-
188
- <p>You can directly execute it which will return a number</p>
189
-
190
- <pre>
191
- m.execute
192
- </pre>
193
-
194
- <p>Note on executing metrics. Since GoodData currently cannot execute metric which is not saved there is some behavior
195
- that might surprise you when executing unsaved metrics on the fly. If you execute a metric or use a metric in a
196
- report it takes all unsaved metrics and saves them. After execution it takes those that it had to save and deletes
197
- them so they are not visible and cluttering the system. If you are creating a metric to be really saved do save it
198
- immediately. This will hopefully change as we will allow execution of metrics that are inlined in execution
199
- description.</p>
200
-
201
- <a name="reports"></a>
202
-
203
- <h2>Reports</h2>
204
-
205
- <p>You can execute report</p>
206
-
207
- <pre>
208
- report = report = GoodData::Report["/gdc/md/pid/12"]
209
- result = report.execute
210
- </pre>
211
-
212
- <p>with result you can print it (needs more work, it roughly works but attribute reports only do not work)</p>
213
-
214
- <pre>
215
- result.print
216
- </pre>
217
-
218
- <p>You can export it to a file. This needs some work so it warns you if it does not make sense to export you report in
219
- given format I think that our platfrom does not support all combinations. Currently there is :pdf, :png and :csv
220
- supported</p>
221
-
222
- <pre>
223
- File.open('dash.pdf', 'w') do |f|
224
- f.write(report.export(:pdf))
225
- end
226
- </pre>
227
-
228
- <p>You can also create a report on the fly.</p>
229
-
230
- <pre>
231
- metric = GoodData::Metric.xcreate(:title => "My Metric", :expression => 'SELECT SUM(#"amount")')
232
- metric.save
233
-
234
- report = GoodData::Report.create(:title => "My report",:left => 'user', :top => metric)
235
- report.save
236
- </pre>
237
-
238
- <p>There are some rules that need explanation. The report is structured a little different than in UI. You specify left
239
- and top. It can either be an attribute or a metric. There can be multiple metrics but all of those need to be either
240
- in top or left section. The objects can be specified in several ways. You can provide Attribute but remember that
241
- eventually GoodData needs Label information (on API you can hit name display form). If you provide attribute it will
242
- resolve to its first Label. If an attribute has more than one it will take the first.</p>
243
-
244
- <p>1) MD object. Metric, Attribute and Label
245
- 2) hash. If you do not have the object handy you can pass a hash structure like this <pre>{:type => :attribute, :title => 'some title'}</pre>. It will perform the lookup for you. This currently works for :attribute and :metric. If you want to
246
- perform the lookup through identifier you can do it as well. Since id is unique <pre>{:identifier => 'some id'}</pre>
247
- 3) String. If you put there a string it is assumed it is a name of an attribute so 'some title' is equivalent with
248
- typing <pre>{:type => :attribute, :title => 'some title'}</pre></p>
249
-
250
- <p>TODO
251
- Describe filtering</p>
252
-
253
- <a name="dashboards"></a>
254
-
255
- <h2>Dashboards</h2>
256
-
257
- <p>You can export whole dashboards</p>
258
-
259
- <pre>
260
- dash = GoodData::Dashboard[33807]
261
- File.open('dash.pdf', 'w') do |f|
262
- f.write(dash.export(:pdf))
263
- end
264
- </pre>
265
-
266
- <p>or just a specific tab</p>
267
-
268
- <pre>
269
- dash = GoodData::Dashboard[33807]
270
- File.open('dash.pdf', 'w') do |f|
271
- f.write(dash.export(:pdf, :tab => dash.tabs_ids.last))
272
- end
273
- </pre>
274
-
275
- <p>
276
- Project
277
- create a project
278
- clone a project
279
- rename a project
280
- delete a project
281
- TBD - add a user
282
- TBD - remove a user
283
-
284
- Domain (Organization)
285
- Add a user to a domain
286
-
287
- Project Datasets
288
- Create a model
289
- Load data
290
- </p>
291
-
292
- <div class="section-nav">
293
- <div class="left align-right">
294
-
295
- <span class="prev disabled">Back</span>
296
-
297
- </div>
298
- <div class="right align-left">
299
-
300
- <a href="/docs/file/doc/pages/TUTORIALS.md" class="next">
301
- Next
302
- </a>
303
-
304
- </div>
305
- <div class="clear"></div>
306
- </div>
307
-
308
- </div>
309
-
310
- </div>