gooddata 0.6.0.pre11 → 0.6.0

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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +12 -1
  3. data/.yardopts +2 -0
  4. data/README.md +6 -3
  5. data/Rakefile +24 -7
  6. data/gooddata +2 -2
  7. data/gooddata.gemspec +4 -3
  8. data/lib/gooddata.rb +17 -12
  9. data/lib/gooddata/bricks/base_downloader.rb +7 -7
  10. data/lib/gooddata/bricks/brick.rb +7 -8
  11. data/lib/gooddata/bricks/bricks.rb +4 -1
  12. data/lib/gooddata/bricks/middleware/base_middleware.rb +2 -2
  13. data/lib/gooddata/bricks/middleware/bench_middleware.rb +5 -6
  14. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +21 -22
  15. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +3 -4
  16. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +14 -14
  17. data/lib/gooddata/bricks/middleware/logger_middleware.rb +6 -6
  18. data/lib/gooddata/bricks/middleware/middleware.rb +4 -1
  19. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +29 -32
  20. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +5 -5
  21. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +6 -8
  22. data/lib/gooddata/bricks/utils.rb +3 -3
  23. data/lib/gooddata/cli/cli.rb +4 -2
  24. data/lib/gooddata/cli/commands/api_cmd.rb +6 -4
  25. data/lib/gooddata/cli/commands/auth_cmd.rb +5 -3
  26. data/lib/gooddata/cli/commands/console_cmd.rb +1 -1
  27. data/lib/gooddata/cli/commands/process_cmd.rb +6 -4
  28. data/lib/gooddata/cli/commands/profile_cmd.rb +5 -3
  29. data/lib/gooddata/cli/commands/project_cmd.rb +24 -22
  30. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +12 -10
  31. data/lib/gooddata/cli/commands/scaffold_cmd.rb +8 -6
  32. data/lib/gooddata/cli/hooks.rb +4 -2
  33. data/lib/gooddata/cli/shared.rb +3 -1
  34. data/lib/gooddata/cli/terminal.rb +16 -0
  35. data/lib/gooddata/client.rb +28 -22
  36. data/lib/gooddata/commands/api.rb +43 -26
  37. data/lib/gooddata/commands/auth.rb +22 -53
  38. data/lib/gooddata/commands/base.rb +2 -0
  39. data/lib/gooddata/commands/commands.rb +3 -0
  40. data/lib/gooddata/commands/datasets.rb +39 -136
  41. data/lib/gooddata/commands/process.rb +134 -130
  42. data/lib/gooddata/commands/profile.rb +2 -0
  43. data/lib/gooddata/commands/projects.rb +91 -129
  44. data/lib/gooddata/commands/runners.rb +11 -11
  45. data/lib/gooddata/commands/scaffold.rb +28 -26
  46. data/lib/gooddata/connection.rb +61 -68
  47. data/lib/gooddata/core/core.rb +1 -2
  48. data/lib/gooddata/data/data.rb +7 -0
  49. data/lib/gooddata/data/guesser.rb +114 -0
  50. data/lib/gooddata/exceptions/command_failed.rb +7 -0
  51. data/lib/gooddata/exceptions/exceptions.rb +7 -0
  52. data/lib/gooddata/{exceptions.rb → exceptions/project_not_found.rb} +2 -2
  53. data/lib/gooddata/extensions/big_decimal.rb +5 -0
  54. data/lib/gooddata/extract.rb +2 -0
  55. data/lib/gooddata/goodzilla/goodzilla.rb +11 -12
  56. data/lib/gooddata/helpers.rb +49 -35
  57. data/lib/gooddata/models/attribute.rb +7 -5
  58. data/lib/gooddata/models/dashboard.rb +44 -45
  59. data/lib/gooddata/models/data_result.rb +10 -13
  60. data/lib/gooddata/models/data_set.rb +6 -6
  61. data/lib/gooddata/models/display_form.rb +4 -4
  62. data/lib/gooddata/models/empty_result.rb +4 -3
  63. data/lib/gooddata/models/fact.rb +5 -5
  64. data/lib/gooddata/models/links.rb +3 -1
  65. data/lib/gooddata/models/metadata.rb +34 -32
  66. data/lib/gooddata/models/metric.rb +33 -34
  67. data/lib/gooddata/models/model.rb +165 -173
  68. data/lib/gooddata/models/models.rb +3 -0
  69. data/lib/gooddata/models/process.rb +18 -17
  70. data/lib/gooddata/models/profile.rb +3 -1
  71. data/lib/gooddata/models/project.rb +107 -35
  72. data/lib/gooddata/models/project_metadata.rb +12 -12
  73. data/lib/gooddata/models/report.rb +31 -30
  74. data/lib/gooddata/models/report_data_result.rb +22 -19
  75. data/lib/gooddata/models/report_definition.rb +101 -80
  76. data/lib/gooddata/version.rb +5 -3
  77. data/lib/templates/bricks/brick.rb.erb +3 -3
  78. data/lib/templates/bricks/main.rb.erb +3 -2
  79. data/lib/templates/project/Goodfile.erb +2 -2
  80. data/lib/templates/project/model/model.rb.erb +19 -19
  81. data/spec/data/.gooddata +4 -0
  82. data/spec/helpers/blueprint_helper.rb +2 -2
  83. data/spec/helpers/cli_helper.rb +28 -0
  84. data/spec/helpers/connection_helper.rb +2 -2
  85. data/spec/integration/command_projects_spec.rb +1 -1
  86. data/spec/integration/create_from_template_spec.rb +12 -0
  87. data/spec/integration/full_project_spec.rb +2 -2
  88. data/spec/integration/partial_md_export_import_spec.rb +36 -0
  89. data/spec/logging_in_logging_out_spec.rb +1 -1
  90. data/spec/spec_helper.rb +29 -2
  91. data/spec/unit/cli/cli_spec.rb +3 -3
  92. data/spec/unit/cli/commands/cmd_api_spec.rb +21 -4
  93. data/spec/unit/cli/commands/cmd_auth_spec.rb +2 -4
  94. data/spec/unit/cli/commands/cmd_process_spec.rb +20 -4
  95. data/spec/unit/cli/commands/cmd_profile_spec.rb +9 -4
  96. data/spec/unit/cli/commands/cmd_project_spec.rb +53 -4
  97. data/spec/unit/cli/commands/cmd_run_ruby_spec.rb +2 -4
  98. data/spec/unit/cli/commands/cmd_scaffold_spec.rb +14 -4
  99. data/spec/unit/commands/command_api_spec.rb +21 -2
  100. data/spec/unit/commands/command_auth_spec.rb +62 -1
  101. data/spec/unit/commands/command_dataset_spec.rb +31 -3
  102. data/spec/unit/commands/command_process_spec.rb +75 -1
  103. data/spec/unit/commands/command_profile_spec.rb +7 -1
  104. data/spec/unit/commands/command_projects_spec.rb +1 -1
  105. data/spec/unit/commands/command_scaffold_spec.rb +46 -1
  106. data/spec/unit/core/connection_spec.rb +1 -0
  107. data/spec/unit/data/guesser_spec.rb +54 -0
  108. data/spec/unit/helpers_spec.rb +47 -0
  109. data/spec/unit/model/schema_builder_spec.rb +2 -0
  110. data/spec/unit/model/tools_spec.rb +89 -0
  111. data/test/test_upload.rb +39 -15
  112. metadata +98 -75
  113. data/test/test_commands.rb +0 -85
  114. data/test/test_guessing.rb +0 -46
  115. data/test/test_model.rb +0 -81
  116. data/test/test_rest_api_basic.rb +0 -41
@@ -1,8 +1,9 @@
1
- require File.join(File.dirname(__FILE__), "data_result.rb")
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'data_result.rb'
2
4
 
3
5
  module GoodData
4
6
  class EmptyResult < DataResult
5
-
6
7
  def initialize(data, options = {})
7
8
  super(data)
8
9
  @options = options
@@ -10,7 +11,7 @@ module GoodData
10
11
  end
11
12
 
12
13
  def to_s
13
- "No Data"
14
+ 'No Data'
14
15
  end
15
16
 
16
17
  def assemble_table
@@ -1,19 +1,19 @@
1
- require File.join(File.dirname(__FILE__), "metadata")
1
+ # encoding: UTF-8
2
2
 
3
- module GoodData
4
- class Fact < GoodData::MdObject
3
+ require_relative 'metadata'
5
4
 
5
+ module GoodData
6
+ class Fact < GoodData::MdObject
6
7
  root_key :fact
7
8
 
8
9
  class << self
9
10
  def [](id)
10
11
  if id == :all
11
12
  GoodData.get(GoodData.project.md['query'] + '/facts/')['query']['entries']
12
- else
13
+ else
13
14
  super
14
15
  end
15
16
  end
16
17
  end
17
-
18
18
  end
19
19
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module GoodData
2
4
  class Links
3
5
  attr_reader :data
@@ -8,7 +10,7 @@ module GoodData
8
10
  category = item['category']
9
11
  if @data[category] then
10
12
  if @data[category]['category'] == category then
11
- @data[category] = { @data[category]['identifier'] => @data[category] }
13
+ @data[category] = {@data[category]['identifier'] => @data[category]}
12
14
  end
13
15
  @data[category][item['identifier']] = item
14
16
  else
@@ -1,4 +1,6 @@
1
- require File.join(File.dirname(__FILE__), 'model')
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'model'
2
4
 
3
5
  module GoodData
4
6
  class MdObject
@@ -7,25 +9,25 @@ module GoodData
7
9
 
8
10
  class << self
9
11
  def root_key(a_key)
10
- define_method :root_key, Proc.new { a_key.to_s}
12
+ define_method :root_key, Proc.new { a_key.to_s }
11
13
  end
12
-
14
+
13
15
  def [](id)
14
16
  raise "Cannot search for nil #{self.class}" unless id
15
17
  uri = if id.is_a? Integer or id =~ /^\d+$/
16
- "#{GoodData.project.md[MD_OBJ_CTG]}/#{id}"
17
- elsif id !~ /\//
18
- identifier_to_uri id
19
- elsif id =~ /^\//
20
- id
21
- else
22
- raise "Unexpected object id format: expected numeric ID, identifier with no slashes or an URI starting with a slash"
23
- end
18
+ "#{GoodData.project.md[MD_OBJ_CTG]}/#{id}"
19
+ elsif id !~ /\//
20
+ identifier_to_uri id
21
+ elsif id =~ /^\//
22
+ id
23
+ else
24
+ raise 'Unexpected object id format: expected numeric ID, identifier with no slashes or an URI starting with a slash'
25
+ end
24
26
  self.new(GoodData.get uri) unless uri.nil?
25
27
  end
26
28
 
27
29
  def find_by_tag(tag)
28
- self[:all].find_all {|r| r["tags"].split(",").include?(tag)}
30
+ self[:all].find_all { |r| r['tags'].split(',').include?(tag) }
29
31
  end
30
32
 
31
33
  def get_by_id(id)
@@ -36,27 +38,26 @@ module GoodData
36
38
  def find_first_by_title(title)
37
39
  all = self[:all]
38
40
  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?
41
+ all.find { |r| r['title'] =~ title }
42
+ else
43
+ all.find { |r| r['title'] == title }
44
+ end
45
+ self[item['link']] unless item.nil?
44
46
  end
45
47
 
46
48
  def identifier_to_uri(*ids)
47
- raise NoProjectError.new "Connect to a project before searching for an object" unless GoodData.project
48
- uri = GoodData.project.md[IDENTIFIERS_CFG]
49
- response = GoodData.post uri, { 'identifierToUri' => ids }
49
+ raise NoProjectError.new 'Connect to a project before searching for an object' unless GoodData.project
50
+ uri = GoodData.project.md[IDENTIFIERS_CFG]
51
+ response = GoodData.post uri, {'identifierToUri' => ids}
50
52
  if response['identifiers'].empty?
51
53
  nil
52
54
  else
53
- ids = response['identifiers'].map {|x| x['uri']}
55
+ ids = response['identifiers'].map { |x| x['uri'] }
54
56
  ids.count == 1 ? ids.first : ids
55
57
  end
56
58
  end
57
59
 
58
60
  alias :id_to_uri :identifier_to_uri
59
-
60
61
  end
61
62
 
62
63
  def initialize(json)
@@ -66,7 +67,7 @@ module GoodData
66
67
  def delete
67
68
  if saved?
68
69
  GoodData.delete(uri)
69
- meta.delete("uri")
70
+ meta.delete('uri')
70
71
  # ["uri"] = nil
71
72
  end
72
73
  end
@@ -107,19 +108,19 @@ module GoodData
107
108
  end
108
109
 
109
110
  def title=(a_title)
110
- data["meta"]["title"] = a_title
111
+ data['meta']['title'] = a_title
111
112
  end
112
113
 
113
114
  def summary=(a_summary)
114
- data["meta"]["summary"] = a_summary
115
+ data['meta']['summary'] = a_summary
115
116
  end
116
117
 
117
118
  def tags
118
- data["meta"]["tags"]
119
+ data['meta']['tags']
119
120
  end
120
121
 
121
122
  def tags=(list_of_tags)
122
- data["meta"]["tags"] = list_of_tags
123
+ data['meta']['tags'] = list_of_tags
123
124
  end
124
125
 
125
126
  def meta
@@ -136,12 +137,12 @@ module GoodData
136
137
 
137
138
  def get_usedby
138
139
  result = GoodData.get "#{GoodData.project.md['usedby2']}/#{obj_id}"
139
- result["entries"]
140
+ result['entries']
140
141
  end
141
142
 
142
143
  def get_using
143
144
  result = GoodData.get "#{GoodData.project.md['using2']}/#{obj_id}"
144
- result["entries"]
145
+ result['entries']
145
146
  end
146
147
 
147
148
  def to_json
@@ -153,7 +154,8 @@ module GoodData
153
154
  end
154
155
 
155
156
  def data
156
- raw_data[root_key]
157
+ key = methods.include?(:root_key) ? root_key : raw_data.keys.first
158
+ raw_data[key]
157
159
  end
158
160
 
159
161
  def saved?
@@ -161,13 +163,13 @@ module GoodData
161
163
  end
162
164
 
163
165
  def save
164
- fail("Validation failed") unless validate
166
+ fail('Validation failed') unless validate
165
167
 
166
168
  if saved?
167
169
  GoodData.put(uri, to_json)
168
170
  else
169
171
  result = GoodData.post(GoodData.project.md['obj'], to_json)
170
- saved_object = self.class[result["uri"]]
172
+ saved_object = self.class[result['uri']]
171
173
  @json = saved_object.raw_data
172
174
  end
173
175
  self
@@ -1,17 +1,18 @@
1
- require File.join(File.dirname(__FILE__), "metadata")
2
- require File.join(File.dirname(__FILE__), '../goodzilla/goodzilla')
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'metadata'
4
+ require_relative '../goodzilla/goodzilla'
3
5
 
4
6
  module GoodData
5
7
  # Metric representation
6
8
  class Metric < GoodData::MdObject
7
-
8
9
  root_key :metric
9
10
 
10
11
  class << self
11
12
  def [](id)
12
13
  if id == :all
13
14
  GoodData.get(GoodData.project.md['query'] + '/metrics/')['query']['entries']
14
- else
15
+ else
15
16
  super
16
17
  end
17
18
  end
@@ -32,43 +33,43 @@ module GoodData
32
33
  else
33
34
  title = options[:title]
34
35
  summary = options[:summary]
35
- expression = options[:expression] || fail("Metric has to have its expression defined")
36
+ expression = options[:expression] || fail('Metric has to have its expression defined')
36
37
  extended_notation = options[:extended_notation] || false
37
38
  end
38
39
 
39
40
  expression = if extended_notation
40
- dict = {
41
- :facts => GoodData::Fact[:all].reduce({}) {|memo, item| memo[item["title"]] = item["link"]; memo},
42
- :attributes => GoodData::Attribute[:all].reduce({}) {|memo, item| memo[item["title"]] = item["link"]; memo},
43
- :metrics => GoodData::Metric[:all].reduce({}) {|memo, item| memo[item["title"]] = item["link"]; memo},
44
- }
45
- interpolated_metric = GoodData::SmallGoodZilla.interpolate_metric(expression, dict)
46
- interpolated_metric
47
- else
48
- expression
49
- end
41
+ dict = {
42
+ :facts => GoodData::Fact[:all].reduce({}) { |memo, item| memo[item['title']] = item['link']; memo },
43
+ :attributes => GoodData::Attribute[:all].reduce({}) { |memo, item| memo[item['title']] = item['link']; memo },
44
+ :metrics => GoodData::Metric[:all].reduce({}) { |memo, item| memo[item['title']] = item['link']; memo },
45
+ }
46
+ interpolated_metric = GoodData::SmallGoodZilla.interpolate_metric(expression, dict)
47
+ interpolated_metric
48
+ else
49
+ expression
50
+ end
50
51
 
51
52
  Metric.new({
52
- "metric" => {
53
- "content" => {
54
- "format" => "#,##0",
55
- "expression" => expression
56
- },
57
- "meta" => {
58
- "tags" => "",
59
- "summary" => summary,
60
- "title" => title,
61
- }
62
- }
63
- })
53
+ 'metric' => {
54
+ 'content' => {
55
+ 'format' => '#,##0',
56
+ 'expression' => expression
57
+ },
58
+ 'meta' => {
59
+ 'tags' => '',
60
+ 'summary' => summary,
61
+ 'title' => title,
62
+ }
63
+ }
64
+ })
64
65
  end
65
66
 
66
67
  def execute(expression, options={})
67
68
  m = if expression.is_a?(String)
68
- GoodData::Metric.create({:title => "Temporary metric to be deleted", :expression => expression}.merge(options))
69
- else
70
- GoodData::Metric.create({:title => "Temporary metric to be deleted"}.merge(expression))
71
- end
69
+ GoodData::Metric.create({:title => 'Temporary metric to be deleted', :expression => expression}.merge(options))
70
+ else
71
+ GoodData::Metric.create({:title => 'Temporary metric to be deleted'}.merge(expression))
72
+ end
72
73
  m.execute
73
74
  end
74
75
 
@@ -79,7 +80,6 @@ module GoodData
79
80
  execute(expression.merge({:extended_notation => true}))
80
81
  end
81
82
  end
82
-
83
83
  end
84
84
 
85
85
  def execute
@@ -88,13 +88,12 @@ module GoodData
88
88
  end
89
89
 
90
90
  def validate
91
- fail "Meric needs to have title" if title.nil?
91
+ fail 'Meric needs to have title' if title.nil?
92
92
  true
93
93
  end
94
94
 
95
95
  def is_metric?
96
96
  true
97
97
  end
98
-
99
98
  end
100
99
  end
@@ -1,13 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative '../helpers'
4
+
1
5
  require 'open-uri'
2
6
  require 'active_support/all'
7
+
3
8
  ##
4
9
  # Module containing classes that counter-part GoodData server-side meta-data
5
10
  # elements, including the server-side data model.
6
11
  #
7
12
  module GoodData
8
-
9
13
  module Model
10
-
11
14
  # GoodData REST API categories
12
15
  LDM_CTG = 'ldm'
13
16
  LDM_MANAGE_CTG = 'ldm-manage'
@@ -24,7 +27,7 @@ module GoodData
24
27
  LABEL_PREFIX = 'label'
25
28
  FACT_PREFIX = 'fact'
26
29
  DATE_FACT_PREFIX = 'dt'
27
- DATE_ATTRIBUTE = "date"
30
+ DATE_ATTRIBUTE = 'date'
28
31
  DATE_ATTRIBUTE_DEFAULT_DISPLAY_FORM = 'mdyy'
29
32
  TIME_FACT_PREFIX = 'tm.dt'
30
33
  TIME_ATTRIBUTE_PREFIX = 'attr.time'
@@ -83,13 +86,13 @@ module GoodData
83
86
  pull = {'pullIntegration' => File.basename(dir)}
84
87
  link = project.md.links('etl')['pull']
85
88
  task = GoodData.post link, pull
86
- while (GoodData.get(task["pullTask"]["uri"])["taskStatus"] === "RUNNING" || GoodData.get(task["pullTask"]["uri"])["taskStatus"] === "PREPARED") do
89
+ while GoodData.get(task['pullTask']['uri'])['taskStatus'] === 'RUNNING' || GoodData.get(task['pullTask']['uri'])['taskStatus'] === 'PREPARED'
87
90
  sleep 30
88
91
  end
89
- if (GoodData.get(task["pullTask"]["uri"])["taskStatus"] == "ERROR")
92
+ if GoodData.get(task['pullTask']['uri'])['taskStatus'] == 'ERROR'
90
93
  s = StringIO.new
91
94
  GoodData.download_from_user_webdav(File.basename(dir) + '/upload_status.json', s)
92
- js = JSON.parse(s.string)
95
+ js = MultiJson.load(s.string)
93
96
  fail "Load Failed with error #{JSON.pretty_generate(js)}"
94
97
  end
95
98
  end
@@ -100,20 +103,18 @@ module GoodData
100
103
  d = Marshal.load(Marshal.dump(a_schema_blueprint))
101
104
  d[:columns] = d[:columns] + b_schema_blueprint[:columns]
102
105
  d[:columns].uniq!
103
- columns_that_failed_to_merge = d[:columns].group_by {|x| x[:name]}.map {|k, v| [k, v.count]}.find_all {|x| x[1] > 1}
106
+ columns_that_failed_to_merge = d[:columns].group_by { |x| x[:name] }.map { |k, v| [k, v.count] }.find_all { |x| x[1] > 1 }
104
107
  fail "Columns #{columns_that_failed_to_merge} failed to merge. When merging columns with the same name they have to be identical." unless columns_that_failed_to_merge.empty?
105
108
  d
106
109
  end
107
-
108
110
  end
109
111
 
110
112
  class ProjectBlueprint
111
-
112
113
  attr_accessor :data
113
114
 
114
115
  def self.from_json(spec)
115
116
  if spec.is_a?(String)
116
- ProjectBlueprint.new(JSON.parse(File.read(spec), :symbolize_names => true))
117
+ ProjectBlueprint.new(MultiJson.load(File.read(spec), :symbolize_keys => true))
117
118
  else
118
119
  ProjectBlueprint.new(spec)
119
120
  end
@@ -140,7 +141,7 @@ module GoodData
140
141
  end
141
142
 
142
143
  def remove_dataset(dataset_name)
143
- x = data[:datasets].find {|d| d[:name] == dataset_name}
144
+ x = data[:datasets].find { |d| d[:name] == dataset_name }
144
145
  index = data[:datasets].index(x)
145
146
  data[:datasets].delete_at(index)
146
147
  end
@@ -205,28 +206,26 @@ module GoodData
205
206
 
206
207
  def to_wire_model
207
208
  {
208
- "diffRequest" => {
209
- "targetModel" => {
210
- "projectModel" => {
211
- "datasets" => datasets.map {|d| d.to_wire_model},
212
- "dateDimensions" => date_dimensions.map {|d|
213
- {
214
- "dateDimension" => {
215
- "name" => d[:name],
216
- "title" => d[:title] || d[:name].humanize
217
- }
218
- }}
219
- }}}}
209
+ 'diffRequest' => {
210
+ 'targetModel' => {
211
+ 'projectModel' => {
212
+ 'datasets' => datasets.map { |d| d.to_wire_model },
213
+ 'dateDimensions' => date_dimensions.map { |d|
214
+ {
215
+ 'dateDimension' => {
216
+ 'name' => d[:name],
217
+ 'title' => d[:title] || d[:name].humanize
218
+ }
219
+ } }
220
+ }}}}
220
221
  end
221
222
 
222
223
  def to_hash
223
224
  @data
224
225
  end
225
-
226
226
  end
227
227
 
228
228
  class SchemaBlueprint
229
-
230
229
  attr_accessor :data
231
230
 
232
231
  def change(&block)
@@ -243,8 +242,8 @@ module GoodData
243
242
 
244
243
  def upload(source, options={})
245
244
  project = options[:project] || GoodData.project
246
- fail "You have to specify a project into which you want to load." if project.nil?
247
- mode = options[:load] || "FULL"
245
+ fail 'You have to specify a project into which you want to load.' if project.nil?
246
+ mode = options[:load] || 'FULL'
248
247
  project.upload(source, to_schema, mode)
249
248
  end
250
249
 
@@ -271,7 +270,7 @@ module GoodData
271
270
  end
272
271
 
273
272
  def has_anchor?
274
- columns.any? { |c| c[:type].to_s == "anchor" }
273
+ columns.any? { |c| c[:type].to_s == 'anchor' }
275
274
  end
276
275
 
277
276
  def anchor
@@ -335,17 +334,14 @@ module GoodData
335
334
  def ==(other)
336
335
  to_hash == other.to_hash
337
336
  end
338
-
339
337
  end
340
338
 
341
339
  class ProjectBuilder
342
-
343
340
  attr_reader :title, :datasets, :reports, :metrics, :uploads, :users, :assert_report, :date_dimensions
344
341
 
345
342
  class << self
346
-
347
- def create_from_data(blueprint)
348
- pb = ProjectBuilder.new
343
+ def create_from_data(blueprint, title = 'Title')
344
+ pb = ProjectBuilder.new(title)
349
345
  pb.data = blueprint.to_hash
350
346
  pb
351
347
  end
@@ -355,7 +351,6 @@ module GoodData
355
351
  block.call(pb)
356
352
  pb
357
353
  end
358
-
359
354
  end
360
355
 
361
356
  def initialize(title)
@@ -370,8 +365,14 @@ module GoodData
370
365
  @date_dimensions = []
371
366
  end
372
367
 
373
- def add_date_dimension(name, options={})
374
- @date_dimensions << {:urn => options[:urn], :name => name, :title => options[:title]}
368
+ def add_date_dimension(name, options = {})
369
+ dimension = {
370
+ urn: options[:urn],
371
+ name: name,
372
+ title: options[:title]
373
+ }
374
+
375
+ @date_dimensions << dimension
375
376
  end
376
377
 
377
378
  def add_dataset(name, &block)
@@ -403,12 +404,12 @@ module GoodData
403
404
  end
404
405
 
405
406
  def load_metrics(file)
406
- new_metrics = JSON.parse(open(file).read, :symbolize_names => true)
407
+ new_metrics = MultiJson.load(open(file).read, :symbolize_keys => true)
407
408
  @metrics = @metrics + new_metrics
408
409
  end
409
410
 
410
411
  def load_datasets(file)
411
- new_metrics = JSON.parse(open(file).read, :symbolize_names => true)
412
+ new_metrics = MultiJson.load(open(file).read, :symbolize_keys => true)
412
413
  @datasets = @datasets + new_metrics
413
414
  end
414
415
 
@@ -417,12 +418,12 @@ module GoodData
417
418
  end
418
419
 
419
420
  def upload(data, options={})
420
- mode = options[:mode] || "FULL"
421
+ mode = options[:mode] || 'FULL'
421
422
  dataset = options[:dataset]
422
423
  @uploads << {
423
- :source => data,
424
- :mode => mode,
425
- :dataset => dataset
424
+ :source => data,
425
+ :mode => mode,
426
+ :dataset => dataset
426
427
  }
427
428
  end
428
429
 
@@ -442,26 +443,24 @@ module GoodData
442
443
 
443
444
  def to_hash
444
445
  {
445
- :title => @title,
446
- :datasets => @datasets,
447
- :uploads => @uploads,
448
- :dashboards => @dashboards,
449
- :metrics => @metrics,
450
- :reports => @reports,
451
- :users => @users,
452
- :assert_tests => @assert_tests,
453
- :date_dimensions => @date_dimensions
446
+ :title => @title,
447
+ :datasets => @datasets,
448
+ :uploads => @uploads,
449
+ :dashboards => @dashboards,
450
+ :metrics => @metrics,
451
+ :reports => @reports,
452
+ :users => @users,
453
+ :assert_tests => @assert_tests,
454
+ :date_dimensions => @date_dimensions
454
455
  }
455
456
  end
456
457
 
457
458
  def get_dataset(name)
458
459
  datasets.find { |d| d.name == name }
459
460
  end
460
-
461
461
  end
462
462
 
463
463
  class DashboardBuilder
464
-
465
464
  def initialize(title)
466
465
  @title = title
467
466
  @tabs = []
@@ -476,14 +475,13 @@ module GoodData
476
475
 
477
476
  def to_hash
478
477
  {
479
- :name => @name,
480
- :tabs => @tabs.map { |tab| tab.to_hash }
478
+ :name => @name,
479
+ :tabs => @tabs.map { |tab| tab.to_hash }
481
480
  }
482
481
  end
483
482
  end
484
483
 
485
484
  class TabBuilder
486
-
487
485
  def initialize(title)
488
486
  @title = title
489
487
  @stuff = []
@@ -495,31 +493,27 @@ module GoodData
495
493
 
496
494
  def to_hash
497
495
  {
498
- :title => @title,
499
- :items => @stuff
496
+ :title => @title,
497
+ :items => @stuff
500
498
  }
501
499
  end
502
-
503
500
  end
504
501
 
505
502
  class SchemaBuilder
506
-
507
503
  attr_accessor :data
508
504
 
509
505
  class << self
510
-
511
506
  def create_from_data(blueprint)
512
507
  sc = SchemaBuilder.new
513
508
  sc.data = blueprint.to_hash
514
509
  sc
515
510
  end
516
-
517
511
  end
518
512
 
519
513
  def initialize(name=nil)
520
514
  @data = {
521
- :name => name,
522
- :columns => []
515
+ :name => name,
516
+ :columns => []
523
517
  }
524
518
  end
525
519
 
@@ -575,20 +569,17 @@ module GoodData
575
569
  def to_schema
576
570
  Schema.new(to_hash)
577
571
  end
578
-
579
572
  end
580
573
 
581
574
  class ProjectCreator
582
-
583
575
  class << self
584
576
  def migrate(options={})
585
-
586
- spec = options[:spec] || fail("You need to provide spec for migration")
577
+ spec = options[:spec] || fail('You need to provide spec for migration')
587
578
  spec = spec.to_hash
588
579
 
589
580
  token = options[:token]
590
581
  project = options[:project] || GoodData::Project.create(:title => spec[:title], :auth_token => token)
591
- fail("You need to specify token for project creation") if token.nil? && project.nil?
582
+ fail('You need to specify token for project creation') if token.nil? && project.nil?
592
583
 
593
584
  begin
594
585
  GoodData.with_project(project) do |p|
@@ -615,8 +606,9 @@ module GoodData
615
606
  bp = ProjectBlueprint.new(spec)
616
607
  # schema = Schema.load(schema) unless schema.respond_to?(:to_maql_create)
617
608
  # project = GoodData.project unless project
618
- result = GoodData.post("/gdc/projects/#{GoodData.project.pid}/model/diff", bp.to_wire_model)
619
- link = result["asyncTask"]["link"]["poll"]
609
+ uri = "/gdc/projects/#{GoodData.project.pid}/model/diff"
610
+ result = GoodData.post(uri, bp.to_wire_model)
611
+ link = result['asyncTask']['link']['poll']
620
612
  response = GoodData.get(link, :process => false)
621
613
  # pp response
622
614
  while response.code != 200
@@ -630,9 +622,9 @@ module GoodData
630
622
  response = GoodData.get(link)
631
623
  ldm_links = GoodData.get project.md[LDM_CTG]
632
624
  ldm_uri = Links.new(ldm_links)[LDM_MANAGE_CTG]
633
- chunks = response["projectModelDiff"]["updateScripts"].find_all {|script| script["updateScript"]["preserveData"] == true && script["updateScript"]["cascadeDrops"] == false}.map {|x| x["updateScript"]["maqlDdlChunks"]}.flatten
625
+ chunks = response['projectModelDiff']['updateScripts'].find_all { |script| script['updateScript']['preserveData'] == true && script['updateScript']['cascadeDrops'] == false }.map { |x| x['updateScript']['maqlDdlChunks'] }.flatten
634
626
  chunks.each do |chunk|
635
- GoodData.post ldm_uri, { 'manage' => { 'maql' => chunk } }
627
+ GoodData.post ldm_uri, {'manage' => {'maql' => chunk}}
636
628
  end
637
629
 
638
630
  bp.datasets.each do |ds|
@@ -669,7 +661,7 @@ module GoodData
669
661
  def load(project, spec)
670
662
  if spec.has_key?(:uploads)
671
663
  spec[:uploads].each do |load|
672
- schema = GoodData::Model::Schema.new(spec[:datasets].detect {|d| d[:name] == load[:dataset]})
664
+ schema = GoodData::Model::Schema.new(spec[:datasets].detect { |d| d[:name] == load[:dataset] })
673
665
  project.upload(load[:source], schema, load[:mode])
674
666
  end
675
667
  end
@@ -716,20 +708,23 @@ module GoodData
716
708
  Schema.new JSON.load(open(file))
717
709
  end
718
710
 
719
- def initialize(config, name = nil)
711
+ def initialize(config, name = 'Default Name', title = 'Default Title')
720
712
  super()
721
713
  @fields = []
722
714
  @attributes = []
723
715
  @facts = []
724
716
  @folders = {
725
- :facts => {},
726
- :attributes => {}
717
+ :facts => {},
718
+ :attributes => {}
727
719
  }
728
720
  @references = []
729
721
  @labels = []
730
722
 
731
723
  config[:name] = name unless config[:name]
732
- config[:title] = config[:title] || config[:name].humanize
724
+ config[:title] = config[:name] unless config[:title]
725
+ config[:title] = title unless config[:title]
726
+ config[:title] = config[:title].humanize
727
+
733
728
  fail 'Schema name not specified' unless config[:name]
734
729
  self.name = config[:name]
735
730
  self.title = config[:title]
@@ -739,17 +734,17 @@ module GoodData
739
734
  def config=(config)
740
735
  config[:columns].each do |c|
741
736
  case c[:type].to_s
742
- when "attribute"
737
+ when 'attribute'
743
738
  add_attribute c
744
- when "fact"
739
+ when 'fact'
745
740
  add_fact c
746
- when "date"
741
+ when 'date'
747
742
  add_date c
748
- when "anchor"
743
+ when 'anchor'
749
744
  set_anchor c
750
- when "label"
745
+ when 'label'
751
746
  add_label c
752
- when "reference"
747
+ when 'reference'
753
748
  add_reference c
754
749
  else
755
750
  fail "Unexpected type #{c[:type]} in #{c.inspect}"
@@ -773,7 +768,7 @@ module GoodData
773
768
  # Generates MAQL DDL script to drop this data set and included pieces
774
769
  #
775
770
  def to_maql_drop
776
- maql = ""
771
+ maql = ''
777
772
  [attributes, facts].each do |obj|
778
773
  maql += obj.to_maql_drop
779
774
  end
@@ -784,9 +779,10 @@ module GoodData
784
779
  # Generates MAQL DDL script to create this data set and included pieces
785
780
  #
786
781
  def to_maql_create
782
+ # TODO: Use template (.erb)
787
783
  maql = "# Create the '#{self.title}' data set\n"
788
784
  maql += "CREATE DATASET {#{self.identifier}} VISUAL (TITLE \"#{self.title}\");\n\n"
789
- [ attributes, facts, { 1 => @anchor } ].each do |objects|
785
+ [attributes, facts, {1 => @anchor}].each do |objects|
790
786
  objects.values.each do |obj|
791
787
  maql += "# Create '#{obj.title}' and add it to the '#{self.title}' data set.\n"
792
788
  maql += obj.to_maql_create
@@ -809,7 +805,7 @@ module GoodData
809
805
  folders_maql + "\n" + maql + "SYNCHRONIZE {#{identifier}};\n"
810
806
  end
811
807
 
812
- def upload(path, project = nil, mode = "FULL")
808
+ def upload(path, project = nil, mode = 'FULL')
813
809
  if path =~ URI::regexp
814
810
  Tempfile.open('remote_file') do |temp|
815
811
  temp << open(path).read
@@ -827,31 +823,32 @@ module GoodData
827
823
 
828
824
  # Generates the SLI manifest describing the data loading
829
825
  #
830
- def to_manifest(mode="FULL")
826
+ def to_manifest(mode = 'FULL')
831
827
  {
832
- 'dataSetSLIManifest' => {
833
- 'parts' => fields.reduce([]) { |memo, f| val = f.to_manifest_part(mode); memo << val unless val.nil?; memo },
834
- 'dataSet' => self.identifier,
835
- 'file' => 'data.csv', # should be configurable
836
- 'csvParams' => {
837
- 'quoteChar' => '"',
838
- 'escapeChar' => '"',
839
- 'separatorChar' => ',',
840
- 'endOfLine' => "\n"
841
- }
828
+ 'dataSetSLIManifest' => {
829
+ 'parts' => fields.reduce([]) { |memo, f| val = f.to_manifest_part(mode); memo << val unless val.nil?; memo },
830
+ 'dataSet' => self.identifier,
831
+ 'file' => 'data.csv', # should be configurable
832
+ 'csvParams' => {
833
+ 'quoteChar' => '"',
834
+ 'escapeChar' => '"',
835
+ 'separatorChar' => ',',
836
+ 'endOfLine' => "\n"
842
837
  }
838
+ }
843
839
  }
844
840
  end
845
841
 
846
842
  def to_wire_model
847
843
  {
848
- "dataset" => {
849
- "identifier" => identifier,
850
- "title" => title,
851
- "anchor" => @anchor.to_wire_model,
852
- "facts" => facts.map {|f| f.to_wire_model},
853
- "attributes" => attributes.map {|a| a.to_wire_model},
854
- "references" => references.map {|r| r.is_a?(DateReference) ? r.schema_ref : type_prefix + "." + r.schema_ref }}}
844
+ 'dataset' => {
845
+ 'identifier' => identifier,
846
+ 'title' => title,
847
+ 'anchor' => @anchor.to_wire_model,
848
+ 'facts' => facts.map { |f| f.to_wire_model },
849
+ 'attributes' => attributes.map { |a| a.to_wire_model },
850
+ 'references' => references.map { |r| r.is_a?(DateReference) ? r.schema_ref : type_prefix + '.' + r.schema_ref }}
851
+ }
855
852
  end
856
853
 
857
854
  private
@@ -902,14 +899,13 @@ module GoodData
902
899
  date.parts.values.each { |p| @fields << p }
903
900
  date.facts.each { |f| facts << f }
904
901
  date.attributes.each { |a| attributes << a }
905
- date.references.each {|r| references << r}
902
+ date.references.each { |r| references << r }
906
903
  end
907
904
 
908
905
  def set_anchor(column)
909
906
  @anchor = Anchor.new column, self
910
907
  @fields << @anchor
911
908
  end
912
-
913
909
  end
914
910
 
915
911
  ##
@@ -922,7 +918,9 @@ module GoodData
922
918
  def initialize(hash, schema)
923
919
  super()
924
920
  raise ArgumentError.new("Schema must be provided, got #{schema.class}") unless schema.is_a? Schema
925
- @name = hash[:name] || raise("Data set fields must have their names defined")
921
+ raise('Data set fields must have their names defined') if hash[:name].nil?
922
+
923
+ @name = hash[:name]
926
924
  @title = hash[:title] || hash[:name].humanize
927
925
  @folder = hash[:folder]
928
926
  @schema = schema
@@ -985,7 +983,7 @@ module GoodData
985
983
  end
986
984
 
987
985
  def table
988
- @table ||= "d_" + @schema.name + "_" + name
986
+ @table ||= 'd_' + @schema.name + '_' + name
989
987
  end
990
988
 
991
989
  def key;
@@ -1001,31 +999,30 @@ module GoodData
1001
999
 
1002
1000
  def to_manifest_part(mode)
1003
1001
  {
1004
- 'referenceKey' => 1,
1005
- 'populates' => [@primary_label.identifier],
1006
- 'mode' => mode,
1007
- 'columnName' => name
1002
+ 'referenceKey' => 1,
1003
+ 'populates' => [@primary_label.identifier],
1004
+ 'mode' => mode,
1005
+ 'columnName' => name
1008
1006
  }
1009
1007
  end
1010
1008
 
1011
1009
  def to_wire_model
1012
1010
  {
1013
- "attribute" => {
1014
- "identifier" => identifier,
1015
- "title" => title,
1016
- "labels" => labels.map do |l|
1017
- {
1018
- "label" => {
1019
- "identifier" => l.identifier,
1020
- "title" => l.title,
1021
- "type" => "GDC.text"
1022
- }
1023
- }
1024
- end
1025
- }
1011
+ 'attribute' => {
1012
+ 'identifier' => identifier,
1013
+ 'title' => title,
1014
+ 'labels' => labels.map do |l|
1015
+ {
1016
+ 'label' => {
1017
+ 'identifier' => l.identifier,
1018
+ 'title' => l.title,
1019
+ 'type' => 'GDC.text'
1020
+ }
1021
+ }
1022
+ end
1023
+ }
1026
1024
  }
1027
1025
  end
1028
-
1029
1026
  end
1030
1027
 
1031
1028
  ##
@@ -1034,30 +1031,31 @@ module GoodData
1034
1031
  # field
1035
1032
  #
1036
1033
  class Label < Column
1037
-
1038
1034
  attr_accessor :attribute
1039
1035
 
1040
- def type_prefix ; 'label' ; end
1036
+ def type_prefix;
1037
+ 'label';
1038
+ end
1041
1039
 
1042
1040
  # def initialize(hash, schema)
1043
1041
  def initialize(hash, attribute, schema)
1044
1042
  super hash, schema
1045
- attribute = attribute.nil? ? schema.fields.find {|field| field.name === hash[:reference]} : attribute
1043
+ attribute = attribute.nil? ? schema.fields.find { |field| field.name === hash[:reference] } : attribute
1046
1044
  @attribute = attribute
1047
1045
  attribute.labels << self
1048
1046
  end
1049
1047
 
1050
1048
  def to_maql_create
1051
- "# LABEL FROM LABEL"
1049
+ '# LABEL FROM LABEL'
1052
1050
  "ALTER ATTRIBUTE {#{@attribute.identifier}} ADD LABELS {#{identifier}}" \
1053
1051
  + " VISUAL (TITLE #{title.inspect}) AS {#{column}};\n"
1054
1052
  end
1055
1053
 
1056
1054
  def to_manifest_part(mode)
1057
1055
  {
1058
- 'populates' => [identifier],
1059
- 'mode' => mode,
1060
- 'columnName' => name
1056
+ 'populates' => [identifier],
1057
+ 'mode' => mode,
1058
+ 'columnName' => name
1061
1059
  }
1062
1060
  end
1063
1061
 
@@ -1068,7 +1066,7 @@ module GoodData
1068
1066
  alias :inspect_orig :inspect
1069
1067
 
1070
1068
  def inspect
1071
- inspect_orig.sub(/>$/, " @attribute=" + @attribute.to_s.sub(/>$/, " @name=#{@attribute.name}") + '>')
1069
+ inspect_orig.sub(/>$/, " @attribute=#{@attribute.to_s.sub(/>$/, " @name=#{@attribute.name}")}>")
1072
1070
  end
1073
1071
  end
1074
1072
 
@@ -1081,14 +1079,14 @@ module GoodData
1081
1079
  if column then
1082
1080
  super
1083
1081
  else
1084
- super({:type => "anchor", :name => 'id'}, schema)
1082
+ super({:type => 'anchor', :name => 'id'}, schema)
1085
1083
  @labels = []
1086
1084
  @primary_label = nil
1087
1085
  end
1088
1086
  end
1089
1087
 
1090
1088
  def table
1091
- @table ||= "f_" + @schema.name
1089
+ @table ||= 'f_' + @schema.name
1092
1090
  end
1093
1091
 
1094
1092
  def to_maql_create
@@ -1100,7 +1098,6 @@ module GoodData
1100
1098
  end
1101
1099
  maql
1102
1100
  end
1103
-
1104
1101
  end
1105
1102
 
1106
1103
  ##
@@ -1134,17 +1131,17 @@ module GoodData
1134
1131
 
1135
1132
  def to_manifest_part(mode)
1136
1133
  {
1137
- 'populates' => [identifier],
1138
- 'mode' => mode,
1139
- 'columnName' => name
1134
+ 'populates' => [identifier],
1135
+ 'mode' => mode,
1136
+ 'columnName' => name
1140
1137
  }
1141
1138
  end
1142
1139
 
1143
1140
  def to_wire_model
1144
1141
  {
1145
- "fact" => {
1146
- "identifier" => identifier,
1147
- "title" => title
1142
+ 'fact' => {
1143
+ 'identifier' => identifier,
1144
+ 'title' => title
1148
1145
  }
1149
1146
  }
1150
1147
  end
@@ -1154,7 +1151,6 @@ module GoodData
1154
1151
  # Reference to another data set
1155
1152
  #
1156
1153
  class Reference < Column
1157
-
1158
1154
  attr_accessor :reference, :schema_ref
1159
1155
 
1160
1156
  def initialize(column, schema)
@@ -1193,10 +1189,10 @@ module GoodData
1193
1189
 
1194
1190
  def to_manifest_part(mode)
1195
1191
  {
1196
- 'populates' => [label_column],
1197
- 'mode' => mode,
1198
- 'columnName' => name,
1199
- 'referenceKey' => 1
1192
+ 'populates' => [label_column],
1193
+ 'mode' => mode,
1194
+ 'columnName' => name,
1195
+ 'referenceKey' => 1
1200
1196
  }
1201
1197
  end
1202
1198
  end
@@ -1205,14 +1201,13 @@ module GoodData
1205
1201
  # Date as a reference to a date dimension
1206
1202
  #
1207
1203
  class DateReference < Reference
1208
-
1209
1204
  attr_accessor :format, :output_format, :urn
1210
1205
 
1211
1206
  def initialize(column, schema)
1212
1207
  super column, schema
1213
- @output_format = column["format"] || 'dd/MM/yyyy'
1208
+ @output_format = column['format'] || 'dd/MM/yyyy'
1214
1209
  @format = @output_format.gsub('yyyy', '%Y').gsub('MM', '%m').gsub('dd', '%d')
1215
- @urn = column[:urn] || "URN:GOODDATA:DATE"
1210
+ @urn = column[:urn] || 'URN:GOODDATA:DATE'
1216
1211
  end
1217
1212
 
1218
1213
  def identifier
@@ -1221,11 +1216,11 @@ module GoodData
1221
1216
 
1222
1217
  def to_manifest_part(mode)
1223
1218
  {
1224
- 'populates' => ["#{identifier}.#{DATE_ATTRIBUTE_DEFAULT_DISPLAY_FORM}"],
1225
- 'mode' => mode,
1226
- 'constraints' => {"date" => output_format},
1227
- 'columnName' => name,
1228
- 'referenceKey' => 1
1219
+ 'populates' => ["#{identifier}.#{DATE_ATTRIBUTE_DEFAULT_DISPLAY_FORM}"],
1220
+ 'mode' => mode,
1221
+ 'constraints' => {'date' => output_format},
1222
+ 'columnName' => name,
1223
+ 'referenceKey' => 1
1229
1224
  }
1230
1225
  end
1231
1226
 
@@ -1249,10 +1244,10 @@ module GoodData
1249
1244
 
1250
1245
  def to_manifest_part(mode)
1251
1246
  {
1252
- 'populates' => ['label.stuff.mmddyy'],
1253
- "format" => "unknown",
1254
- "mode" => mode,
1255
- "referenceKey" => 1
1247
+ 'populates' => ['label.stuff.mmddyy'],
1248
+ 'format' => 'unknown',
1249
+ 'mode' => mode,
1250
+ 'referenceKey' => 1
1256
1251
  }
1257
1252
  end
1258
1253
  end
@@ -1274,7 +1269,6 @@ module GoodData
1274
1269
  # Time as a reference to a time-of-a-day dimension
1275
1270
  #
1276
1271
  class TimeReference < Reference
1277
-
1278
1272
  end
1279
1273
 
1280
1274
  ##
@@ -1343,7 +1337,6 @@ module GoodData
1343
1337
  def to_manifest_part(mode)
1344
1338
  nil
1345
1339
  end
1346
-
1347
1340
  end
1348
1341
 
1349
1342
  ##
@@ -1351,8 +1344,10 @@ module GoodData
1351
1344
  #
1352
1345
  class Folder < MdObject
1353
1346
  def initialize(title)
1347
+ # TODO: should a super be here?
1348
+ # how to deal with name vs title?
1354
1349
  @title = title
1355
- @name = title
1350
+ @name = GoodData::Helpers.sanitize_string(title)
1356
1351
  end
1357
1352
 
1358
1353
  def to_maql_create
@@ -1366,11 +1361,11 @@ module GoodData
1366
1361
  #
1367
1362
  class AttributeFolder < Folder
1368
1363
  def type;
1369
- "ATTRIBUTE";
1364
+ 'ATTRIBUTE'
1370
1365
  end
1371
1366
 
1372
1367
  def type_prefix;
1373
- "dim";
1368
+ 'dim'
1374
1369
  end
1375
1370
  end
1376
1371
 
@@ -1379,21 +1374,20 @@ module GoodData
1379
1374
  #
1380
1375
  class FactFolder < Folder
1381
1376
  def type;
1382
- "FACT";
1377
+ 'FACT'
1383
1378
  end
1384
1379
 
1385
1380
  def type_prefix;
1386
- "ffld";
1381
+ 'ffld'
1387
1382
  end
1388
1383
  end
1389
1384
 
1390
1385
  class DateDimension < MdObject
1391
-
1392
1386
  def initialize(spec={})
1393
1387
  super()
1394
1388
  @name = spec[:name]
1395
1389
  @title = spec[:title] || @name
1396
- @urn = spec[:urn] || "URN:GOODDATA:DATE"
1390
+ @urn = spec[:urn] || 'URN:GOODDATA:DATE'
1397
1391
  end
1398
1392
 
1399
1393
  def to_maql_create
@@ -1401,12 +1395,10 @@ module GoodData
1401
1395
  # title = "title"
1402
1396
  # name = "name"
1403
1397
 
1404
- maql = ""
1398
+ maql = ''
1405
1399
  maql += "INCLUDE TEMPLATE \"#{@urn}\" MODIFY (IDENTIFIER \"#{@name}\", TITLE \"#{@title}\");"
1406
1400
  maql
1407
1401
  end
1408
-
1409
1402
  end
1410
-
1411
1403
  end
1412
1404
  end