gooddata 0.6.6 → 0.6.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{CHANGELOG.markdown → CHANGELOG.md} +6 -1
- data/lib/gooddata/cli/commands/project_cmd.rb +6 -29
- data/lib/gooddata/commands/project.rb +36 -44
- data/lib/gooddata/connection.rb +7 -0
- data/lib/gooddata/core/connection.rb +3 -0
- data/lib/gooddata/core/rest.rb +38 -19
- data/lib/gooddata/mixins/md_object_query.rb +3 -2
- data/lib/gooddata/models/metadata/dashboard.rb +3 -8
- data/lib/gooddata/models/metadata/report.rb +1 -6
- data/lib/gooddata/models/model.rb +5 -4
- data/lib/gooddata/models/process.rb +10 -14
- data/lib/gooddata/models/project.rb +34 -26
- data/lib/gooddata/models/project_blueprint.rb +14 -7
- data/lib/gooddata/models/project_creator.rb +2 -6
- data/lib/gooddata/models/schedule.rb +13 -2
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
- data/spec/data/ruby_process/process.rb +2 -0
- data/spec/data/ruby_process/stuff.txt +1 -0
- data/spec/integration/full_process_schedule_spec.rb +69 -0
- data/spec/integration/full_project_spec.rb +14 -5
- data/spec/unit/models/schedule_spec.rb +7 -30
- metadata +7 -66
- data/doc/.gitignore +0 -1
- data/doc/css/.gitkeepme +0 -1
- data/doc/images/.gitkeepme +0 -1
- data/doc/images/background.png +0 -0
- data/doc/images/bg-callout-button.png +0 -0
- data/doc/images/header-logo.png +0 -0
- data/doc/images/logo-image.png +0 -0
- data/doc/js/.gitkeepme +0 -1
- data/doc/pages/GET_STARTED.md +0 -310
- data/doc/pages/HOMEPAGE.md +0 -77
- data/doc/pages/TUTORIALS.md +0 -52
- data/doc/pages/tutorial/BRICKS.md +0 -260
- data/doc/pages/tutorial/CREATING_A_MODEL.md +0 -81
- data/doc/pages/tutorial/CRUNCHING_NUMBERS.md +0 -231
- data/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md +0 -120
- data/doc/pages/tutorial/YOUR_FIRST_PROJECT.md +0 -53
- data/doc/templates/default/class/dot/setup.rb +0 -6
- data/doc/templates/default/class/dot/superklass.erb +0 -3
- data/doc/templates/default/class/setup.rb +0 -37
- data/doc/templates/default/class/text/setup.rb +0 -11
- data/doc/templates/default/class/text/subclasses.erb +0 -5
- data/doc/templates/default/constant/text/header.erb +0 -11
- data/doc/templates/default/constant/text/setup.rb +0 -3
- data/doc/templates/default/docstring/setup.rb +0 -51
- data/doc/templates/default/docstring/text/abstract.erb +0 -2
- data/doc/templates/default/docstring/text/deprecated.erb +0 -2
- data/doc/templates/default/docstring/text/index.erb +0 -2
- data/doc/templates/default/docstring/text/note.erb +0 -4
- data/doc/templates/default/docstring/text/private.erb +0 -2
- data/doc/templates/default/docstring/text/returns_void.erb +0 -1
- data/doc/templates/default/docstring/text/text.erb +0 -1
- data/doc/templates/default/docstring/text/todo.erb +0 -4
- data/doc/templates/default/layout/dot/header.erb +0 -6
- data/doc/templates/default/layout/dot/setup.rb +0 -14
- data/doc/templates/default/method/setup.rb +0 -3
- data/doc/templates/default/method/text/header.erb +0 -1
- data/doc/templates/default/method_details/setup.rb +0 -11
- data/doc/templates/default/method_details/text/header.erb +0 -10
- data/doc/templates/default/method_details/text/method_signature.erb +0 -12
- data/doc/templates/default/method_details/text/setup.rb +0 -10
- data/doc/templates/default/module/dot/child.erb +0 -1
- data/doc/templates/default/module/dot/dependencies.erb +0 -3
- data/doc/templates/default/module/dot/header.erb +0 -6
- data/doc/templates/default/module/dot/info.erb +0 -14
- data/doc/templates/default/module/dot/setup.rb +0 -14
- data/doc/templates/default/module/setup.rb +0 -164
- data/doc/templates/default/module/text/children.erb +0 -10
- data/doc/templates/default/module/text/class_meths_list.erb +0 -8
- data/doc/templates/default/module/text/extends.erb +0 -8
- data/doc/templates/default/module/text/header.erb +0 -7
- data/doc/templates/default/module/text/includes.erb +0 -8
- data/doc/templates/default/module/text/instance_meths_list.erb +0 -8
- data/doc/templates/default/module/text/setup.rb +0 -12
- data/doc/templates/default/root/dot/child.erb +0 -3
- data/doc/templates/default/root/dot/setup.rb +0 -5
- data/doc/templates/default/tags/setup.rb +0 -55
- data/doc/templates/default/tags/text/example.erb +0 -12
- data/doc/templates/default/tags/text/index.erb +0 -1
- data/doc/templates/default/tags/text/option.erb +0 -20
- data/doc/templates/default/tags/text/overload.erb +0 -19
- data/doc/templates/default/tags/text/see.erb +0 -11
- 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
|
-
|
14
|
-
|
15
|
-
if
|
16
|
-
|
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(
|
22
|
+
ProjectBlueprint.new(spec)
|
19
23
|
end
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
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
|
data/lib/gooddata/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
Hello Ruby from the deep
|
@@ -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(
|
6
|
-
@invalid_spec = JSON.parse(File.read(
|
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(
|
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)).
|
286
|
-
expect(l.value?("DEFINITELY NON EXISTENT VALUE HOPEFULLY")).
|
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
|
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 = '
|
19
|
+
TEST_PROCESS_ID = 'dc143d80-58a1-4acd-96b6-8d11fc4571de'
|
20
20
|
|
21
|
-
SCHEDULE_ID = '
|
22
|
-
SCHEDULE_URL = '/gdc/projects/
|
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 = "
|
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
|
-
|
403
|
-
|
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.
|
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-
|
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.
|
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
|
data/doc/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
html/
|
data/doc/css/.gitkeepme
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
KEEP THIS FILE !!!
|
data/doc/images/.gitkeepme
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
KEEP THIS FILE !!!
|
data/doc/images/background.png
DELETED
Binary file
|
Binary file
|
data/doc/images/header-logo.png
DELETED
Binary file
|
data/doc/images/logo-image.png
DELETED
Binary file
|
data/doc/js/.gitkeepme
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
KEEP THIS FILE !!!
|
data/doc/pages/GET_STARTED.md
DELETED
@@ -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>
|