gooddata 0.6.0.pre10 → 0.6.0.pre11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +2 -0
  3. data/.gitignore +3 -0
  4. data/.travis.yml +7 -0
  5. data/.yardopts +3 -2
  6. data/README.md +8 -145
  7. data/Rakefile +23 -6
  8. data/bin/gooddata +3 -400
  9. data/doc/pages/GET_STARTED.md +5 -4
  10. data/doc/pages/HOMEPAGE.md +2 -0
  11. data/doc/pages/TUTORIALS.md +3 -3
  12. data/doc/pages/tutorial/BRICKS.md +4 -1
  13. data/doc/pages/tutorial/CREATING_A_MODEL.md +2 -0
  14. data/doc/pages/tutorial/CRUNCHING_NUMBERS.md +1 -3
  15. data/doc/pages/tutorial/TEST_DRIVEN_DEVELOPMENT.md +2 -0
  16. data/doc/pages/tutorial/YOUR_FIRST_PROJECT.md +4 -3
  17. data/doc/templates/default/class/setup.rb +1 -0
  18. data/doc/templates/default/method_details/setup.rb +2 -1
  19. data/doc/templates/default/module/setup.rb +1 -1
  20. data/gooddata +7 -0
  21. data/gooddata.gemspec +1 -0
  22. data/lib/gooddata.rb +15 -4
  23. data/lib/gooddata/bricks/base_downloader.rb +1 -0
  24. data/lib/gooddata/bricks/brick.rb +17 -12
  25. data/lib/gooddata/bricks/bricks.rb +7 -0
  26. data/lib/gooddata/bricks/middleware/base_middleware.rb +13 -0
  27. data/lib/gooddata/bricks/middleware/bench_middleware.rb +1 -0
  28. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +2 -1
  29. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +30 -0
  30. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +10 -8
  31. data/lib/gooddata/bricks/middleware/logger_middleware.rb +3 -2
  32. data/lib/gooddata/bricks/middleware/middleware.rb +4 -11
  33. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +2 -0
  34. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +2 -0
  35. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +2 -0
  36. data/lib/gooddata/cli/cli.rb +28 -0
  37. data/lib/gooddata/cli/commands/api_cmd.rb +30 -0
  38. data/lib/gooddata/cli/commands/auth_cmd.rb +17 -0
  39. data/lib/gooddata/cli/commands/console_cmd.rb +17 -0
  40. data/lib/gooddata/cli/commands/process_cmd.rb +55 -0
  41. data/lib/gooddata/cli/commands/profile_cmd.rb +22 -0
  42. data/lib/gooddata/cli/commands/project_cmd.rb +143 -0
  43. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +55 -0
  44. data/lib/gooddata/cli/commands/scaffold_cmd.rb +32 -0
  45. data/lib/gooddata/cli/hooks.rb +43 -0
  46. data/lib/gooddata/cli/shared.rb +51 -0
  47. data/lib/gooddata/client.rb +37 -24
  48. data/lib/gooddata/commands/api.rb +1 -0
  49. data/lib/gooddata/commands/auth.rb +8 -4
  50. data/lib/gooddata/commands/base.rb +2 -80
  51. data/lib/gooddata/commands/commands.rb +4 -9
  52. data/lib/gooddata/commands/datasets.rb +1 -1
  53. data/lib/gooddata/commands/runners.rb +6 -7
  54. data/lib/gooddata/connection.rb +40 -35
  55. data/lib/gooddata/core/core.rb +8 -0
  56. data/lib/gooddata/exceptions.rb +1 -1
  57. data/lib/gooddata/goodzilla/goodzilla.rb +12 -0
  58. data/lib/gooddata/models/attribute.rb +2 -0
  59. data/lib/gooddata/models/dashboard.rb +9 -2
  60. data/lib/gooddata/models/data_result.rb +3 -256
  61. data/lib/gooddata/models/data_set.rb +2 -0
  62. data/lib/gooddata/models/display_form.rb +2 -0
  63. data/lib/gooddata/models/empty_result.rb +37 -0
  64. data/lib/gooddata/models/fact.rb +2 -0
  65. data/lib/gooddata/models/metadata.rb +6 -1
  66. data/lib/gooddata/models/metric.rb +2 -1
  67. data/lib/gooddata/{model.rb → models/model.rb} +1 -1
  68. data/lib/gooddata/models/models.rb +4 -0
  69. data/lib/gooddata/models/project.rb +10 -6
  70. data/lib/gooddata/models/report.rb +6 -0
  71. data/lib/gooddata/models/report_data_result.rb +167 -0
  72. data/lib/gooddata/models/report_definition.rb +2 -0
  73. data/lib/gooddata/version.rb +15 -1
  74. data/spec/bricks/bricks_spec.rb +39 -0
  75. data/spec/helpers/blueprint_helper.rb +1 -1
  76. data/spec/helpers/connection_helper.rb +12 -0
  77. data/spec/{project_build_and_update_spec.rb → integration/command_projects_spec.rb} +0 -3
  78. data/spec/{full_project_spec.rb → integration/full_project_spec.rb} +0 -3
  79. data/spec/logging_in_logging_out_spec.rb +17 -0
  80. data/spec/spec_helper.rb +6 -1
  81. data/spec/unit/bricks/bricks_spec.rb +23 -0
  82. data/spec/unit/bricks/middleware/bench_middleware_spec.rb +9 -0
  83. data/spec/unit/bricks/middleware/bulk_salesforce_middleware_spec.rb +9 -0
  84. data/spec/unit/bricks/middleware/gooddata_middleware_spec.rb +9 -0
  85. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +9 -0
  86. data/spec/unit/bricks/middleware/restforce_middleware_spec.rb +9 -0
  87. data/spec/unit/bricks/middleware/stdout_middleware_spec.rb +9 -0
  88. data/spec/unit/bricks/middleware/twitter_middleware_spec.rb +9 -0
  89. data/spec/unit/cli/cli_spec.rb +11 -0
  90. data/spec/unit/cli/commands/cmd_api_spec.rb +11 -0
  91. data/spec/unit/cli/commands/cmd_auth_spec.rb +11 -0
  92. data/spec/unit/cli/commands/cmd_process_spec.rb +11 -0
  93. data/spec/unit/cli/commands/cmd_profile_spec.rb +11 -0
  94. data/spec/unit/cli/commands/cmd_project_spec.rb +11 -0
  95. data/spec/unit/cli/commands/cmd_run_ruby_spec.rb +11 -0
  96. data/spec/unit/cli/commands/cmd_scaffold_spec.rb +11 -0
  97. data/spec/unit/commands/command_api_spec.rb +12 -0
  98. data/spec/unit/commands/command_auth_spec.rb +12 -0
  99. data/spec/unit/commands/command_dataset_spec.rb +12 -0
  100. data/spec/unit/commands/command_process_spec.rb +12 -0
  101. data/spec/unit/commands/command_profile_spec.rb +12 -0
  102. data/spec/unit/commands/command_projects_spec.rb +12 -0
  103. data/spec/unit/commands/command_scaffold_spec.rb +12 -0
  104. data/spec/unit/core/connection_spec.rb +25 -0
  105. data/spec/unit/core/core_spec.rb +7 -0
  106. data/spec/{goodzilla_spec.rb → unit/godzilla/goodzilla_spec.rb} +0 -0
  107. data/spec/{blueprint_spec.rb → unit/model/blueprint_spec.rb} +3 -3
  108. data/spec/{merging_blueprints_spec.rb → unit/model/model_spec.rb} +28 -26
  109. data/spec/{model_spec.rb → unit/model/project_blueprint_spec.rb} +0 -0
  110. data/spec/{model_dsl_spec.rb → unit/model/schema_builder_spec.rb} +1 -1
  111. metadata +77 -61
@@ -0,0 +1,8 @@
1
+ # require File.join(File.dirname(__FILE__), "")
2
+
3
+ module GoodData
4
+
5
+ # Core of GoodData Gem
6
+ class Core
7
+ end
8
+ end
@@ -2,6 +2,6 @@ module GoodData
2
2
 
3
3
  # Project Not Found
4
4
  class ProjectNotFound < RestClient::ResourceNotFound
5
-
6
5
  end
6
+
7
7
  end
@@ -1,17 +1,29 @@
1
1
  module GoodData::SmallGoodZilla
2
2
 
3
+ # Get IDs from MAQL string
4
+ # @param a_maql_string Input MAQL string
5
+ # @return [Array<String>] List of IDS
3
6
  def self.get_ids(a_maql_string)
4
7
  a_maql_string.scan(/!\[([^\"]+)\]/).flatten
5
8
  end
6
9
 
10
+ # Get Facts from MAQL string
11
+ # @param a_maql_string Input MAQL string
12
+ # @return [Array<String>] List of Facts
7
13
  def self.get_facts(a_maql_string)
8
14
  a_maql_string.scan(/#\"([^\"]+)\"/).flatten
9
15
  end
10
16
 
17
+ # Get Attributes from MAQL string
18
+ # @param a_maql_string Input MAQL string
19
+ # @return [Array<String>] List of Attributes
11
20
  def self.get_attributes(a_maql_string)
12
21
  a_maql_string.scan(/@\"([^\"]+)\"/).flatten
13
22
  end
14
23
 
24
+ # Get Metrics from MAQL string
25
+ # @param a_maql_string Input MAQL string
26
+ # @return [Array<String>] List of Metrics
15
27
  def self.get_metrics(a_maql_string)
16
28
  a_maql_string.scan(/\?"([^\"]+)\"/).flatten
17
29
  end
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "metadata")
2
+
1
3
  module GoodData
2
4
  class Attribute < GoodData::MdObject
3
5
 
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "metadata")
2
+
1
3
  module GoodData
2
4
  class Dashboard < GoodData::MdObject
3
5
 
@@ -6,7 +8,7 @@ module GoodData
6
8
  class << self
7
9
  def [](id)
8
10
  if id == :all
9
- GoodData.get(GoodData.project.md['query'] + '/projectDashboard/')['query']['entries']
11
+ GoodData.get(GoodData.project.md['query'] + '/projectdashboards/')['query']['entries']
10
12
  else
11
13
  super
12
14
  end
@@ -70,11 +72,16 @@ module GoodData
70
72
 
71
73
  end
72
74
 
75
+ def exportable?
76
+ true
77
+ end
78
+
73
79
  def export(format, options={})
74
80
  supported_formats = [:pdf]
75
81
  fail "Wrong format provied \"#{format}\". Only supports formats #{supported_formats.join(', ')}" unless supported_formats.include?(format)
76
82
  tab = options[:tab] || ""
77
- x = GoodData.post("/gdc/projects/#{GoodData.project.uri}/clientexport", {"clientExport" => {"url" => "https://secure.gooddata.com/dashboard.html#project=#{GoodData.project.uri}&dashboard=#{uri}&tab=#{tab}&export=1", "name" => title}}, :process => false)
83
+
84
+ x = GoodData.post("#{GoodData.project.uri}/clientexport", {"clientExport" => {"url" => "https://secure.gooddata.com/dashboard.html#project=#{GoodData.project.uri}&dashboard=#{uri}&tab=#{tab}&export=1", "name" => title}}, :process => false)
78
85
  while (x.code == 202) do
79
86
  sleep(1)
80
87
  uri = JSON.parse(x.body)["asyncTask"]["link"]["poll"]
@@ -1,3 +1,6 @@
1
+ require 'active_support/all'
2
+
3
+ # TODO: Move to some shared helper
1
4
  class BigDecimal; def pretty_print(p) p.text to_s; end; end
2
5
 
3
6
  module GoodData
@@ -33,260 +36,4 @@ module GoodData
33
36
 
34
37
  end
35
38
 
36
- class EmptyResult < DataResult
37
-
38
- def initialize(data, options = {})
39
- super(data)
40
- @options = options
41
- assemble_table
42
- end
43
-
44
- def to_s
45
- "No Data"
46
- end
47
-
48
- def assemble_table
49
- @table = [[]]
50
- # CSV::Table.new([GoodData::Row.new([],[],false)])
51
- end
52
-
53
- def to_table
54
- @table
55
- end
56
-
57
- def without_column_headers
58
- @table
59
- end
60
-
61
- def == (otherDataResult)
62
- false
63
- end
64
-
65
- def diff(otherDataResult)
66
- ['empty']
67
- end
68
- end
69
-
70
- # class SFDataResult < DataResult
71
- #
72
- # def initialize(data, options = {})
73
- # super(data)
74
- # @options = options
75
- # assemble_table
76
- # end
77
- #
78
- # def assemble_table
79
- # sf_data = data[:queryResponse][:result][:records]
80
- # sf_data = sf_data.is_a?(Hash) ? [sf_data] : sf_data
81
- # if @options[:soql]
82
- # # puts @options[:soql]
83
- # fields = @options[:soql].strip.match(/SELECT (.*) FROM/i)[1]
84
- # @headers = fields.strip.split(",").map do |item|
85
- # item.strip.split(/\s/)
86
- # end.map do |item|
87
- # item.last.to_sym
88
- # end
89
- # # pp @headers
90
- # elsif @options[:headers]
91
- # @headers = @options[:headers]
92
- # else
93
- # @headers = sf_data.first.keys - [:type, :Id]
94
- # end
95
- # @table = CSV::Table.new(sf_data.collect do |line|
96
- # GoodData::Row.new([], @headers.map {|h| line[h] || ' '}, false)
97
- # end)
98
- # rescue
99
- # fail "Unable to assemble the table. Either the data provided are empty or the SOQL is malformed."
100
- # end
101
- #
102
- # def to_table
103
- # @table
104
- # end
105
- #
106
- # def == (otherDataResult)
107
- # result = true
108
- # len = @table.length
109
- # other_table = otherDataResult.to_table
110
- # if len != other_table.length
111
- # # puts "TABLES ARE OF DIFFERENT SIZES"
112
- # return false
113
- # end
114
- #
115
- # diff(otherDataResult).empty?() ? true : false
116
- #
117
- # end
118
- #
119
- # def diff(otherDataResult)
120
- # other_table = otherDataResult.to_table
121
- # differences = []
122
- #
123
- # @table.each do |row|
124
- # differences << row unless other_table.detect {|r| r == row}
125
- # end
126
- # differences
127
- # end
128
- #
129
- # end
130
-
131
- class ReportDataResult < DataResult
132
-
133
- ROW_LIMIT = 10000000
134
-
135
- attr_reader :row_headers, :column_headers, :table, :headers_height, :headers_width
136
-
137
- def initialize(data)
138
- super
139
- @row_headers = []
140
- @column_headers = []
141
- @table = []
142
-
143
- @row_headers, @headers_width = tabularize_rows
144
- @column_headers, @headers_height = tabularize_columns
145
-
146
- assemble_table
147
- end
148
-
149
- def without_column_headers
150
- @table = table.transpose[headers_height, ROW_LIMIT].transpose
151
- self
152
- end
153
-
154
- def to_data_table
155
- table.transpose[headers_height, ROW_LIMIT].transpose[headers_width, ROW_LIMIT]
156
- end
157
-
158
- def each_line
159
- to_table.each {|line| yield line}
160
- end
161
- alias :each_row :each_line
162
-
163
- def each_column
164
- table.each {|line| yield line}
165
- end
166
-
167
- def to_a
168
- table.to_a
169
- end
170
-
171
- def to_table
172
- table.transpose
173
- end
174
-
175
- def [](index)
176
- to_table[index]
177
- end
178
- alias :row :[]
179
-
180
- def column(index)
181
- table[index]
182
- end
183
-
184
- def include_row?(row)
185
- to_table.include?(row)
186
- end
187
-
188
- def include_column?(row)
189
- table.include?(row)
190
- end
191
-
192
- def == (otherDataResult)
193
- result = true
194
- csv_table = to_table
195
- len = csv_table.length
196
- table = otherDataResult.respond_to?(:to_table) ? otherDataResult.to_table : otherDataResult
197
- return false if len != table.length
198
- diff(otherDataResult).empty?() ? true : false
199
- end
200
-
201
- def diff(otherDataResult)
202
- csv_table = to_table
203
- other_table = otherDataResult.respond_to?(:to_table) ? otherDataResult.to_table : otherDataResult
204
- differences = []
205
-
206
- csv_table.each do |row|
207
- differences << row unless other_table.detect {|r| r == row}
208
- end
209
- differences
210
- end
211
-
212
- private
213
- def each_level(table, level, children, lookup)
214
- max_level = level + 1
215
- children.each do |kid|
216
- first = kid["first"]
217
- last = kid["last"]
218
- repetition = last - first + 1
219
- repetition.times do |i|
220
- table[first + i] ||= []
221
- if kid["type"] == 'total'
222
- table[first + i][level] = kid["id"]
223
- else
224
- table[first + i][level] = lookup[level][kid["id"].to_s]
225
- end
226
- end
227
- if (!kid["children"].empty?)
228
- new_level = each_level(table, level+1, kid["children"], lookup)
229
- max_level = [max_level, new_level].max
230
- end
231
- end
232
- max_level
233
- end
234
-
235
- def tabularize_rows
236
- rows = data["xtab_data"]["rows"]
237
- kids = rows["tree"]["children"]
238
-
239
- if kids.empty? || (kids.size == 1 && kids.first['type'] == 'metric')
240
- headers, size = [[nil]], 0
241
- else
242
- headers = []
243
- size = each_level(headers, 0, rows["tree"]["children"], rows["lookups"])
244
- end
245
- return headers, size
246
- end
247
-
248
- def tabularize_columns
249
- columns = data["xtab_data"]["columns"]
250
- kids = columns["tree"]["children"]
251
-
252
- if kids.empty? || (kids.size == 1 && kids.first['type'] == 'metric')
253
- headers, size = [[nil]], 0
254
- else
255
- headers = []
256
- size = each_level(headers, 0, columns["tree"]["children"], columns["lookups"])
257
- end
258
- return headers, size
259
- end
260
-
261
- def assemble_table()
262
- # puts "=== COLUMNS === #{column_headers.size}x#{headers_height}"
263
- (column_headers.size).times do |i|
264
- (headers_height).times do |j|
265
- table[headers_width + i] ||= []
266
- # puts "[#{headers_width + i}][#{j}] #{column_headers[i][j]}"
267
- table[headers_width + i][j] = column_headers[i][j]
268
- end
269
- end
270
-
271
- # puts "=== ROWS ==="
272
- (row_headers.size).times do |i|
273
- (headers_width).times do |j|
274
- table[j] ||= []
275
- # puts "[#{j}][#{headers_height + i}] #{row_headers[i][j]}"
276
- table[j][headers_height + i] = row_headers[i][j]
277
- end
278
- end
279
-
280
- xtab_data = data["xtab_data"]["data"]
281
- # puts "=== DATA === #{column_headers.size}x#{row_headers.size}"
282
- (column_headers.size).times do |i|
283
- (row_headers.size).times do |j|
284
- table[headers_width + i] ||= []
285
- # puts "[#{headers_width + i}, #{headers_height + j}] [#{i}][#{j}]=#{xtab_data[j][i]}"
286
- val = xtab_data[j][i]
287
- table[headers_width + i][headers_height + j] = val.nil? ? val : BigDecimal(val)
288
- end
289
- end
290
- end
291
- end
292
39
  end
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "metadata.rb")
2
+
1
3
  module GoodData
2
4
  class DataSet < MdObject
3
5
 
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "metadata")
2
+
1
3
  module GoodData
2
4
  class DisplayForm < GoodData::MdObject
3
5
 
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), "data_result.rb")
2
+
3
+ module GoodData
4
+ class EmptyResult < DataResult
5
+
6
+ def initialize(data, options = {})
7
+ super(data)
8
+ @options = options
9
+ assemble_table
10
+ end
11
+
12
+ def to_s
13
+ "No Data"
14
+ end
15
+
16
+ def assemble_table
17
+ @table = [[]]
18
+ # CSV::Table.new([GoodData::Row.new([],[],false)])
19
+ end
20
+
21
+ def to_table
22
+ @table
23
+ end
24
+
25
+ def without_column_headers
26
+ @table
27
+ end
28
+
29
+ def == (otherDataResult)
30
+ false
31
+ end
32
+
33
+ def diff(otherDataResult)
34
+ ['empty']
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), "metadata")
2
+
1
3
  module GoodData
2
4
  class Fact < GoodData::MdObject
3
5
 
@@ -1,4 +1,4 @@
1
- require 'gooddata/model'
1
+ require File.join(File.dirname(__FILE__), 'model')
2
2
 
3
3
  module GoodData
4
4
  class MdObject
@@ -180,5 +180,10 @@ module GoodData
180
180
  def validate
181
181
  true
182
182
  end
183
+
184
+ def exportable?
185
+ false
186
+ end
187
+
183
188
  end
184
189
  end
@@ -1,4 +1,5 @@
1
- require 'gooddata/goodzilla/goodzilla'
1
+ require File.join(File.dirname(__FILE__), "metadata")
2
+ require File.join(File.dirname(__FILE__), '../goodzilla/goodzilla')
2
3
 
3
4
  module GoodData
4
5
  # Metric representation
@@ -88,7 +88,7 @@ module GoodData
88
88
  end
89
89
  if (GoodData.get(task["pullTask"]["uri"])["taskStatus"] == "ERROR")
90
90
  s = StringIO.new
91
- GoodData.download_form_user_webdav(File.basename(dir) + '/upload_status.json', s)
91
+ GoodData.download_from_user_webdav(File.basename(dir) + '/upload_status.json', s)
92
92
  js = JSON.parse(s.string)
93
93
  fail "Load Failed with error #{JSON.pretty_generate(js)}"
94
94
  end