gooddata 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
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>