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.
- 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>
|