gooddata 0.6.0.pre6 → 0.6.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,12 +28,20 @@ module GoodData
28
28
  self[:all].find_all {|r| r["tags"].split(",").include?(tag)}
29
29
  end
30
30
 
31
- def find_first_by_title(title)
32
- item = self[:all].find {|r| r["title"] == title}
33
- self[item["link"]]
31
+ def get_by_id(id)
32
+ uri = GoodData::MdObject.id_to_uri(id)
33
+ self[uri] unless uri.nil?
34
34
  end
35
35
 
36
- private
36
+ def find_first_by_title(title)
37
+ all = self[:all]
38
+ item = if title.is_a?(Regexp)
39
+ all.find {|r| r["title"] =~ title}
40
+ else
41
+ all.find {|r| r["title"] == title}
42
+ end
43
+ self[item["link"]] unless item.nil?
44
+ end
37
45
 
38
46
  def identifier_to_uri(id)
39
47
  raise NoProjectError.new "Connect to a project before searching for an object" unless GoodData.project
@@ -45,6 +53,9 @@ module GoodData
45
53
  response['identifiers'][0]['uri']
46
54
  end
47
55
  end
56
+
57
+ alias :id_to_uri :identifier_to_uri
58
+
48
59
  end
49
60
 
50
61
  def initialize(json)
@@ -52,7 +63,18 @@ module GoodData
52
63
  end
53
64
 
54
65
  def delete
55
- GoodData.delete(uri)
66
+ if saved?
67
+ GoodData.delete(uri)
68
+ meta.delete("uri")
69
+ # ["uri"] = nil
70
+ end
71
+ end
72
+
73
+ def refresh
74
+ if saved?
75
+ @json = GoodData.get(uri)
76
+ end
77
+ self
56
78
  end
57
79
 
58
80
  def obj_id
@@ -64,7 +86,7 @@ module GoodData
64
86
  end
65
87
 
66
88
  def uri
67
- meta['uri']
89
+ meta && meta['uri']
68
90
  end
69
91
 
70
92
  def browser_uri
@@ -100,11 +122,11 @@ module GoodData
100
122
  end
101
123
 
102
124
  def meta
103
- data['meta']
125
+ data && data['meta']
104
126
  end
105
127
 
106
128
  def content
107
- data['content']
129
+ data && data['content']
108
130
  end
109
131
 
110
132
  def project
@@ -158,4 +180,4 @@ module GoodData
158
180
  true
159
181
  end
160
182
  end
161
- end
183
+ end
@@ -74,7 +74,7 @@ module GoodData
74
74
 
75
75
  def execute
76
76
  res = GoodData::ReportDefinition.execute(:left => self)
77
- res.to_table[0][0]
77
+ res[0][0]
78
78
  end
79
79
 
80
80
  def validate
@@ -7,68 +7,11 @@ module GoodData
7
7
  class << self
8
8
  def [](id)
9
9
  if id == :all
10
- GoodData.get("/gdc/projects/hi95siviyangv53c3vptkz1eas546pnn/dataload/processes")
10
+ GoodData.get("/gdc/projects/#{GoodData.project.pid}/dataload/processes")
11
11
  else
12
- self.new(GoodData.get("/gdc/projects/hi95siviyangv53c3vptkz1eas546pnn/dataload/processes/#{id}"))
12
+ self.new(GoodData.get("/gdc/projects/#{GoodData.project.pid}/dataload/processes/#{id}"))
13
13
  end
14
14
  end
15
-
16
- def deploy(dir, options={}, &block)
17
- if block
18
- begin
19
- res = deploy_graph(dir, options)
20
- block.call(res)
21
- ensure
22
- self_link = res["process"]["links"]["self"]
23
- GoodData.delete(self_link)
24
- end
25
- else
26
- deploy_graph(dir, options)
27
- end
28
- end
29
-
30
- def deploy_graph(dir, options={})
31
- dir = Pathname(dir)
32
- fail "Provided path (#{dir}) is not directory." unless dir.directory?
33
- type = options[:type] || "ETL"
34
-
35
- deploy_name = options[:name] || options[:project_name]
36
- verbose = options[:verbose] || false
37
- project_pid = 'hi95siviyangv53c3vptkz1eas546pnn'
38
-
39
- puts HighLine::color("Deploying #{dir}", HighLine::BOLD) if verbose
40
- res = nil
41
-
42
- Tempfile.open("deploy-graph-archive") do |temp|
43
- Zip::OutputStream.open(temp.path) do |zio|
44
- Dir.glob(dir + "**/*") do |item|
45
- puts "including #{item}" if verbose
46
- unless File.directory?(item)
47
- zio.put_next_entry(item)
48
- zio.print IO.read(item)
49
- end
50
- end
51
- end
52
-
53
- GoodData.connection.upload(temp.path)
54
- process_id = options[:process]
55
-
56
- data = {
57
- :process => {
58
- :name => deploy_name,
59
- :path => "/uploads/#{File.basename(temp.path)}",
60
- :type => type
61
- }
62
- }
63
- res = if process_id.nil?
64
- GoodData.post("/gdc/projects/#{project_pid}/dataload/processes", data)
65
- else
66
- GoodData.put("/gdc/projects/#{project_pid}/dataload/processes/#{process_id}", data)
67
- end
68
- end
69
- puts HighLine::color("Deploy DONE #{dir}", HighLine::BOLD) if verbose
70
- res
71
- end
72
15
  end
73
16
 
74
17
  def initialize(data)
@@ -90,7 +90,7 @@ module GoodData
90
90
 
91
91
  def delete
92
92
  raise "Project '#{title}' with id #{uri} is already deleted" if state == :deleted
93
- GoodData.delete data['links']['self']
93
+ GoodData.delete(uri)
94
94
  end
95
95
 
96
96
  def uri
@@ -2,15 +2,24 @@ module GoodData
2
2
  class ProjectMetadata
3
3
 
4
4
  class << self
5
+
6
+ def keys
7
+ ProjectMetadata[:all].keys
8
+ end
9
+
5
10
  def [](key)
6
11
  if key == :all
7
- GoodData.get("/gdc/projects/#{GoodData.project.pid}/dataload/metadata")
12
+ res = GoodData.get("/gdc/projects/#{GoodData.project.pid}/dataload/metadata")
13
+ res["metadataItems"]["items"].reduce({}) {|memo, i| memo[i["metadataItem"]["key"]] = i["metadataItem"]["value"]; memo}
8
14
  else
9
15
  res = GoodData.get("/gdc/projects/#{GoodData.project.pid}/dataload/metadata/#{key}")
10
16
  res["metadataItem"]["value"]
11
17
  end
12
18
  end
13
19
 
20
+ alias_method :get, :[]
21
+ alias_method :get_key, :[]
22
+
14
23
  def has_key?(key)
15
24
  begin
16
25
  ProjectMetadata[key]
@@ -49,9 +49,6 @@ module GoodData
49
49
  @json[:report][:content][:definitions] << a_definition
50
50
  end
51
51
 
52
- def to_json(options={})
53
- JSON.pretty_generate(@json, options)
54
- end
55
52
  # ----
56
53
 
57
54
 
@@ -57,11 +57,41 @@ module GoodData
57
57
  if item.respond_to?(:is_attribute?)
58
58
  item.display_forms.first
59
59
  elsif item.is_a?(String)
60
- GoodData::Attribute.find_first_by_title(item).display_forms.first
61
- elsif item.is_a?(Hash) && item[:type].to_s == "metric"
62
- GoodData::Metric.find_first_by_title(item[:title])
63
- elsif item.is_a?(Hash) && item[:type].to_s == "attribute"
64
- GoodData::Attribute.find_first_by_title(item[:title]).display_forms.first
60
+ x = GoodData::MdObject.get_by_id(item)
61
+ fail "Object given by id \"#{item}\" could not be found" if x.nil?
62
+ case x.raw_data.keys.first.to_s
63
+ when "attribute"
64
+ GoodData::Attribute.new(x.raw_data).display_forms.first
65
+ when "attributeDisplayForm"
66
+ GoodData::DisplayForm.new(x.raw_data)
67
+ when "metric"
68
+ GoodData::Metric.new(x.raw_data)
69
+ end
70
+ elsif item.is_a?(Hash) && item.keys.include?(:title)
71
+ case item[:type].to_s
72
+ when "metric"
73
+ GoodData::Metric.find_first_by_title(item[:title])
74
+ when "attribute"
75
+ GoodData::Attribute.find_first_by_title(item[:title]).display_forms.first
76
+ end
77
+ elsif item.is_a?(Hash) && (item.keys.include?(:id))
78
+ case item[:type].to_s
79
+ when "metric"
80
+ GoodData::Metric.get_by_id(item[:id])
81
+ when "attribute"
82
+ GoodData::Attribute.get_by_id(item[:id]).display_forms.first
83
+ when "label"
84
+ GoodData::DisplayForm.get_by_id(item[:id])
85
+ end
86
+ elsif item.is_a?(Hash) && (item.keys.include?(:identifier))
87
+ case item[:type].to_s
88
+ when "metric"
89
+ GoodData::Metric.get_by_id(item[:identifier])
90
+ when "attribute"
91
+ GoodData::Attribute.get_by_id(item[:identifier]).display_forms.first
92
+ when "label"
93
+ GoodData::DisplayForm.get_by_id(item[:identifier])
94
+ end
65
95
  else
66
96
  item
67
97
  end
@@ -83,8 +113,8 @@ module GoodData
83
113
  rd.save
84
114
  rd.execute
85
115
  ensure
86
- rd.delete if rd.saved? rescue nil
87
- unsaved_metrics.each {|m| m.delete if m.saved?}
116
+ rd.delete if rd && rd.saved?
117
+ unsaved_metrics.each {|m| m.delete if m && m.saved?}
88
118
  end
89
119
  end
90
120
 
@@ -126,7 +156,12 @@ module GoodData
126
156
  end
127
157
 
128
158
  def execute
129
- result = GoodData.post '/gdc/xtab2/executor3', {"report_req" => {"reportDefinition" => uri}}
159
+ result = if saved?
160
+ GoodData.post '/gdc/xtab2/executor3', {"report_req" => {"reportDefinition" => uri}}
161
+ else
162
+ # GoodData.post '/gdc/xtab2/executor3', {"report_req" => raw_data}
163
+ fail("this is currently unsupported. For executing unsaved report definitions please use class method execute.")
164
+ end
130
165
  data_result_uri = result["execResult"]["dataResult"]
131
166
  result = GoodData.get data_result_uri
132
167
  while result["taskState"] && result["taskState"]["status"] == "WAIT" do
@@ -1,3 +1,3 @@
1
1
  module GoodData
2
- VERSION = "0.6.0.pre6"
2
+ VERSION = "0.6.0.pre7"
3
3
  end
@@ -0,0 +1,54 @@
1
+ require 'gooddata'
2
+
3
+ describe "Spin a project", :constraint => 'slow' do
4
+
5
+ before(:all) do
6
+ spec = JSON.parse(File.read("./spec/test_project_model_spec.json"), :symbolize_names => true)
7
+ GoodData.connect("svarovsky+gem_tester@gooddata.com", "jindrisska")
8
+ GoodData.logging_on
9
+
10
+ @project = GoodData::Model::ProjectCreator.migrate({:spec => spec, :token => "INTNA000000GDPM"})
11
+ end
12
+
13
+ after(:all) do
14
+ @project.delete unless @project.nil?
15
+ end
16
+
17
+ it "should compute a metric" do
18
+ GoodData.with_project(@project) do |p|
19
+ f = GoodData::Fact.find_first_by_title('Lines changed')
20
+ metric = GoodData::Metric.xcreate("SELECT SUM(#\"#{f.title}\")")
21
+ metric.execute.should == 9
22
+ end
23
+ end
24
+
25
+ it "should execute an anonymous metric twice and not fail" do
26
+ GoodData.with_project(@project) do |p|
27
+ f = GoodData::Fact.find_first_by_title('Lines changed')
28
+ metric = GoodData::Metric.xcreate("SELECT SUM(#\"#{f.title}\")")
29
+ metric.execute.should == 9
30
+ # Since GD platform cannot execute inline specified metric the metric has to be saved
31
+ # The code tries to resolve this as transparently as possible
32
+ metric.execute.should == 9
33
+ end
34
+ end
35
+
36
+ it "should compute a report" do
37
+ GoodData.with_project(@project) do |p|
38
+ f = GoodData::Fact.find_first_by_title('Lines changed')
39
+ metric = GoodData::Metric.xcreate(:title => "My metric", :expression => "SELECT SUM(#\"#{f.title}\")")
40
+ metric.save
41
+
42
+ result = GoodData::ReportDefinition.execute(:title => "My report", :top => [metric], :left => ['label.devs.email'])
43
+ result[1][1].should == 3
44
+ result.include_row?(["jirka@gooddata.com", 5]).should == true
45
+ end
46
+ end
47
+
48
+ it "should contain metadata for each dataset in project metadata" do
49
+ GoodData.with_project(@project) do |p|
50
+ k = GoodData::ProjectMetadata.keys
51
+ k.should include("manifest_devs")
52
+ end
53
+ end
54
+ end
@@ -1,4 +1,4 @@
1
- require 'gooddata/goodzilla/goodzilla'
1
+ require 'gooddata'
2
2
 
3
3
  describe GoodData::SmallGoodZilla do
4
4
 
@@ -54,4 +54,4 @@ describe GoodData::SmallGoodZilla do
54
54
  interpolated.should == "SELECT SUM([a]) WHERE [d]=[x] AND [snap]=1"
55
55
  end
56
56
 
57
- end
57
+ end
@@ -6,7 +6,8 @@ describe GoodData::Model::SchemaBuilder do
6
6
  it "should create a schema" do
7
7
  builder = GoodData::Model::SchemaBuilder.new("a_title")
8
8
  schema = builder.to_schema
9
- schema.title.should == "a_title"
9
+ schema.title.should == "A title"
10
+ schema.name.should == "a_title"
10
11
  end
11
12
 
12
13
  it "should create a schema with some columns" do
@@ -0,0 +1,86 @@
1
+ {
2
+ "title": "Dev Week test",
3
+ "datasets": [
4
+ {
5
+ "name": "repos",
6
+ "columns": [
7
+ {
8
+ "type": "anchor",
9
+ "name": "id"
10
+ },
11
+ {
12
+ "type": "label",
13
+ "name": "name",
14
+ "reference": "id"
15
+ }
16
+ ]
17
+ },
18
+ {
19
+ "name": "devs",
20
+ "columns": [
21
+ {
22
+ "type": "anchor",
23
+ "name": "id"
24
+ },
25
+ {
26
+ "type": "label",
27
+ "name": "email",
28
+ "reference": "id"
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "name": "commits",
34
+ "columns": [
35
+ {
36
+ "type": "fact",
37
+ "name": "lines_changed"
38
+ },
39
+ {
40
+ "type": "date",
41
+ "name": "committed_on",
42
+ "dataset": "committed_on"
43
+ },
44
+ {
45
+ "type": "reference",
46
+ "name": "dev_id",
47
+ "dataset": "devs",
48
+ "reference": "id"
49
+ },
50
+ {
51
+ "type": "reference",
52
+ "name": "repo_id",
53
+ "dataset": "repos",
54
+ "reference": "id"
55
+ }
56
+ ]
57
+ }
58
+ ],
59
+ "uploads": [
60
+ {
61
+ "source":
62
+ [["lines_changed","committed_on","dev_id","repo_id"],
63
+ [1,"01/01/2014",1,1],
64
+ [3,"01/02/2014",2,2],
65
+ [5,"05/02/2014",3,1]],
66
+ "mode": "FULL",
67
+ "dataset": "commits"
68
+ },
69
+ {
70
+ "source":
71
+ [["id", "email"],
72
+ [1, "tomas@gooddata.com"],
73
+ [2, "petr@gooddata.com"],
74
+ [3, "jirka@gooddata.com"]],
75
+ "mode": "FULL",
76
+ "dataset": "devs"
77
+ }
78
+ ],
79
+ "date_dimensions": [
80
+ {
81
+ "urn": null,
82
+ "name": "committed_on",
83
+ "title": null
84
+ }
85
+ ]
86
+ }