gooddata 0.5.16 → 0.6.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/Gemfile +2 -0
  2. data/bin/gooddata +291 -8
  3. data/gooddata.gemspec +14 -5
  4. data/lib/gooddata/client.rb +34 -5
  5. data/lib/gooddata/commands/api.rb +27 -30
  6. data/lib/gooddata/commands/process.rb +137 -0
  7. data/lib/gooddata/commands/profile.rb +5 -5
  8. data/lib/gooddata/commands/projects.rb +107 -40
  9. data/lib/gooddata/commands/runners.rb +37 -0
  10. data/lib/gooddata/commands/scaffold.rb +30 -0
  11. data/lib/gooddata/connection.rb +31 -19
  12. data/lib/gooddata/extract.rb +1 -1
  13. data/lib/gooddata/goodzilla/goodzilla.rb +40 -0
  14. data/lib/gooddata/model.rb +418 -138
  15. data/lib/gooddata/models/attribute.rb +24 -0
  16. data/lib/gooddata/models/dashboard.rb +60 -0
  17. data/lib/gooddata/models/data_result.rb +4 -6
  18. data/lib/gooddata/models/data_set.rb +20 -0
  19. data/lib/gooddata/models/display_form.rb +7 -0
  20. data/lib/gooddata/models/fact.rb +17 -0
  21. data/lib/gooddata/models/metadata.rb +69 -17
  22. data/lib/gooddata/models/metric.rb +90 -0
  23. data/lib/gooddata/models/process.rb +112 -0
  24. data/lib/gooddata/models/profile.rb +1 -1
  25. data/lib/gooddata/models/project.rb +85 -29
  26. data/lib/gooddata/models/report.rb +45 -0
  27. data/lib/gooddata/models/report_definition.rb +139 -0
  28. data/lib/gooddata/version.rb +1 -1
  29. data/lib/templates/bricks/brick.rb.erb +7 -0
  30. data/lib/templates/bricks/main.rb.erb +4 -0
  31. data/spec/goodzilla_spec.rb +57 -0
  32. data/spec/model_dsl_spec.rb +22 -0
  33. data/test/test_commands.rb +1 -1
  34. data/test/test_model.rb +6 -6
  35. metadata +137 -16
  36. data/bin/igd.rb +0 -33
  37. data/lib/gooddata/command.rb +0 -75
  38. data/lib/gooddata/commands/help.rb +0 -104
  39. data/lib/gooddata/commands/version.rb +0 -7
  40. data/test/helper.rb +0 -13
@@ -10,4 +10,4 @@ module GoodData::Extract
10
10
  CSV.open @file, 'r', &block
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -0,0 +1,40 @@
1
+ module GoodData::SmallGoodZilla
2
+
3
+ def self.get_facts(a_maql_string)
4
+ a_maql_string.scan(/#\"([^\"]+)\"/).flatten
5
+ end
6
+
7
+ def self.get_attributes(a_maql_string)
8
+ a_maql_string.scan(/@\"([^\"]+)\"/).flatten
9
+ end
10
+
11
+ def self.get_metrics(a_maql_string)
12
+ a_maql_string.scan(/\?"([^\"]+)\"/).flatten
13
+ end
14
+
15
+ def self.interpolate(values, dictionaries)
16
+ {
17
+ :facts => interpolate_values(values[:facts], dictionaries[:facts]),
18
+ :attributes => interpolate_values(values[:attributes], dictionaries[:attributes]),
19
+ :metrics => interpolate_values(values[:metrics], dictionaries[:metrics])
20
+ }
21
+ end
22
+
23
+ def self.interpolate_values(keys, values)
24
+ x = values.values_at(*keys)
25
+ keys.zip(x)
26
+ end
27
+
28
+ def self.interpolate_metric(metric, dictionary)
29
+ interpolated = interpolate({
30
+ :facts => GoodData::SmallGoodZilla.get_facts(metric),
31
+ :attributes => GoodData::SmallGoodZilla.get_attributes(metric),
32
+ :metrics => GoodData::SmallGoodZilla.get_metrics(metric)
33
+ }, dictionary)
34
+ metric = interpolated[:facts].reduce(metric) {|memo, item| memo.sub("#\"#{item[0]}\"", "[#{item[1]}]")}
35
+ metric = interpolated[:attributes].reduce(metric) {|memo, item| memo.sub("@\"#{item[0]}\"", "[#{item[1]}]")}
36
+ metric = interpolated[:metrics].reduce(metric) {|memo, item| memo.sub("?\"#{item[0]}\"", "[#{item[1]}]")}
37
+ metric
38
+ end
39
+
40
+ end
@@ -1,4 +1,4 @@
1
- require 'iconv'
1
+ require 'open-uri'
2
2
 
3
3
  ##
4
4
  # Module containing classes that counter-part GoodData server-side meta-data
@@ -32,30 +32,303 @@ module GoodData
32
32
 
33
33
  SKIP_FIELD = false
34
34
 
35
- BEGINNING_OF_TIMES = Date.parse('1/1/1900')
36
-
37
35
  class << self
38
- def add_dataset(title, columns, project = nil)
39
- add_schema Schema.new('columns' => columns, 'title' => title), project
36
+ def add_dataset(name, columns, project = nil)
37
+ Schema.new('columns' => columns, 'name' => name)
38
+ add_schema(schema , project)
40
39
  end
41
40
 
42
41
  def add_schema(schema, project = nil)
43
- unless schema.is_a?(Schema) || schema.is_a?(String) then
42
+ unless schema.respond_to?(:to_maql_create) || schema.is_a?(String) then
44
43
  raise ArgumentError.new("Schema object or schema file path expected, got '#{schema}'")
45
44
  end
46
- schema = Schema.load schema unless schema.is_a? Schema
45
+ schema = Schema.load(schema) unless schema.respond_to?(:to_maql_create)
47
46
  project = GoodData.project unless project
48
47
  ldm_links = GoodData.get project.md[LDM_CTG]
49
48
  ldm_uri = Links.new(ldm_links)[LDM_MANAGE_CTG]
50
49
  GoodData.post ldm_uri, { 'manage' => { 'maql' => schema.to_maql_create } }
51
50
  end
52
51
 
53
- def to_id(str)
54
- Iconv.iconv('ascii//ignore//translit', 'utf-8', str) \
55
- .to_s.gsub(/[^\w\d_]/, '').gsub(/^[\d_]*/, '').downcase
52
+ end
53
+
54
+ class ProjectBuilder
55
+
56
+ attr_reader :title, :datasets, :reports, :metrics, :uploads, :users, :assert_report, :date_dimensions
57
+
58
+ class << self
59
+
60
+ def create(title, options={}, &block)
61
+ pb = ProjectBuilder.new(title)
62
+ block.call(pb)
63
+ pb
64
+ end
65
+
66
+ end
67
+
68
+ def initialize(title)
69
+ @title = title
70
+ @datasets = []
71
+ @reports = []
72
+ @assert_tests = []
73
+ @metrics = []
74
+ @uploads = []
75
+ @users = []
76
+ @dashboards = []
77
+ @date_dimensions = []
78
+ end
79
+
80
+ def add_date_dimension(name, options={})
81
+ @date_dimensions << {:urn => options[:urn], :name => name, :title => options[:title]}
82
+ end
83
+
84
+ def add_dataset(name, &block)
85
+ builder = GoodData::Model::SchemaBuilder.new(name)
86
+ block.call(builder)
87
+ @datasets << builder.to_hash
88
+ end
89
+
90
+ def add_report(title, options={})
91
+ @reports << {:title => title}.merge(options)
92
+ end
93
+
94
+ def add_metric(title, options={})
95
+ @metrics << {:title => title}.merge(options)
96
+ end
97
+
98
+ def add_dashboard(title, &block)
99
+ db = DashboardBuilder.new(title)
100
+ block.call(db)
101
+ @dashboards << db.to_hash
102
+ end
103
+
104
+ def load_metrics(file)
105
+ new_metrics = JSON.parse(open(file).read, :symbolize_names => true)
106
+ @metrics = @metrics + new_metrics
56
107
  end
108
+
109
+ def load_datasets(file)
110
+ new_metrics = JSON.parse(open(file).read, :symbolize_names => true)
111
+ @datasets = @datasets + new_metrics
112
+ end
113
+
114
+ def assert_report(report, result)
115
+ @assert_tests << {:report => report, :result => result}
116
+ end
117
+
118
+ def upload(data, options={})
119
+ mode = options[:mode] || "FULL"
120
+ dataset = options[:dataset]
121
+ @uploads << {
122
+ :source => data,
123
+ :mode => mode,
124
+ :dataset => dataset
125
+ }
126
+ end
127
+
128
+ def add_users(users)
129
+ @users << users
130
+ end
131
+
132
+ def to_json
133
+ JSON.pretty_generate(to_hash)
134
+ end
135
+
136
+ def to_hash
137
+ {
138
+ :title => @title,
139
+ :datasets => @datasets,
140
+ :uploads => @uploads,
141
+ :dashboards => @dashboards,
142
+ :metrics => @metrics,
143
+ :reports => @reports,
144
+ :users => @users,
145
+ :assert_tests => @assert_tests,
146
+ :date_dimensions => @date_dimensions
147
+ }
148
+ end
149
+
57
150
  end
58
151
 
152
+ class DashboardBuilder
153
+
154
+ def initialize(title)
155
+ @title = title
156
+ @tabs = []
157
+ end
158
+
159
+ def add_tab(tab, &block)
160
+ tb = TabBuilder.new(tab)
161
+ block.call(tb)
162
+ @tabs << tb
163
+ tb
164
+ end
165
+
166
+ def to_hash
167
+ {
168
+ :name => @name,
169
+ :tabs => @tabs.map{|tab| tab.to_hash}
170
+ }
171
+ end
172
+ end
173
+
174
+ class TabBuilder
175
+
176
+ def initialize(title)
177
+ @title = title
178
+ @stuff = []
179
+ end
180
+
181
+ def add_report(options={})
182
+ @stuff << {:type => :report}.merge(options)
183
+ end
184
+
185
+ def to_hash
186
+ {
187
+ :title => @title,
188
+ :items => @stuff
189
+ }
190
+ end
191
+
192
+ end
193
+
194
+ class SchemaBuilder
195
+
196
+ attr_accessor :title, :name
197
+
198
+ def initialize(name=nil)
199
+ @name = name
200
+ @columns = []
201
+ end
202
+
203
+ def add_column(column_def)
204
+ @columns.push(column_def)
205
+ self
206
+ end
207
+
208
+ def add_anchor(name, options={})
209
+ add_column({ :type => :anchor, :name => name}.merge(options))
210
+ self
211
+ end
212
+
213
+ def add_attribute(name, options={})
214
+ add_column({ :type => :attribute, :name => name}.merge(options))
215
+ self
216
+ end
217
+
218
+ def add_fact(name, options={})
219
+ add_column({ :type => :fact, :name => name}.merge(options))
220
+ self
221
+ end
222
+
223
+ def add_label(name, options={})
224
+ add_column({ :type => :label, :name => name}.merge(options))
225
+ self
226
+ end
227
+
228
+ def add_date(name, options={})
229
+ add_column({ :type => :date, :name => name}.merge(options))
230
+ end
231
+
232
+ def add_reference(name, options={})
233
+ add_column({ :type => :reference, :name => name}.merge(options))
234
+ end
235
+
236
+ def to_schema
237
+ Schema.new(to_hash)
238
+ end
239
+
240
+ def to_json
241
+ JSON.pretty_generate(to_hash)
242
+ end
243
+
244
+ def to_hash
245
+ h = {
246
+ :name => @name,
247
+ :columns => @columns
248
+ }
249
+ h.has_key?(:title) ? h.merge({:title => h[:title]}) : h
250
+ end
251
+ end
252
+
253
+ class ProjectCreator
254
+
255
+ class << self
256
+ def migrate(options={})
257
+
258
+ spec = options[:spec] || fail("You need to provide spec for migration")
259
+ spec = spec.to_hash
260
+ project = options[:project]
261
+ token = options[:token] || fail("You need to specify token for project creation")
262
+ new_project = GoodData::Project.create(:title => spec[:title], :auth_token => token)
263
+
264
+ begin
265
+ GoodData.with_project(new_project) do |p|
266
+ migrate_date_dimensions(p, spec[:date_dimensions])
267
+ migrate_datasets(p, spec[:datasets])
268
+ load(p, spec)
269
+ migrate_metrics(p, spec[:metrics])
270
+ migrate_reports(p, spec[:reports])
271
+ migrate_dashboards(p, spec[:dashboards])
272
+ migrate_users(p, spec[:users])
273
+ execute_tests(p, spec[:assert_tests])
274
+ p
275
+ end
276
+ end
277
+ end
278
+
279
+ def migrate_date_dimensions(project, spec)
280
+ spec.each do |dd|
281
+ Model.add_schema(DateDimension.new(dd), project)
282
+ end
283
+ end
284
+
285
+ def migrate_datasets(project, spec)
286
+ spec.each do |ds|
287
+ project.add_dataset(GoodData::Model::Schema.new(ds))
288
+ end
289
+ end
290
+
291
+ def migrate_reports(project, spec)
292
+ spec.each do |report|
293
+ project.add_report(report)
294
+ end
295
+ end
296
+
297
+ def migrate_dashboards(project, spec)
298
+ spec.each do |dash|
299
+ project.add_dashboard(dash)
300
+ end
301
+ end
302
+
303
+ def migrate_metrics(project, spec)
304
+ spec.each do |metric|
305
+ project.add_metric(metric)
306
+ end
307
+ end
308
+
309
+ def migrate_users(project, spec)
310
+ spec.each do |user|
311
+ puts "Would migrate user #{user}"
312
+ # project.add_user(user)
313
+ end
314
+ end
315
+
316
+ def load(project, spec)
317
+ spec[:uploads].each do |load|
318
+ schema = GoodData::Model::Schema.new(spec[:datasets].detect {|d| d[:name] == load[:dataset]})
319
+ project.upload(load[:source], schema, load[:mode])
320
+ end
321
+ end
322
+
323
+ def execute_tests(project, spec)
324
+ spec.each do |assert|
325
+ result = GoodData::ReportDefinition.execute(assert[:report])
326
+ fail "Test did not pass. Got #{result.table.inspect}, expected #{assert[:result].inspect}" if result.table != assert[:result]
327
+ end
328
+ end
329
+ end
330
+ end
331
+
59
332
  class MdObject
60
333
  attr_accessor :name, :title
61
334
 
@@ -72,7 +345,7 @@ module GoodData
72
345
  # non-Latin character and then dropping non-alphanumerical characters.
73
346
  #
74
347
  def identifier
75
- @identifier ||= "#{self.type_prefix}.#{Model::to_id(name)}"
348
+ @identifier ||= "#{self.type_prefix}.#{name}"
76
349
  end
77
350
  end
78
351
 
@@ -82,13 +355,14 @@ module GoodData
82
355
  # model abstractions.
83
356
  #
84
357
  class Schema < MdObject
85
- attr_reader :fields, :attributes, :facts, :folders, :references, :labels
358
+ attr_reader :fields, :attributes, :facts, :folders, :references, :labels, :name, :title
86
359
 
87
360
  def self.load(file)
88
361
  Schema.new JSON.load(open(file))
89
362
  end
90
363
 
91
- def initialize(config, title = nil)
364
+ def initialize(config, name = nil)
365
+ super()
92
366
  @fields = []
93
367
  @attributes = {}
94
368
  @facts = {}
@@ -99,64 +373,45 @@ module GoodData
99
373
  @references = {}
100
374
  @labels = []
101
375
 
102
- config['title'] = title unless config['title']
103
- raise 'Schema name not specified' unless config['title']
104
- self.title = config['title']
376
+ config[:name] = name unless config[:name]
377
+ config[:title] = config[:title] || config[:name].humanize
378
+ fail 'Schema name not specified' unless config[:name]
379
+ self.name = config[:name]
380
+ self.title = config[:title]
105
381
  self.config = config
106
382
  end
107
383
 
108
- def transform_header(headers)
109
- result = fields.reduce([]) do |memo, f|
110
- val = f.to_csv_header(headers)
111
- memo << val unless val === SKIP_FIELD
112
- memo
113
- end
114
- result.flatten
115
- end
116
-
117
- def transform_row(headers, row)
118
- result = fields.reduce([]) do |memo, f|
119
- val = f.to_csv_data(headers, row)
120
- memo << val unless val === SKIP_FIELD
121
- memo
122
- end
123
- result.flatten
124
- end
125
-
126
384
  def config=(config)
127
- config['columns'].each do |c|
128
- case c['type']
129
- when 'ATTRIBUTE'
385
+ config[:columns].each do |c|
386
+ case c[:type].to_s
387
+ when "attribute"
130
388
  add_attribute c
131
- when 'FACT'
389
+ when "fact"
132
390
  add_fact c
133
- when 'DATE'
391
+ when "date"
134
392
  add_date c
135
- when 'CONNECTION_POINT'
393
+ when "anchor"
136
394
  set_connection_point c
137
- when 'LABEL'
395
+ when "label"
138
396
  add_label c
139
- when 'REFERENCE'
397
+ when "reference"
140
398
  add_reference c
141
399
  else
142
- fail "Unexpected type #{c['type']} in #{c.inspect}"
400
+ fail "Unexpected type #{c[:type]} in #{c.inspect}"
143
401
  end
144
402
  end
145
403
  @connection_point = RecordsOf.new(nil, self) unless @connection_point
146
404
  end
147
405
 
148
- def title=(title)
149
- @name = title
150
- @title = title
406
+ def type_prefix
407
+ 'dataset'
151
408
  end
152
409
 
153
- def type_prefix ; 'dataset' ; end
154
-
155
410
  ##
156
411
  # Underlying fact table name
157
412
  #
158
413
  def table
159
- @table ||= FACT_COLUMN_PREFIX + Model::to_id(name)
414
+ @table ||= FACT_COLUMN_PREFIX + name
160
415
  end
161
416
 
162
417
  ##
@@ -199,27 +454,39 @@ module GoodData
199
454
  folders_maql + "\n" + maql + "SYNCHRONIZE {#{identifier}};\n"
200
455
  end
201
456
 
202
- # Load given file into a data set described by the given schema
203
- #
204
457
  def upload(path, project = nil, mode = "FULL")
458
+ if path =~ URI::regexp
459
+ Tempfile.open('remote_file') do |temp|
460
+ temp << open(path).read
461
+ temp.flush
462
+ upload_data(temp, project, mode)
463
+ end
464
+ else
465
+ upload_data(path, project, mode)
466
+ end
467
+ end
468
+
469
+ # Load given file into a data set described by the given schema
470
+ def upload_data(path, project = nil, mode = "FULL")
205
471
  path = path.path if path.respond_to? :path
206
- header = nil
472
+
473
+ inline_data = path.is_a?(String) ? false : true
474
+
207
475
  project = GoodData.project unless project
208
476
 
209
477
  # create a temporary zip file
210
478
  dir = Dir.mktmpdir
211
- Zip::ZipFile.open("#{dir}/upload.zip", Zip::ZipFile::CREATE) do |zip|
479
+ Zip::File.open("#{dir}/upload.zip", Zip::File::CREATE) do |zip|
212
480
  # TODO make sure schema columns match CSV column names
213
481
  zip.get_output_stream('upload_info.json') { |f| f.puts JSON.pretty_generate(to_manifest(mode)) }
214
- zip.get_output_stream('data.csv') do |f|
215
- FasterCSV.foreach(path, :headers => true, :return_headers => true) do |row|
216
- output = if row.header_row?
217
- transform_header(row)
218
- else
219
- transform_row(header, row)
482
+ if inline_data
483
+ zip.get_output_stream('data.csv') do |f|
484
+ path.each do |row|
485
+ f.puts row.to_csv
220
486
  end
221
- f.puts output.to_csv
222
487
  end
488
+ else
489
+ zip.add('data.csv', path)
223
490
  end
224
491
  end
225
492
 
@@ -234,6 +501,7 @@ module GoodData
234
501
  while (GoodData.get(task["pullTask"]["uri"])["taskStatus"] === "RUNNING" || GoodData.get(task["pullTask"]["uri"])["taskStatus"] === "PREPARED") do
235
502
  sleep 30
236
503
  end
504
+ fail "Load Failed" if (GoodData.get(task["pullTask"]["uri"])["taskStatus"] == "ERROR")
237
505
  puts "Done loading"
238
506
  end
239
507
 
@@ -322,10 +590,11 @@ module GoodData
322
590
  attr_accessor :folder, :name, :title, :schema
323
591
 
324
592
  def initialize(hash, schema)
593
+ super()
325
594
  raise ArgumentError.new("Schema must be provided, got #{schema.class}") unless schema.is_a? Schema
326
- @name = hash['name'] || raise("Data set fields must have their names defined")
327
- @title = hash['title'] || hash['name']
328
- @folder = hash['folder']
595
+ @name = hash[:name] || raise("Data set fields must have their names defined")
596
+ @title = hash[:title] || hash[:name].humanize
597
+ @folder = hash[:folder]
329
598
  @schema = schema
330
599
  end
331
600
 
@@ -334,7 +603,7 @@ module GoodData
334
603
  # non-Latin character and then dropping non-alphanumerical characters.
335
604
  #
336
605
  def identifier
337
- @identifier ||= "#{self.type_prefix}.#{Model::to_id @schema.title}.#{Model::to_id name}"
606
+ @identifier ||= "#{self.type_prefix}.#{@schema.name}.#{name}"
338
607
  end
339
608
 
340
609
  def to_maql_drop
@@ -343,7 +612,7 @@ module GoodData
343
612
 
344
613
  def visual
345
614
  visual = super
346
- visual += ", FOLDER {#{folder_prefix}.#{Model::to_id(folder)}}" if folder
615
+ visual += ", FOLDER {#{folder_prefix}.#{(folder)}}" if folder
347
616
  visual
348
617
  end
349
618
 
@@ -380,10 +649,10 @@ module GoodData
380
649
  end
381
650
 
382
651
  def table
383
- @table ||= "d_" + Model::to_id(@schema.name) + "_" + Model::to_id(name)
652
+ @table ||= "d_" + @schema.name + "_" + name
384
653
  end
385
654
 
386
- def key ; "#{Model::to_id(@name)}#{FK_SUFFIX}" ; end
655
+ def key ; "#{@name}#{FK_SUFFIX}" ; end
387
656
 
388
657
  def to_maql_create
389
658
  maql = "CREATE ATTRIBUTE {#{identifier}} VISUAL (#{visual})" \
@@ -413,7 +682,7 @@ module GoodData
413
682
  # def initialize(hash, schema)
414
683
  def initialize(hash, attribute, schema)
415
684
  super hash, schema
416
- @attribute = attribute || schema.fields.find {|field| field.name === hash["reference"]}
685
+ @attribute = attribute || schema.fields.find {|field| field.name === hash[:reference]}
417
686
  end
418
687
 
419
688
  def to_maql_create
@@ -431,7 +700,7 @@ module GoodData
431
700
  end
432
701
 
433
702
  def column
434
- "#{@attribute.table}.#{LABEL_COLUMN_PREFIX}#{Model::to_id name}"
703
+ "#{@attribute.table}.#{LABEL_COLUMN_PREFIX}#{name}"
435
704
  end
436
705
 
437
706
  alias :inspect_orig :inspect
@@ -457,7 +726,7 @@ module GoodData
457
726
  end
458
727
 
459
728
  def table
460
- @table ||= "f_" + Model::to_id(@schema.name)
729
+ @table ||= "f_" + @schema.name
461
730
  end
462
731
 
463
732
  def to_maql_create
@@ -484,7 +753,7 @@ module GoodData
484
753
  end
485
754
 
486
755
  def column
487
- @column ||= table + '.' + column_prefix + Model::to_id(name)
756
+ @column ||= table + '.' + column_prefix + name
488
757
  end
489
758
 
490
759
  def to_maql_create
@@ -508,10 +777,9 @@ module GoodData
508
777
  def initialize(column, schema)
509
778
  super column, schema
510
779
  # pp column
511
-
512
- @name = column['name']
513
- @reference = column['reference']
514
- @schema_ref = column['schema_reference']
780
+ @name = column[:name]
781
+ @reference = column[:reference]
782
+ @schema_ref = column[:dataset]
515
783
  @schema = schema
516
784
  end
517
785
 
@@ -521,13 +789,13 @@ module GoodData
521
789
  # from the reference key.
522
790
  #
523
791
  def identifier
524
- @identifier ||= "#{ATTRIBUTE_PREFIX}.#{Model::to_id @schema_ref}.#{Model::to_id @reference}"
792
+ @identifier ||= "#{ATTRIBUTE_PREFIX}.#{@schema_ref}.#{@reference}"
525
793
  end
526
794
 
527
- def key ; "#{Model::to_id @name}_id" ; end
795
+ def key ; "#{@name}_id" ; end
528
796
 
529
797
  def label_column
530
- "#{LABEL_PREFIX}.#{Model::to_id @schema_ref}.#{Model::to_id @reference}"
798
+ "#{LABEL_PREFIX}.#{@schema_ref}.#{@reference}"
531
799
  end
532
800
 
533
801
  def to_maql_create
@@ -551,40 +819,40 @@ module GoodData
551
819
  ##
552
820
  # Fact representation of a date.
553
821
  #
554
- class DateFact < Fact
555
-
556
- attr_accessor :format, :output_format
557
-
558
- def initialize(column, schema)
559
- super column, schema
560
- @output_format = column["format"] || '("dd/MM/yyyy")'
561
- @format = @output_format.gsub('yyyy', '%Y').gsub('MM', '%m').gsub('dd', '%d')
562
- end
563
-
564
- def column_prefix ; DATE_COLUMN_PREFIX ; end
565
- def type_prefix ; DATE_FACT_PREFIX ; end
566
-
567
- def to_csv_header(row)
568
- "#{name}_fact"
569
- end
570
-
571
- def to_csv_data(headers, row)
572
- val = row[name]
573
- val.nil?() ? nil : (Date.strptime(val, format) - BEGINNING_OF_TIMES).to_i
574
- rescue ArgumentError
575
- raise "Value \"#{val}\" for column \"#{name}\" did not match the format: #{format}. " +
576
- "Perhaps you need to add or change the \"format\" key in the data set configuration."
577
- end
578
-
579
- def to_manifest_part(mode)
580
- {
581
- 'populates' => [ identifier ],
582
- 'mode' => mode,
583
- 'columnName' => "#{name}_fact"
584
- }
585
- end
586
-
587
- end
822
+ # class DateFact < Fact
823
+ #
824
+ # attr_accessor :format, :output_format
825
+ #
826
+ # def initialize(column, schema)
827
+ # super column, schema
828
+ # @output_format = column["format"] || '("dd/MM/yyyy")'
829
+ # @format = @output_format.gsub('yyyy', '%Y').gsub('MM', '%m').gsub('dd', '%d')
830
+ # end
831
+ #
832
+ # def column_prefix ; DATE_COLUMN_PREFIX ; end
833
+ # def type_prefix ; DATE_FACT_PREFIX ; end
834
+ #
835
+ # def to_csv_header(row)
836
+ # "#{name}_fact"
837
+ # end
838
+ #
839
+ # def to_csv_data(headers, row)
840
+ # val = row[name]
841
+ # val.nil?() ? nil : (Date.strptime(val, format) - BEGINNING_OF_TIMES).to_i
842
+ # rescue ArgumentError
843
+ # raise "Value \"#{val}\" for column \"#{name}\" did not match the format: #{format}. " +
844
+ # "Perhaps you need to add or change the \"format\" key in the data set configuration."
845
+ # end
846
+ #
847
+ # def to_manifest_part(mode)
848
+ # {
849
+ # 'populates' => [ identifier ],
850
+ # 'mode' => mode,
851
+ # 'columnName' => "#{name}_fact"
852
+ # }
853
+ # end
854
+ #
855
+ # end
588
856
 
589
857
  ##
590
858
  # Date as a reference to a date dimension
@@ -595,13 +863,13 @@ module GoodData
595
863
 
596
864
  def initialize(column, schema)
597
865
  super column, schema
598
- @output_format = column["format"] || '("dd/MM/yyyy")'
866
+ @output_format = column["format"] || 'dd/MM/yyyy'
599
867
  @format = @output_format.gsub('yyyy', '%Y').gsub('MM', '%m').gsub('dd', '%d')
600
- @urn = column["urn"] || "URN:GOODDATA:DATE"
868
+ @urn = column[:urn] || "URN:GOODDATA:DATE"
601
869
  end
602
870
 
603
871
  def identifier
604
- @identifier ||= "#{Model::to_id @schema_ref}.#{DATE_ATTRIBUTE}"
872
+ @identifier ||= "#{@schema_ref}.#{DATE_ATTRIBUTE}"
605
873
  end
606
874
 
607
875
  def to_manifest_part(mode)
@@ -614,14 +882,14 @@ module GoodData
614
882
  }
615
883
  end
616
884
 
617
- def to_maql_create
618
- # urn:chefs_warehouse_fiscal:date
619
- super_maql = super
620
- maql = ""
621
- # maql = "# Include date dimensions\n"
622
- # maql += "INCLUDE TEMPLATE \"#{urn}\" MODIFY (IDENTIFIER \"#{name}\", TITLE \"#{title || name}\");\n"
623
- maql += super_maql
624
- end
885
+ # def to_maql_create
886
+ # # urn:chefs_warehouse_fiscal:date
887
+ # super_maql = super
888
+ # maql = ""
889
+ # # maql = "# Include date dimensions\n"
890
+ # # maql += "INCLUDE TEMPLATE \"#{urn}\" MODIFY (IDENTIFIER \"#{name}\", TITLE \"#{title || name}\");\n"
891
+ # maql += super_maql
892
+ # end
625
893
 
626
894
  end
627
895
 
@@ -677,22 +945,22 @@ module GoodData
677
945
  super column, schema
678
946
  @parts = {} ; @facts = [] ; @attributes = []; @references = []
679
947
 
680
- @facts << @parts[:date_fact] = DateFact.new(column, schema)
681
- if column['schema_reference'] then
948
+ # @facts << @parts[:date_fact] = DateFact.new(column, schema)
949
+ if column[:dataset] then
682
950
  @parts[:date_ref] = DateReference.new column, schema
683
951
  @references << @parts[:date_ref]
684
952
  else
685
953
  @attributes << @parts[:date_attr] = DateAttribute.new(column, schema)
686
954
  end
687
- if column['datetime'] then
688
- puts "*** datetime"
689
- @facts << @parts[:time_fact] = TimeFact.new(column, schema)
690
- if column['schema_reference'] then
691
- @parts[:time_ref] = TimeReference.new column, schema
692
- else
693
- @attributes << @parts[:time_attr] = TimeAttribute.new(column, schema)
694
- end
695
- end
955
+ # if column['datetime'] then
956
+ # puts "*** datetime"
957
+ # @facts << @parts[:time_fact] = TimeFact.new(column, schema)
958
+ # if column['schema_reference'] then
959
+ # @parts[:time_ref] = TimeReference.new column, schema
960
+ # else
961
+ # @attributes << @parts[:time_attr] = TimeAttribute.new(column, schema)
962
+ # end
963
+ # end
696
964
  end
697
965
 
698
966
  def to_maql_create
@@ -727,7 +995,7 @@ module GoodData
727
995
  end
728
996
 
729
997
  def to_maql_create
730
- "CREATE FOLDER {#{type_prefix}.#{Model::to_id(name)}}" \
998
+ "CREATE FOLDER {#{type_prefix}.#{name}}" \
731
999
  + " VISUAL (#{visual}) TYPE #{type};\n"
732
1000
  end
733
1001
  end
@@ -750,13 +1018,25 @@ module GoodData
750
1018
 
751
1019
  class DateDimension < MdObject
752
1020
 
1021
+ def initialize(spec={})
1022
+ super()
1023
+ @name = spec[:name]
1024
+ @title = spec[:title] || @name
1025
+ @urn = spec[:urn] || "URN:GOODDATA:DATE"
1026
+ end
1027
+
1028
+
753
1029
  def to_maql_create
754
- # urn:chefs_warehouse_fiscal:date
1030
+ # urn = "urn:chefs_warehouse_fiscal:date"
1031
+ # title = "title"
1032
+ # name = "name"
1033
+
755
1034
  maql = ""
756
- maql += "INCLUDE TEMPLATE \"#{urn}\" MODIFY (IDENTIFIER \"#{name}\", TITLE \"#{title || name}\");"
1035
+ maql += "INCLUDE TEMPLATE \"#{@urn}\" MODIFY (IDENTIFIER \"#{@name}\", TITLE \"#{@title}\");"
757
1036
  maql
758
1037
  end
1038
+
759
1039
  end
760
1040
 
761
1041
  end
762
- end
1042
+ end