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
data/doc/pages/HOMEPAGE.md
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
# @title Homepage
|
2
|
-
|
3
|
-
<div class="jumbotron">
|
4
|
-
<!-- style="background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,white), color-stop(100%,#6d3353));"> -->
|
5
|
-
|
6
|
-
<a href="http://sdk.gooddata.com" id="left-floater">
|
7
|
-
<p style="margin-top: 5px;">See other <br />SDKs</p>
|
8
|
-
</a>
|
9
|
-
|
10
|
-
<img src="http://www.prestonlee.com/wp-content/uploads/2008/09/ruby.png" width="200px" style="margin-bottom: 10px;">
|
11
|
-
<br />
|
12
|
-
|
13
|
-
<h1>Leverage power of GoodData API.<br />Now.</h1>
|
14
|
-
|
15
|
-
<a class="callout" target="_blank" href="https://github.com/gooddata/gooddata-ruby">Fork me on Github</a>
|
16
|
-
<div style="margin-top: 25px;">
|
17
|
-
<iframe src="http://ghbtns.com/github-btn.html?user=gooddata&repo=gooddata-ruby&type=watch&count=true&size=large"
|
18
|
-
allowtransparency="true" frameborder="0" scrolling="0" width="170" height="30"></iframe>
|
19
|
-
<a href="https://twitter.com/gooddata_dev" class="twitter-follow-button" data-show-count="false" data-size="large">Follow @gooddata_dev</a>
|
20
|
-
</div>
|
21
|
-
</div>
|
22
|
-
|
23
|
-
<div class="divider">
|
24
|
-
<h2>Feature set that rocks!</h2>
|
25
|
-
</div>
|
26
|
-
|
27
|
-
<div class="container-narrow">
|
28
|
-
|
29
|
-
<div class="row-fluid marketing">
|
30
|
-
<div class="span6">
|
31
|
-
<div>
|
32
|
-
<img src="http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/MD-shuffle.png?itok=zffXPwRr" width="50px">
|
33
|
-
<h4 style="display: inline;">Expressive</h4>
|
34
|
-
<p>Do more with less code.</p>
|
35
|
-
</div>
|
36
|
-
|
37
|
-
<div>
|
38
|
-
<img src="http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/hammer.png?itok=GwaBj_x2" width="50px">
|
39
|
-
<h4 style="display: inline;">Battle Tested</h4>
|
40
|
-
<p>Used on 10s of projects written by people at GoodData.</p>
|
41
|
-
</div>
|
42
|
-
|
43
|
-
|
44
|
-
</div>
|
45
|
-
|
46
|
-
<div class="span6">
|
47
|
-
|
48
|
-
|
49
|
-
<div>
|
50
|
-
|
51
|
-
<img src="http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/plugin-disabled.png?itok=lVgrl6D3" width="50px">
|
52
|
-
<h4 style="display: inline;">Automation friendly</h4>
|
53
|
-
<p>No more manual jobs.</p>
|
54
|
-
</div>
|
55
|
-
|
56
|
-
<div><img src="http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/layers_0.png?itok=wBvb1GYw" width="50px">
|
57
|
-
<h4 style="display: inline;">Full stack</h4>
|
58
|
-
<p>The whole cycle of a project done using dev familiar tools.</p>
|
59
|
-
</div>
|
60
|
-
|
61
|
-
</div>
|
62
|
-
|
63
|
-
</div>
|
64
|
-
</div>
|
65
|
-
|
66
|
-
<div class="divider">
|
67
|
-
<h2>The Story</h2>
|
68
|
-
</div>
|
69
|
-
|
70
|
-
<div class="row-fluid marketing container-narrow" style="margin: auto;">
|
71
|
-
|
72
|
-
<div class="span12" >
|
73
|
-
<div style="margin: 25px 0 25px 0;font-size: 18px;line-height:1.3;">
|
74
|
-
Since its beginning, GoodData was alway super adamant to have everything accessible over APIs. GoodData Ruby SDK is the most polished wrapper over them. It gives high level way to work with the most common tasks and provides low level plumbing to let you play with any API with ease. If you wanted to automate your latest project look no further.
|
75
|
-
</div>
|
76
|
-
</div>
|
77
|
-
</div>
|
data/doc/pages/TUTORIALS.md
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
# @title Tutorials
|
2
|
-
|
3
|
-
<div class="container-narrow">
|
4
|
-
<ul class="posts">
|
5
|
-
<div>
|
6
|
-
<a href="/docs/file/doc/pages/tutorial/YOUR_FIRST_PROJECT.md"><h3>Your first project</h3></a>
|
7
|
-
|
8
|
-
<div>Let's spin up a project that will be the base for other tutorials. It will take only 5 mins. Promise.
|
9
|
-
</div>
|
10
|
-
</div>
|
11
|
-
|
12
|
-
|
13
|
-
<div>
|
14
|
-
<a href="/docs/file/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md"><h3>Test driven
|
15
|
-
development</h3></a>
|
16
|
-
|
17
|
-
<div>Let's have a look how you can bump project development a little to achieve test driven development of
|
18
|
-
your reports and projects.
|
19
|
-
</div>
|
20
|
-
</div>
|
21
|
-
|
22
|
-
|
23
|
-
<div>
|
24
|
-
<a href="/docs/file/doc/pages/tutorial/CREATING_A_MODEL.md"><h3>Creating a model</h3></a>
|
25
|
-
|
26
|
-
<div>Model plays a huge role in the Reporting process. Let's have a look on how to create it using Ruby SDK
|
27
|
-
and compare it with other approaches.
|
28
|
-
</div>
|
29
|
-
</div>
|
30
|
-
|
31
|
-
|
32
|
-
<div>
|
33
|
-
<a href="/docs/file/doc/pages/tutorial/CRUNCHING_NUMBERS.md"><h3>Crunching numbers</h3></a>
|
34
|
-
|
35
|
-
<div>Regardless of how much other things there are in the project the most important thing is to get some
|
36
|
-
numbers out. Let's do it. With Ruby.
|
37
|
-
</div>
|
38
|
-
</div>
|
39
|
-
|
40
|
-
|
41
|
-
<div>
|
42
|
-
<a href="/docs/file/doc/pages/tutorial/BRICKS.md"><h3>Executing ruby on GoodData plaform</h3>
|
43
|
-
</a>
|
44
|
-
|
45
|
-
<div>ETL is the back bone of every project. But project is not just about crunching numbers. What to do with
|
46
|
-
tasks that are very well suited for solving by a regular programming language, like Ruby?
|
47
|
-
</div>
|
48
|
-
</div>
|
49
|
-
|
50
|
-
|
51
|
-
</ul>
|
52
|
-
</div>
|
@@ -1,260 +0,0 @@
|
|
1
|
-
# @title Executing ruby on GoodData plaform
|
2
|
-
|
3
|
-
You can run Ruby on GoodData platform. Let's have a look at the platform and walk step by step through doing the simplest possible deployment and then move to more advanced tasks.
|
4
|
-
|
5
|
-
## Not reinventing the wheel
|
6
|
-
|
7
|
-
The main idea is that only minority of people should be forced to write code. The others should be happy running them without understanding the details. Soon we will introduce better UI to do just that. Until then it is more programatic but if you are not scared read on.
|
8
|
-
|
9
|
-
## Setting up the stage
|
10
|
-
|
11
|
-
GoodData Ruby SDK stack is built so you can easily develop things locally and deploy them when you have tested them and are happy with how they work. You need to set up an environment first.
|
12
|
-
|
13
|
-
### Prerequisites
|
14
|
-
|
15
|
-
* Git
|
16
|
-
* Ruby (JRuby recommended)
|
17
|
-
* Ruby Gems
|
18
|
-
|
19
|
-
Go ahead and run
|
20
|
-
|
21
|
-
git clone https://github.com/gooddata/app_store.git
|
22
|
-
|
23
|
-
We just cloned the remote repository which contains information about the used libraries and also contains some stuff that others created. We will investigate that later. Let's continue with setting things up.
|
24
|
-
|
25
|
-
Run
|
26
|
-
|
27
|
-
gem install bundler
|
28
|
-
|
29
|
-
This will install bundler which is a useful package installation tool. Let's use it
|
30
|
-
|
31
|
-
cd local_repo
|
32
|
-
bundle install --binstubs
|
33
|
-
|
34
|
-
This will ensure that you have installed exactly what we have on the production machines. This should mitigate bugs caused by slightly different versions of libraries and incompatible APIs.
|
35
|
-
|
36
|
-
You are ready to go.
|
37
|
-
|
38
|
-
## Running your first brick
|
39
|
-
|
40
|
-
The small pieces of ruby that are run on the platform are called bricks. Nobody knows where and why this name emerged but there are rumors that it is supposed to reference the fact that out of brick just laid together you can create a solid wall.
|
41
|
-
|
42
|
-
If you open the repository you will see there some directories. Find directory called misc/hello_world and open it. It contains only one file. Do not open it yet.
|
43
|
-
|
44
|
-
Run this in console.
|
45
|
-
|
46
|
-
bundle exec gooddata -l -Uname@gooddata.com -Pmy_pass run_ruby -p project_pid -d hello_world_brick --name "some_deploy" --remote
|
47
|
-
|
48
|
-
It will take some time but after a while you should see green DONE on your console and a link for the log. Open it in your browser and you should see there something like this. On one of the lines there should be hello world. Great you just ran your first ruby brick.
|
49
|
-
|
50
|
-
### Looking inside Hello World
|
51
|
-
|
52
|
-
Let's see what is happening inside. Open the main.rb file in your favorite editor. You should see something like this.
|
53
|
-
|
54
|
-
require 'gooddata'
|
55
|
-
require 'logger'
|
56
|
-
|
57
|
-
module GoodData::Bricks
|
58
|
-
class HelloWorldBrick
|
59
|
-
|
60
|
-
def call(params)
|
61
|
-
logger = Logger.new(params[:GDC_LOGGER_FILE])
|
62
|
-
logger.info "Hello world"
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
GoodData::Bricks::HelloWorldBrick.new
|
69
|
-
|
70
|
-
This is all. Let's dissect it. The interface is very simple. You have to provide an instance of an object that responds to a message :call (in other words does implement method call). This method takes one parameter and that is a hash map of parameters.
|
71
|
-
|
72
|
-
You can see that we have implemented such a class and returning an instance of that class. The method accepts params and you can see that we immediately make use of them when grabbing logger and the writing to it. Platform does the heavy lifting on the back and you have already seen the result.
|
73
|
-
|
74
|
-
## Digging deeper
|
75
|
-
|
76
|
-
It might be surprising if I tell you that this is not exactly how majority of the real bricks are implemented. What we showed you is fine and this is how we started but after we implemented some bricks we found out that we are repeating ourselves a lot. So we tried to come up with something better.
|
77
|
-
|
78
|
-
remark: If you know how Rack or any similar framework works for abstracting web applications you would be right at home since that is where most of the inspiration came from.
|
79
|
-
|
80
|
-
We introduced three concepts.
|
81
|
-
|
82
|
-
* _Application_ - This part is responsible for doing the core of the task you are interested in. Structure of an app is pretty much what you have already seen.
|
83
|
-
* _Middleware_ - very similar to app. The main difference is that you can chain them together. The main similarity is that it has the same interface as an app
|
84
|
-
* _Pipelines_ - If you chain multiple middleweres and applications it creates a pipeline.
|
85
|
-
|
86
|
-
Let's have a look how it works visually.
|
87
|
-
|
88
|
-
![Example pipeline consisting of 3 middlewares](https://dl.dropboxusercontent.com/s/g5rymdmmx97hc61/middlewares.png?token_hash=AAE7qAjkOxA6tQGDk8UY17ltRu0ZG5UqwSJ_8ZtAl7ZNaA)
|
89
|
-
|
90
|
-
This is a simple pipeline with 2 middlewares and one app. The arrows depict how the execution order would flow.
|
91
|
-
|
92
|
-
### Executing a pipeline
|
93
|
-
Your pipeline is executed. First middleware is called then the second and third. Then your app is called it does what it needs to and then the call goes back through the middlewares (so they can actually act twice).
|
94
|
-
|
95
|
-
This probably does not seem that much useful so let's have a look at couple of examples where you might use it.
|
96
|
-
|
97
|
-
Plumbing - just the plumbing. Did you notice how we had to set up the logger in our Hello World example? It is not a lot of code but imagine that you need to do 10 things like this. It can bog you down. There are couple of middlewares that try to help you with similar stuff. It is similar to what AOP style of programming tries to do.
|
98
|
-
|
99
|
-
Examples
|
100
|
-
|
101
|
-
* log in to various systems and prepeare for action
|
102
|
-
* Set up loggers
|
103
|
-
|
104
|
-
Decorators - Imagine that you have done something great. For example computing hierarchy of people from some information. It is so much useful that you would like to let other people use it. But everybody has slightly different use case. Somebody wants to output it to web dav or s3 storage. Somebody want's to tweet about that it finished somebody might want to store this file into vertica. Implementing serialization in a separate middlewere means that you do not need to touch the actually code that.
|
105
|
-
|
106
|
-
* measuring time
|
107
|
-
* serializing stuff to various places
|
108
|
-
* letting other people know
|
109
|
-
|
110
|
-
### First pipeline
|
111
|
-
|
112
|
-
Ok let's create our first pipeline. Let's open misc/hello_world_pipeline_brick in your browser
|
113
|
-
|
114
|
-
You will see two files. Let's check the hello_world.rb first.
|
115
|
-
|
116
|
-
module MyFirstBrick
|
117
|
-
|
118
|
-
class HelloWorldBrick
|
119
|
-
def call(params)
|
120
|
-
logger = params[:gdc_logger]
|
121
|
-
logger.info "Hello world"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
It looks exactly the same as in previosus case except for the logger setting up. Let's look at the other file main.rb
|
128
|
-
|
129
|
-
You see that at the top we are requiring the hello_world.rb and then we are setting up the pipeline. You can see that even this basic example uses quite a bit of middleare but hopefully their names are fairly self describing. Logging will hook up a logger. GoodData logs you in to GD and hooks the library to the logger if you want to. Timinng will simply measure the execution of the app itself.
|
130
|
-
|
131
|
-
Notice several things. Pipeline has exactly one app. It also has to be the last one in the pipeline. It has zero or more middlewares. When constructong a pipeline you can specify a stage either via a class or an instance. If it is a class we instatntiate it for you (without parameters). This is useful if you want to parametrize the middleware somehow.
|
132
|
-
|
133
|
-
## Middlewares
|
134
|
-
Let's have a look at some middlewares
|
135
|
-
App was not very challenging from programming perspective (which is the goal) and you will see that middleware is not any more complicated. There are generally two types of middleares. First is a middleware that wants to act only once. It is like fire and forget. For example setting up logger. You just create it and do not care. There is a second type and that is a middleware that wants to act twice. Once before the app itself was called. Second after an app was called. Typical example might be time measuring. You want to start your clock before the app itself is called but then you have to stop them sometimes. The difference is absolutely minimal let's walk through both of them.
|
136
|
-
|
137
|
-
### Logger middleware
|
138
|
-
require 'logger'
|
139
|
-
|
140
|
-
module GoodData::Bricks
|
141
|
-
class LoggerMiddleware < GoodData::Bricks::Middleware
|
142
|
-
|
143
|
-
def call(params)
|
144
|
-
logger = params[:gdc_logger] = params[:GDC_LOGGER_FILE].nil? ? Logger.new(STDOUT) : Logger.new(params[:GDC_LOGGER_FILE])
|
145
|
-
logger.info("Pipeline starts")
|
146
|
-
|
147
|
-
returning(@app.call(params)) do |result|
|
148
|
-
logger.info("Pipeline ending")
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
### Benchmarking middleware
|
156
|
-
|
157
|
-
require 'benchmark'
|
158
|
-
|
159
|
-
module GoodData::Bricks
|
160
|
-
|
161
|
-
class BenchMiddleware < GoodData::Bricks::Middleware
|
162
|
-
|
163
|
-
def call(params)
|
164
|
-
puts "Starting timer"
|
165
|
-
result = nil
|
166
|
-
report = Benchmark.measure { result = @app.call(params) }
|
167
|
-
puts "Stopping timer"
|
168
|
-
pp report
|
169
|
-
result
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
You see there are really only minimal changes. Let's walk through the couple of important points more carefully. As we stated before difference between app and a middleware is mainly in the fact that you can chain middlewares. Thus middleware has to know who is the next on in the chain and at some point it is going to call him. That is the `@app.call(params)`. Notice how we are still using the same interface. This way it is no difference if the next guy is app or middleware. The second important piece might be the returning function but that is just a way how to be more dry. Returning will take one param evaluate it store it you can do some stuff on it and then its value is returned. These things are equivalent.
|
176
|
-
|
177
|
-
returning(Person.new) do |o|
|
178
|
-
p.name = "Tomas"
|
179
|
-
end
|
180
|
-
|
181
|
-
p = Person.new
|
182
|
-
p.name = "Tomas"
|
183
|
-
p
|
184
|
-
|
185
|
-
### Passing values
|
186
|
-
|
187
|
-
We haven't talk much explicitly about passing values. The recommended way how to pass parameters is through the `:call(params)` methods parameters. You can see example of that for example in the logger middleware. It creates a logger and puts it into the param object. All following middlewares that are called can benefit from it. You can again see the usage in the HelloWorld.
|
188
|
-
|
189
|
-
### Providing initial sets of parameters
|
190
|
-
|
191
|
-
When deploying you will have to either provide parameters during execution or to the scheduler. Since we are developing locally it would be great to have similar functionality during local execution. This is exactly what `--params` parameter does.
|
192
|
-
|
193
|
-
bundle exec gooddata -v run_ruby --remote asdas/asdadas --params path_to_params_file.json
|
194
|
-
|
195
|
-
The file is simple JSON file. This file is used in both local or remote execution.
|
196
|
-
|
197
|
-
{
|
198
|
-
"param1" : "value1",
|
199
|
-
"param2" : "value2"
|
200
|
-
}
|
201
|
-
|
202
|
-
### Return parameters
|
203
|
-
|
204
|
-
## Local harness
|
205
|
-
Let's talk a little about the harness that makes it possible to test things locally. It tries to run your bricks in similar environment as it would run on the server. This mainly means that you will get the same parameters etc. The goal is to provide you environment to debug and test before you deploy.
|
206
|
-
|
207
|
-
|
208
|
-
### Run locally
|
209
|
-
|
210
|
-
The most complete command
|
211
|
-
|
212
|
-
bundle exec gooddata -l -s https://secure.gooddata.com -Uname@gooddata.com -Pmy_pass -w https://secure-di.getgooddata.com run_ruby -p rjzbt1shubkj9c8es6f75t2avke748mj -d brick_test --name "some_deploy"
|
213
|
-
|
214
|
-
looks intimidating but let's break it down. Many of these can be omitted and are there in case you can override everything.
|
215
|
-
|
216
|
-
bundle exec
|
217
|
-
|
218
|
-
means you are executing it with exact the same libraries as you would on the server (we are expecting that your local repo is up to date).
|
219
|
-
|
220
|
-
-l
|
221
|
-
|
222
|
-
Means that HTTP communication will be logged to STDOUT.
|
223
|
-
|
224
|
-
-s https://secure.gooddata.com
|
225
|
-
|
226
|
-
Means which datacenter you are connecting to. If you are not going against something special you should be able to leave this out
|
227
|
-
|
228
|
-
-w https://secure-di.getgooddata.com
|
229
|
-
|
230
|
-
File staging area used for uploading the files for execution. Similar case as for he server. By default you should not be forced to use it.
|
231
|
-
|
232
|
-
-p PID
|
233
|
-
|
234
|
-
Currently only execution context we have is project context. You have to specify a project PID to be abel to run your brick
|
235
|
-
|
236
|
-
-d path_to_brick
|
237
|
-
|
238
|
-
This tells the tool where brick lives. It expect the directory where the main.rb lives. Do not point this directly to a file.
|
239
|
-
|
240
|
-
--name some_name
|
241
|
-
|
242
|
-
Used when deployed to name the process so later you can identify it
|
243
|
-
|
244
|
-
### Run remotely
|
245
|
-
|
246
|
-
The only change to do when you are running things remotely is to add `--remote` to the command. Everything else should remain the same.
|
247
|
-
|
248
|
-
<div class="section-nav">
|
249
|
-
<div class="left align-right">
|
250
|
-
<a href="/docs/file/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md" class="prev">
|
251
|
-
Back
|
252
|
-
</a>
|
253
|
-
</div>
|
254
|
-
<div class="right align-left">
|
255
|
-
|
256
|
-
<span class="next disabled">Next</span>
|
257
|
-
|
258
|
-
</div>
|
259
|
-
<div class="clear"></div>
|
260
|
-
</div>
|
@@ -1,81 +0,0 @@
|
|
1
|
-
# @title Creating A Model
|
2
|
-
|
3
|
-
There are several ways how to express a model and create it in GoodData. The most prominent way to do it is the visual modeler that is part of the CloudConnect package. There are clear advantages like being visual but there are also drawbacks. It is not repeatable, it is not programmable and it is not text based. Let's have a look how to create a simple model using Ruby SDK.
|
4
|
-
|
5
|
-
## The model
|
6
|
-
The model we will be creating is this
|
7
|
-
|
8
|
-
## The code
|
9
|
-
Create a file called model.rb and put this inside.
|
10
|
-
|
11
|
-
GoodData::Model::ProjectBuilder.create("gooddata-ruby test #{Time.now.to_i}") do |p|
|
12
|
-
p.add_date_dimension("closed_date")
|
13
|
-
|
14
|
-
p.add_dataset("users") do |d|
|
15
|
-
d.add_anchor("id")
|
16
|
-
d.add_label("name", :reference => 'id')
|
17
|
-
end
|
18
|
-
|
19
|
-
p.add_dataset("regions") do |d|
|
20
|
-
d.add_anchor("id")
|
21
|
-
d.add_attribute("name")
|
22
|
-
end
|
23
|
-
|
24
|
-
p.add_dataset("opportunities") do |d|
|
25
|
-
d.add_fact("amount")
|
26
|
-
d.add_date("closed_date", :dataset => "closed_date")
|
27
|
-
d.add_reference("user_id", :dataset => 'users', :reference => 'id')
|
28
|
-
d.add_reference("region_id", :dataset => 'regions', :reference => 'id')
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
Hopefully the model is self descriptive and if you are not strong on terminology like label, anchor etc please refer to "Building a model with GD".
|
33
|
-
|
34
|
-
## Some rules
|
35
|
-
|
36
|
-
Please note several things
|
37
|
-
|
38
|
-
* we are trying to apply several conventions if you follow them it will be less typing for you but you can always override them.
|
39
|
-
* in all the cases where you type a name it is a string that will be used to create a technical name in gooddata also called identifier on the API. The user visible name which we call title will be inferred if not provided. The inferring process is simple. We expect you to provide name in the snake case (as is typical in ruby, this means things like close_date, opportunity_dimension etc). These will be translated int human readable strings (Close date, Opportunity dimension). If you do not like the title you can specify it directly via :title => "My own title"`
|
40
|
-
* the names are also used as reference names in the model. Notice how the date is using name of the close_date dimension and also the user_id reference is using reference users
|
41
|
-
|
42
|
-
## Executing the model
|
43
|
-
|
44
|
-
gooddata --username joe@example.com --password my_secret_pass --token my_token project build model.rb
|
45
|
-
|
46
|
-
## Loading data
|
47
|
-
As part of the process we allow you to load data since sometimes some initial datasets should be part of the model and not ETL. The typical usecase is for the sake of defining reports which are filtered on certain values these values have to be present.
|
48
|
-
|
49
|
-
### Loading data given inline
|
50
|
-
|
51
|
-
p.upload([["id", "name"],
|
52
|
-
["1", "Tomas"],
|
53
|
-
["2", "Petr"]], :dataset => 'users')
|
54
|
-
|
55
|
-
|
56
|
-
### Loading data given by filename
|
57
|
-
|
58
|
-
p.upload("/some/local_file.csv", :dataset => "users")
|
59
|
-
|
60
|
-
### Loading data given by web file
|
61
|
-
|
62
|
-
p.upload("http://www.example.com/some/remote_file.csv", :dataset => "users")
|
63
|
-
|
64
|
-
In all cases the file has to have headers that has the same name as the name of the particular columns (not necessarily in the same order).
|
65
|
-
|
66
|
-
<div class="section-nav">
|
67
|
-
<div class="left align-right">
|
68
|
-
<a href="/docs/file/doc/pages/tutorial/YOUR_FIRST_PROJECT.md" class="prev">
|
69
|
-
Back
|
70
|
-
</a>
|
71
|
-
</div>
|
72
|
-
|
73
|
-
<div class="right align-left">
|
74
|
-
|
75
|
-
<a href="/docs/file/doc/pages/tutorial/CRUNCHING_NUMBERS.md" class="next">
|
76
|
-
Next
|
77
|
-
</a>
|
78
|
-
|
79
|
-
</div>
|
80
|
-
<div class="clear"></div>
|
81
|
-
</div>
|