gooddata 0.5.1 → 0.5.2
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.
- data/VERSION +1 -1
- data/lib/gooddata/client.rb +6 -6
- data/lib/gooddata/connection.rb +21 -12
- data/lib/gooddata/models/data_result.rb +50 -5
- data/lib/gooddata/models/report.rb +4 -3
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.2
|
data/lib/gooddata/client.rb
CHANGED
@@ -129,8 +129,8 @@ module GoodData
|
|
129
129
|
# === Examples
|
130
130
|
#
|
131
131
|
# GoodData.get '/gdc/projects'
|
132
|
-
def get(path)
|
133
|
-
connection.get(path)
|
132
|
+
def get(path, options = {})
|
133
|
+
connection.get(path, options)
|
134
134
|
end
|
135
135
|
|
136
136
|
# Performs a HTTP POST request.
|
@@ -145,8 +145,8 @@ module GoodData
|
|
145
145
|
# === Examples
|
146
146
|
#
|
147
147
|
# GoodData.post '/gdc/projects', { ... }
|
148
|
-
def post(path, data)
|
149
|
-
connection.post path, data
|
148
|
+
def post(path, data, options = {})
|
149
|
+
connection.post path, data, options
|
150
150
|
end
|
151
151
|
|
152
152
|
# Performs a HTTP DELETE request.
|
@@ -160,8 +160,8 @@ module GoodData
|
|
160
160
|
# === Examples
|
161
161
|
#
|
162
162
|
# GoodData.delete '/gdc/project/1'
|
163
|
-
def delete(path)
|
164
|
-
connection.delete path
|
163
|
+
def delete(path, options = {})
|
164
|
+
connection.delete path, options
|
165
165
|
end
|
166
166
|
|
167
167
|
def test_login
|
data/lib/gooddata/connection.rb
CHANGED
@@ -32,7 +32,7 @@ module GoodData
|
|
32
32
|
DEFAULT_URL = 'https://secure.gooddata.com'
|
33
33
|
LOGIN_PATH = '/gdc/account/login'
|
34
34
|
TOKEN_PATH = '/gdc/account/token'
|
35
|
-
STAGE_PATH = '/uploads'
|
35
|
+
STAGE_PATH = '/uploads/'
|
36
36
|
|
37
37
|
# Set the GoodData account credentials.
|
38
38
|
#
|
@@ -68,9 +68,11 @@ module GoodData
|
|
68
68
|
#
|
69
69
|
# Connection.new(username, password).get '/gdc/projects'
|
70
70
|
def get(path, options = {})
|
71
|
+
pp options
|
71
72
|
GoodData.logger.debug "GET #{path}"
|
72
73
|
ensure_connection
|
73
|
-
|
74
|
+
b = Proc.new { @server[path].get cookies }
|
75
|
+
response = (options[:process] == false) ? (b.call) : process_response(options, &b)
|
74
76
|
end
|
75
77
|
|
76
78
|
# Performs a HTTP POST request.
|
@@ -86,10 +88,11 @@ module GoodData
|
|
86
88
|
#
|
87
89
|
# Connection.new(username, password).post '/gdc/projects', { ... }
|
88
90
|
def post(path, data, options = {})
|
89
|
-
payload = data.to_json
|
91
|
+
payload = data.is_a?(Hash) ? data.to_json : data
|
90
92
|
GoodData.logger.debug "POST #{path}, payload: #{payload}"
|
91
93
|
ensure_connection
|
92
|
-
|
94
|
+
b = Proc.new { @server[path].post payload, cookies }
|
95
|
+
options[:process] == false ? b.call : process_response(options, &b)
|
93
96
|
end
|
94
97
|
|
95
98
|
# Performs a HTTP DELETE request.
|
@@ -103,10 +106,11 @@ module GoodData
|
|
103
106
|
# === Examples
|
104
107
|
#
|
105
108
|
# Connection.new(username, password).delete '/gdc/project/1'
|
106
|
-
def delete(path)
|
109
|
+
def delete(path, options = {})
|
107
110
|
GoodData.logger.debug "DELETE #{path}"
|
108
111
|
ensure_connection
|
109
|
-
|
112
|
+
b = Proc.new { @server[path].delete cookies }
|
113
|
+
options[:process] == false ? b.call : process_response(options, &b)
|
110
114
|
end
|
111
115
|
|
112
116
|
# Get the cookies associated with the current connection.
|
@@ -137,19 +141,23 @@ module GoodData
|
|
137
141
|
# /uploads/ resources are special in that they use a different
|
138
142
|
# host and a basic authentication.
|
139
143
|
def upload(file, dir = nil)
|
144
|
+
ensure_connection
|
140
145
|
# We should have followed a link. If it was correct.
|
141
146
|
stage_url = DEFAULT_URL.sub(/\./, '-di.')
|
142
147
|
|
143
148
|
# Make a directory, if needed
|
144
149
|
if dir then
|
150
|
+
method = :mkcol
|
151
|
+
url = stage_url + STAGE_PATH + dir + '/'
|
152
|
+
GoodData.logger.debug "#{method}: #{url}"
|
145
153
|
RestClient::Request.execute(
|
146
|
-
:method =>
|
147
|
-
:url =>
|
154
|
+
:method => method,
|
155
|
+
:url => url,
|
148
156
|
:user => @username,
|
149
157
|
:password => @password,
|
150
158
|
:timeout => @options[:timeout],
|
151
159
|
:headers => {
|
152
|
-
:user_agent => GoodData.gem_version_string
|
160
|
+
:user_agent => GoodData.gem_version_string
|
153
161
|
}
|
154
162
|
)
|
155
163
|
end
|
@@ -204,14 +212,14 @@ module GoodData
|
|
204
212
|
@status = :logged_in
|
205
213
|
end
|
206
214
|
|
207
|
-
def process_response(options = {})
|
215
|
+
def process_response(options = {}, &block)
|
208
216
|
begin
|
209
217
|
begin
|
210
|
-
response =
|
218
|
+
response = block.call
|
211
219
|
rescue RestClient::Unauthorized
|
212
220
|
raise $! if options[:dont_reauth]
|
213
221
|
refresh_token
|
214
|
-
response =
|
222
|
+
response = block.call
|
215
223
|
end
|
216
224
|
merge_cookies! response.cookies
|
217
225
|
content_type = response.headers[:content_type]
|
@@ -223,6 +231,7 @@ module GoodData
|
|
223
231
|
GoodData.logger.debug "Response: a zipped stream"
|
224
232
|
elsif response.headers[:content_length].to_s == '0'
|
225
233
|
result = nil
|
234
|
+
GoodData.logger.debug "Response: Empty response possibly 204"
|
226
235
|
else
|
227
236
|
raise "Unsupported response content type '%s':\n%s" % [ content_type, response.to_str[0..127] ]
|
228
237
|
end
|
@@ -17,12 +17,15 @@ module GoodData
|
|
17
17
|
private
|
18
18
|
def convert_field(val)
|
19
19
|
if val.is_a?(String) && val.match(/^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/)
|
20
|
+
# Is it a Number?
|
20
21
|
val = val.scan(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/).first
|
21
22
|
val = val.include?('.') ? val.to_f.round : val.to_i
|
22
23
|
return val
|
23
|
-
elsif val.nil? || val
|
24
|
-
|
24
|
+
elsif val.nil? || (val.respond_to?(:strip) && val.strip.empty?)
|
25
|
+
#is ia a String
|
26
|
+
return ''
|
25
27
|
elsif val.respond_to? :round
|
28
|
+
# No idea what that one does
|
26
29
|
return val.round
|
27
30
|
else
|
28
31
|
return val
|
@@ -39,14 +42,17 @@ module GoodData
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def print
|
45
|
+
puts to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
42
49
|
a = to_table.to_a
|
43
50
|
a.transpose.unshift((1..a.length).to_a).each_with_index.map{|col, i|
|
44
51
|
col.unshift(i.zero?? nil : i) # inserts row labels #
|
45
52
|
w = col.map{|cell| cell.to_s.length}.max # w = "column width" #
|
46
53
|
col.each_with_index.map{|cell, i|
|
47
54
|
i.zero?? cell.to_s.center(w) : cell.to_s.ljust(w)} # alligns the column #
|
48
|
-
}.transpose.
|
49
|
-
nil
|
55
|
+
}.transpose.map{|row| "[#{row.join(' | ')}]"}.join("\n")
|
50
56
|
end
|
51
57
|
|
52
58
|
def to_table
|
@@ -55,6 +61,38 @@ module GoodData
|
|
55
61
|
|
56
62
|
end
|
57
63
|
|
64
|
+
class EmptyResult < DataResult
|
65
|
+
|
66
|
+
def initialize(data, options = {})
|
67
|
+
super(data)
|
68
|
+
@options = options
|
69
|
+
assemble_table
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_s
|
73
|
+
"No Data"
|
74
|
+
end
|
75
|
+
|
76
|
+
def assemble_table
|
77
|
+
@table = FasterCSV::Table.new([GoodData::Row.new([],[],false)])
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_table
|
81
|
+
@table
|
82
|
+
end
|
83
|
+
|
84
|
+
def without_column_headers
|
85
|
+
@table
|
86
|
+
end
|
87
|
+
|
88
|
+
def == (otherDataResult)
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
def diff(otherDataResult)
|
93
|
+
['empty']
|
94
|
+
end
|
95
|
+
end
|
58
96
|
|
59
97
|
class SFDataResult < DataResult
|
60
98
|
|
@@ -68,7 +106,14 @@ module GoodData
|
|
68
106
|
sf_data = data[:queryResponse][:result][:records]
|
69
107
|
sf_data = sf_data.is_a?(Hash) ? [sf_data] : sf_data
|
70
108
|
if @options[:soql]
|
71
|
-
|
109
|
+
# puts @options[:soql]
|
110
|
+
fields = @options[:soql].strip.match(/SELECT (.*) FROM/i)[1]
|
111
|
+
@headers = fields.strip.split(",").map do |item|
|
112
|
+
item.strip.split(/\s/)
|
113
|
+
end.map do |item|
|
114
|
+
item.last.to_sym
|
115
|
+
end
|
116
|
+
# pp @headers
|
72
117
|
elsif @options[:headers]
|
73
118
|
@headers = @options[:headers]
|
74
119
|
else
|
@@ -14,15 +14,16 @@ module GoodData
|
|
14
14
|
def execute
|
15
15
|
# puts "Executing report #{uri}"
|
16
16
|
result = GoodData.post '/gdc/xtab2/executor3', {"report_req" => {"report" => uri}}
|
17
|
+
|
17
18
|
dataResultUri = result["reportResult2"]["content"]["dataResult"]
|
18
|
-
|
19
19
|
result = GoodData.get dataResultUri
|
20
|
+
return EmptyResult.new([]) if result.nil?
|
21
|
+
|
20
22
|
while result["taskState"] && result["taskState"]["status"] == "WAIT" do
|
21
23
|
sleep 10
|
22
24
|
result = GoodData.get dataResultUri
|
23
25
|
end
|
24
|
-
|
25
|
-
data_result
|
26
|
+
ReportDataResult.new(GoodData.get dataResultUri)
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gooddata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 2
|
10
|
+
version: 0.5.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pavel Kolesnikov
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-
|
19
|
+
date: 2012-02-14 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|