gooddata 0.5.16 → 0.6.0.pre2

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 (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