gd_bam 0.1.34 → 0.1.35

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bam/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bam
2
- VERSION = '0.1.34'
2
+ VERSION = '0.1.35'
3
3
  end
@@ -98,7 +98,7 @@ module GoodData
98
98
  def self.sink_out_gd_metadata(metadata, sink)
99
99
  metadata_fields = metadata[:fields]
100
100
  sink_facts = GoodData::Bam::Sink.get_fact_fields(sink).map {|f| f[:meta]}
101
- x = metadata_fields.map {|f| sink_facts.include?(f[:name]) ? f.merge({:type => "decimal"}) : f}
101
+ x = metadata_fields.map {|f| sink_facts.include?(f[:name]) ? f.merge({:type => "decimal", :length => 20, :scale => 3}) : f}
102
102
  GoodData::Bam::Metadata.create(metadata.merge({:fields => x}))
103
103
  end
104
104
 
@@ -110,7 +110,12 @@ module GoodData
110
110
  :type => description[:type]
111
111
  }) do |record|
112
112
  description[:fields].each do |field|
113
- builder.Field :name => field[:name], :type => field[:type] || "string", :nullable => "true"
113
+ # binding.pry if field.has_key?(:length)
114
+ cloned_field = field.clone
115
+ cloned_field[:type] = "string" if cloned_field[:type].blank?
116
+ cloned_field[:nullable] = "true" if cloned_field[:nullable].blank?
117
+
118
+ builder.Field cloned_field
114
119
  end
115
120
  end
116
121
  end
@@ -38,19 +38,29 @@ module GoodData
38
38
  function integer count() {
39
39
 
40
40
  // This would run for the first time since we do not have anything stored in the custom properties hash
41
- if (indexOf($in.0.key, "#{dataset}_LAST_RUN") != -1) {
41
+ //if (indexOf($in.0.key, "#{dataset}_LAST_RUN") != -1) {
42
42
  return 4;
43
- }
44
- else {
45
- return 0;
46
- }
43
+ //}
44
+ //else {
45
+ // return 0;
46
+ //}
47
47
  }
48
48
 
49
49
  string last_run = null;
50
50
  long last_run_ts = null;
51
51
  string end_date = null;
52
- long now = date2long(today());
53
- long ten_mins_ago = now - (60 * 10) ;
52
+ date now = today();
53
+
54
+ string p_year = date2str(now, "yyyy");
55
+ string p_month = date2str(now, "MM");
56
+ string p_day = date2str(now, "dd");
57
+ string p_hour = date2str(now, "HH");
58
+ string p_minute = date2str(now, "mm");
59
+ string p_second = date2str(now, "ss");
60
+
61
+ string now_date_concatenated = concat(p_year, '-', p_month, '-', p_day, 'T', p_hour, ':', p_minute, ':', p_second, '.000');
62
+ long now_without_milis = date2long(str2date(now_date_concatenated, "yyyy-MM-dd'T'HH:mm:ss.SSS"));
63
+ long ten_mins_ago = now_without_milis - (60L * 10L * 1000L);
54
64
 
55
65
 
56
66
  function integer transform(integer idx) {
@@ -59,6 +69,11 @@ function integer transform(integer idx) {
59
69
  last_run_ts = date2long(jodaStr2date(last_run, ["yyyy-MM-dd'T'HH:mm:ss.SSSZZ"], 'en_US', 'UTC', 'UTC'));
60
70
  }
61
71
 
72
+ printErr(ten_mins_ago);
73
+ printErr(date2long(now));
74
+ printErr(last_run_ts);
75
+
76
+
62
77
  if (end_date == null) {
63
78
  if (ten_mins_ago < last_run_ts) {
64
79
  end_date = jodaDate2str(long2date(last_run_ts), "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", "en_US", 'UTC');
@@ -66,7 +81,7 @@ function integer transform(integer idx) {
66
81
  end_date = jodaDate2str(long2date(ten_mins_ago), "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", "en_US", 'UTC');
67
82
  }
68
83
  }
69
-
84
+
70
85
  if (idx == 1) {
71
86
  $out.0.all = "#{dataset}_TRUNCATE_DATE=" + jodaDate2str(jodaStr2date(last_run, ["yyyy-MM-dd'T'HH:mm:ss.SSSZZ"], 'en_US', 'UTC', 'UTC'), "yyyy-MM-dd HH:mm:ss", 'en_US', 'UTC');
72
87
  } else if (idx == 2) {
@@ -74,7 +89,8 @@ function integer transform(integer idx) {
74
89
  } else if (idx == 3) {
75
90
  $out.0.all = "#{dataset}_END=" + end_date;
76
91
  } else {
77
- $out.0.all = "#{dataset}_LAST_RUN=" + end_date;
92
+ $out.0.all = "#{dataset}_LAST_RUN=" + end_date;
93
+ //+ last_run_ts + " " + ten_mins_ago;
78
94
  }
79
95
 
80
96
  return OK;
@@ -320,7 +336,9 @@ HEREDOC
320
336
  es_transformation_source = if has_timestamp
321
337
  "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = str2date($in.0.#{timestamp_field[:name]},\"joda:yyyy-MM-dd'T'HH:mm:ss.SSSZZ\");;\nreturn OK;\n}"
322
338
  else
323
- "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = long2date(${GRAPH_STARTED_TIMESTAMP});\nreturn OK;\n}"
339
+ "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = jodaStr2date(\"${#{dataset}_END}\",[\"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"], 'en_US', 'UTC', 'UTC');\nreturn OK;\n}"
340
+
341
+
324
342
  end
325
343
 
326
344
  Core::build_node2(builder, Nodes.copy2({:name => "#{file} copy", :id => "#{file}_copy"}))
@@ -338,7 +356,7 @@ HEREDOC
338
356
  Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_s3:0", :fromNode => "#{file}_copy:2", :metadata => "#{file}_source_metadata"}))
339
357
 
340
358
  else
341
- Core::build_node2(builder, Nodes.reformat2({:name => "#{file} Reformat", :id => "#{file}_s3_reformat", :transformation => "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Timestamp = toString(${GRAPH_STARTED_TIMESTAMP});\nreturn OK;\n}"}))
359
+ Core::build_node2(builder, Nodes.reformat2({:name => "#{file} Reformat", :id => "#{file}_s3_reformat", :transformation => "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Timestamp = \"${#{dataset}_END}\";\nreturn OK;\n}"}))
342
360
  Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_s3_reformat:0", :fromNode => "#{file}_copy:2", :metadata => "#{file}_source_metadata"}))
343
361
 
344
362
  Core::build_node2(builder, Nodes.writer2({:enabled => "enabled", :name => "#{file} s3 Writer", :id => "#{file}_s3", :fileURL => "https://${S3_ACCESS_KEY_ID}:\`replace(\"${S3_SECRET_ACCESS_KEY}\",\"/\",\"%2F\")\`@${S3_BUCKETNAME}.s3.amazonaws.com/${GDC_PROJECT_ID}/#{file}/#{file}_\`date2long(today())\`", :outputFieldNames => true}))
@@ -450,7 +468,6 @@ HEREDOC
450
468
 
451
469
  (tap[:fields] - [id_field, timestamp_field]).each_with_index do |field, i|
452
470
  f = field[:name]
453
-
454
471
  selects = if (f == "CreatedDate") then
455
472
  [{
456
473
  :object => sf_object,
@@ -465,6 +482,7 @@ HEREDOC
465
482
  else
466
483
  objects_to_get.reduce([]) do |memo, o|
467
484
  fields = client.fields(o)
485
+ fields_with_details = client.fields(sf_object, :with_details => true)
468
486
  # how the history is stored does not rely on table naming convention. It is a couple of conventionsmangled together.This piece of code is trying to recognize which it is and produce the right downloader
469
487
  generic_field_history = ["NewValue", "OldValue", "ParentId"].all? {|fl| fields.include?(fl)}
470
488
  specific_field_history = ["NewValue", "OldValue", "#{sf_object}Id"].all? {|fl| fields.include?(fl)}
@@ -483,8 +501,10 @@ HEREDOC
483
501
  ]
484
502
  elsif (specific_field_history && !field[:multi_currency])
485
503
  # This is like the previous with the difference that it specifically names the id of the record. Like OpportunityId, AccountId, etc.
504
+ sf_field = fields_with_details.find {|sf_f| sf_f[:name] == f}
505
+ sf_field_type = sf_field[:type]
486
506
  [
487
- "SELECT NewValue, CreatedDate, #{sf_object}Id FROM #{o} WHERE Field = '#{f}'",
507
+ sf_field_type == "reference" ? "SELECT NewValue, CreatedDate, #{sf_object}Id FROM #{o} WHERE Field = '#{f.chomp('Id')}'" : "SELECT NewValue, CreatedDate, #{sf_object}Id FROM #{o} WHERE Field = '#{f}'",
488
508
  "{\"xmlFieldsMapping\":{\"xmlFields\":[
489
509
  {\"xmlFieldMapping\":{\"name\":\"NewValue\",\"label\":\"NewValue\",\"xmlPath\":\"NewValue\",\"metadataField\":\"Value\"}},
490
510
  {\"xmlFieldMapping\":{\"name\":\"CreatedDate\",\"label\":\"CreatedDate\",\"xmlPath\":\"CreatedDate\",\"metadataField\":\"Timestamp\"}},
@@ -547,7 +567,7 @@ HEREDOC
547
567
 
548
568
  phase = 1
549
569
 
550
- taps_memo.values.each_slice(6).to_a.each do |slice|
570
+ taps_memo.values.each_slice(4).to_a.each do |slice|
551
571
  builder.Phase(:number => phase +=1) do
552
572
  slice.each do |field|
553
573
  # taps_memo.each do |key, field|
@@ -747,7 +767,7 @@ HEREDOC
747
767
  es_transformation_source = if has_timestamp
748
768
  "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = str2date($in.0.#{timestamp_field[:name]},\"joda:yyyy-MM-dd'T'HH:mm:ss.SSSZZ\");\nreturn OK;\n}"
749
769
  else
750
- "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = long2date(${GRAPH_STARTED_TIMESTAMP});\nreturn OK;\n}"
770
+ "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Id = $in.0.#{id_field[:name]};\n$out.0.Timestamp = jodaStr2date(\"${#{dataset}_END}\",[\"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"], 'en_US', 'UTC', 'UTC');\nreturn OK;\n}"
751
771
  end
752
772
 
753
773
  Core::build_node2(builder, Nodes.copy2({:name => "#{file} copy", :id => "#{file}_copy"}))
@@ -757,7 +777,7 @@ HEREDOC
757
777
  Core::build_node2(builder, Nodes.reformat2({:name => "#{file} Reformat", :id => "#{file}_es_reformat", :transformation => es_transformation_source}))
758
778
  Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_es_reformat:0", :fromNode => "#{file}_copy:1", :metadata => "#{file}_source_metadata"}))
759
779
  Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_csv:0", :fromNode => "#{file}_copy:0", :metadata => "#{file}_source_metadata"}))
760
-
780
+
761
781
  if s3_backup
762
782
  if has_timestamp
763
783
  Core::build_node2(builder, Nodes.writer2({:enabled => "enabled", :name => "#{file} s3 Writer", :id => "#{file}_s3", :fileURL => "https://${S3_ACCESS_KEY_ID}:\`replace(\"${S3_SECRET_ACCESS_KEY}\",\"/\",\"%2F\")\`@${S3_BUCKETNAME}.s3.amazonaws.com/${GDC_PROJECT_ID}/#{file}/#{file}_\`date2long(today())\`", :outputFieldNames => true}))
@@ -772,7 +792,6 @@ HEREDOC
772
792
  # Core::build_node2(builder, Nodes.writer2({:enabled => "enabled", :name => "#{file} s3 Writer", :id => "#{file}_s3", :fileURL => "https://${S3_ACCESS_KEY_ID}:\`replace(\"${S3_SECRET_ACCESS_KEY}\",\"/\",\"%2F\")\`@${S3_BUCKETNAME}.s3.amazonaws.com/${GDC_PROJECT_ID}/#{file}/#{file}_\`date2long(today())\`", :outputFieldNames => true}))
773
793
  # Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_s3:0", :fromNode => "#{file}_copy:2", :metadata => "#{file}_source_metadata"}))
774
794
  end
775
-
776
795
 
777
796
  Core::build_node2(builder, Nodes.sort2({:sortKey => "Timestamp(a)",:name => "#{file} es Sort", :id => "#{file}_es_sort"}))
778
797
  Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_es_sort:0", :fromNode => "#{file}_es_reformat:0", :metadata => "#{file}_es_metadata"}))
@@ -144,7 +144,7 @@ function decimal deal_with_scientific_notation(string a_number) {
144
144
  if (isnull(a_number) || a_number == "") {
145
145
  return null;
146
146
  } else {
147
- return str2decimal(a_number);
147
+ return floor(str2decimal(a_number)*1000D)/1000D;
148
148
  }
149
149
  }
150
150
 
@@ -304,6 +304,7 @@ HEREDOC
304
304
  end
305
305
 
306
306
 
307
+ # Skipping the one row that is added by ES
307
308
  transformation_source = if Metadata::has_field?(metadata_from_es, "Snapshot")
308
309
  "function integer transform() {\n" + (Tap.source_target_mappging(tap).map {|t| "$out.0.#{t.last} = $in.0.#{t.first};"}.join("\n")) + "\n$out.0.Snapshot = date2str(dateAdd(str2date(\"1900-01-01\", \"yyyy-MM-dd\"), str2long($in.0.Snapshot), day), \"yyyy-MM-dd\");\nreturn OK;\n}"
309
310
  else
@@ -311,17 +312,53 @@ HEREDOC
311
312
  end
312
313
  Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "reformat", :transformation => transformation_source}))
313
314
  Core::build_node2(builder, Nodes.edge2({:toNode => "reformat:0", :fromNode => "es:0", :metadata => "es_metadata"}))
315
+
316
+ # Filter out deleted Records
314
317
  if tap[:has_deleted_records] == true
315
318
  filter_deleted_function = "function integer transform() {\nif ($in.0.IsDeleted == \"true\") {return SKIP;} else {$out.0.* = $in.0.*; return OK;};\n}"
316
319
  Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "filter_deleted", :transformation => filter_deleted_function}))
317
320
  Core::build_node2(builder, Nodes.edge2({:toNode => "filter_deleted:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
318
- Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "filter_deleted:0", :metadata => "output_metadata"}))
321
+ Core::build_node2(builder, Nodes.edge2({:toNode => "dummy_reformat_1:0", :fromNode => "filter_deleted:0", :metadata => "output_metadata"}))
319
322
  else
320
- Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
323
+ Core::build_node2(builder, Nodes.edge2({:toNode => "dummy_reformat_1:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
321
324
  end
322
325
 
326
+ Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "dummy_reformat_1", :transformation => Nodes::MAP_ALL}))
327
+
328
+ # Propagating a value from latest snapshot to all snapshots if necessary
329
+ if tap[:propagate_latest_value_for] && !tap[:propagate_latest_value_for].empty?
330
+
331
+ retain_transform = <<HEREDOC
332
+ #{tap[:propagate_latest_value_for].map {|f| "string " + f + " = \"\";"}.join("\n")}
333
+ string id = null;
334
+ string previousId = null;
335
+
336
+ function integer transform() {
337
+ $out.0.* = $in.0.*;
338
+ id = $in.0.Id;
339
+ if (id != previousId) {
340
+ #{tap[:propagate_latest_value_for].map {|f| f + " = $in.0." + f + ";"}.join("\n")}
341
+ }
342
+ #{tap[:propagate_latest_value_for].map {|f| "$out.0." + f + " = " + f + ";"}.join("\n")}
343
+ previousId = id;
344
+ return ALL;
345
+ }
346
+ HEREDOC
347
+ fields_to_propagate = tap[:propagate_latest_value_for]
348
+ propagate_values_function = "string lastId;\nfunction integer transform() {\nif (lastId !=$in.0.Id) {$in.0.*=$out.0.*;} else {$in.0.*=$out.0.*; #{fields_to_propagate.map{|f| "$out.0.#{f} = \"XXXXX\""}.join("\n")}};lastId=$in.0.Id \nreturn OK;\n}"
349
+ Core::build_node2(builder, Nodes.sort2({:sortKey => "Id(a);Snapshot(d)", :id => "sort_for_history_retain"}));
350
+ Core::build_node2(builder, Nodes.edge2({:toNode => "sort_for_history_retain:0", :fromNode => "dummy_reformat_1:0", :metadata => "output_metadata"}))
351
+ Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "retain_values_reformat", :transformation => retain_transform}))
352
+ Core::build_node2(builder, Nodes.edge2({:toNode => "retain_values_reformat:0", :fromNode => "sort_for_history_retain:0", :metadata => "output_metadata"}))
353
+ Core::build_node2(builder, Nodes.edge2({:toNode => "dummy_reformat_2:0", :fromNode => "retain_values_reformat:0", :metadata => "output_metadata"}))
354
+ else
355
+ Core::build_node2(builder, Nodes.edge2({:toNode => "dummy_reformat_2:0", :fromNode => "dummy_reformat_1:0", :metadata => "output_metadata"}))
356
+ end
357
+
358
+ Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "dummy_reformat_2", :transformation => Nodes::MAP_ALL}))
359
+
323
360
  Core::build_node2(builder, Nodes.copy2({:name => "Copy", :id => "copy"}))
324
- # Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
361
+ Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "dummy_reformat_2:0", :metadata => "output_metadata"}))
325
362
  Core::build_node2(builder, Nodes.writer2({:name => "CSV Writer", :id => "csv", :fileURL => "${PROJECT}/data/#{tap[:id]}.csv", :outputFieldNames => "true", :makeDirs => "true"}))
326
363
  Core::build_node2(builder, Nodes.edge2({:toNode => "csv:0", :fromNode => "copy:0", :metadata => "output_metadata"}))
327
364
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gd_bam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.34
4
+ version: 0.1.35
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-01 00:00:00.000000000 Z
12
+ date: 2013-10-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -258,7 +258,7 @@ dependencies:
258
258
  requirements:
259
259
  - - ! '>='
260
260
  - !ruby/object:Gem::Version
261
- version: 0.0.2
261
+ version: 0.0.4
262
262
  type: :runtime
263
263
  prerelease: false
264
264
  version_requirements: !ruby/object:Gem::Requirement
@@ -266,7 +266,7 @@ dependencies:
266
266
  requirements:
267
267
  - - ! '>='
268
268
  - !ruby/object:Gem::Version
269
- version: 0.0.2
269
+ version: 0.0.4
270
270
  - !ruby/object:Gem::Dependency
271
271
  name: gd_es
272
272
  requirement: !ruby/object:Gem::Requirement
@@ -320,11 +320,9 @@ files:
320
320
  - lib/base/step.rb
321
321
  - lib/base/tap.rb
322
322
  - lib/base/taps.rb
323
- - lib/base/taps.rb.orig
324
323
  - lib/cloud_connect/dsl/cc.rb
325
324
  - lib/cloud_connect/dsl/es_helpers.rb
326
325
  - lib/cloud_connect/dsl/helpers.rb
327
- - lib/cloud_connect/dsl/helpers.rb.orig
328
326
  - lib/cloud_connect/dsl/nodes.rb
329
327
  - lib/cloud_connect/dsl/sf_helpers.rb
330
328
  - lib/cloud_connect/dsl/structure_helpers.rb
@@ -1,35 +0,0 @@
1
- module GoodData
2
- module Bam
3
- module Taps
4
-
5
- def self.get_incremental(taps)
6
- taps.find_all {|t| t[:direct] == false || t[:direct].nil? }
7
- end
8
-
9
- def self.get_salesforce(taps)
10
- taps.find_all {|t| t[:source_type] == :salesforce}
11
- end
12
-
13
- def self.get_file(taps)
14
- taps.find_all {|t| [:web, :file].include?(t[:source_type]) }
15
- end
16
-
17
- <<<<<<< HEAD
18
- def self.get_deleted_records_info(taps, client)
19
- deleted = client.modules.map {|i| {:name => i[:name], :flag => i[:replicateable]}}.reduce({}) {|memo, x| memo.merge({x[:name] => x[:flag]})}
20
- taps.map do |t|
21
- if t[:source_type] == :salesforce
22
- t.merge({:has_deleted_records => deleted[t[:object]]})
23
- else
24
- t.merge({:has_deleted_records => false})
25
- end
26
- end
27
- =======
28
- def self.get_box(taps)
29
- taps.find_all {|t| [:box].include?(t[:source_type]) }
30
- >>>>>>> Box init
31
- end
32
-
33
- end
34
- end
35
- end
@@ -1,229 +0,0 @@
1
- module GoodData
2
- module CloudConnect
3
- module Helpers
4
-
5
- def self.property(builder, data)
6
- builder.Property({
7
- :id => data[:id],
8
- :name => data[:name] || data[:id],
9
- :value => data[:value]
10
- })
11
- end
12
-
13
- def self.property_file(builder, data)
14
- builder.Property({
15
- :id => data[:id],
16
- :fileURL => data[:fileURL]
17
- })
18
- end
19
-
20
- <<<<<<< HEAD
21
- def self.create_deleted_records_meta(builder)
22
- builder.Metadata({:id => "deleted_records_metadata"}) do |builder|
23
- csv_metadata(builder, {
24
- :name => "deleted_records_metadata",
25
- :fields => [
26
- {:type => "string", :name => "Id"},
27
- {:type => "string", :name => "Timestamp"}
28
- =======
29
- def self.create_http_request_meta(builder)
30
- builder.Metadata({:id => "http_metadata"}) do |builder|
31
- csv_metadata(builder, {
32
- :name => "http_metadata",
33
- :fields => [
34
- {:type => "string", :name => "response"},
35
- {:type => "string", :name => "all"}
36
- >>>>>>> Box init
37
- ]
38
- })
39
- end
40
- end
41
-
42
- def self.create_trash_meta(builder)
43
- builder.Metadata({:id => "trash_metadata"}) do |builder|
44
- csv_metadata(builder, {
45
- :name => "trash_metadata",
46
- :fields => [{:type => "string", :name => "all"}]
47
- })
48
- end
49
- end
50
-
51
- def self.save_metadata(filename, data)
52
- dirname = File.dirname(filename)
53
- FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
54
-
55
- File.open(filename, "w") do |file|
56
- builder = Builder::XmlMarkup.new(:target => file, :indent=>2)
57
- builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
58
- csv_metadata(builder, data)
59
- end
60
- end
61
-
62
- def self.create_moving_graph(file, options={})
63
- source = options[:source]
64
- target = options[:target]
65
- operation = options[:operation]
66
- force = options[:force] || false
67
-
68
- File.open(file, "w") do |file|
69
- builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
70
- builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
71
- builder.Graph({
72
- :name => "File Copy"
73
- }) do
74
- builder.Global do
75
- builder.Metadata({:id => "list_metadata"}) do |builder|
76
- Helpers::csv_metadata(builder, {
77
- :name => "list_metadata",
78
- :fields => [{:name=>"filePath", :type=>"string"}]
79
- })
80
- end
81
- Helpers::property_file(builder, {:id => "workspace_params", :fileURL => "workspace.prm"})
82
- end
83
- builder.Phase(:number => 0) do
84
-
85
- transformation_source = "function integer transform() {\n" + ([["filePath", "filePath"]].map {|t| "$out.0.#{t.last} = $in.0.#{t.first};"}.join("\n")) + "\nreturn OK;\n}"
86
- Core::build_node2(builder, Nodes.file_list2(:baseURL => target, :id => "file_list", :output_mapping => transformation_source))
87
-
88
- Core::build_node2(builder, Nodes.file_delete2(:baseURL => "${filePath}", :id => "file_delete"))
89
- Core::build_node2(builder, Nodes.edge2({:toNode => "file_delete:0", :fromNode => "file_list:0", :metadata => "list_metadata"}))
90
- end
91
- builder.Phase(:number => 1) do
92
- Core::build_node2(builder, Nodes.file_copy2({:sourcePath => source, :targetPath => target, :operation => operation, :id => "file_copy"}))
93
- end
94
- end
95
- end
96
- end
97
-
98
- def self.csv_metadata(builder, description)
99
- sf_description = description.merge({
100
- :fieldDelimiter => ",",
101
- :recordDelimiter => "\\n",
102
- :type => "delimited",
103
- })
104
- metadata(builder, sf_description)
105
- end
106
-
107
- # prepares a sink for sinking into GD. This means dealing with stuff like scientific notation which is handled bu uploading as a decimal and not string
108
- def self.sink_out_gd_metadata(metadata, sink)
109
- metadata_fields = metadata[:fields]
110
- sink_facts = GoodData::Bam::Sink.get_fact_fields(sink).map {|f| f[:meta]}
111
- x = metadata_fields.map {|f| sink_facts.include?(f[:name]) ? f.merge({:type => "decimal"}) : f}
112
- GoodData::Bam::Metadata.create(metadata.merge({:fields => x}))
113
- end
114
-
115
- def self.metadata(builder, description)
116
- builder.Record({
117
- :fieldDelimiter => description[:fieldDelimiter],
118
- :name => description[:name],
119
- :recordDelimiter => description[:recordDelimiter],
120
- :type => description[:type]
121
- }) do |record|
122
- description[:fields].each do |field|
123
- builder.Field :name => field[:name], :type => field[:type] || "string", :nullable => "true"
124
- end
125
- end
126
- end
127
-
128
- def self.create_lookup_meta(builder)
129
- builder.Metadata({:id => "lookup_metadata"}) do |builder|
130
- csv_metadata(builder, {
131
- :name => "lookup_metadata",
132
- :fields => [{:type => "string", :name => "key"}, {:type => "string", :name => "value"}]
133
- })
134
- end
135
- end
136
-
137
- def self.create_file_list_meta(builder)
138
- builder.Metadata({:id => "file_list"}) do |builder|
139
- csv_metadata(builder, {
140
- :name => "file_list",
141
- :fields => [
142
- {:name => "filePath", :type => "string"},
143
- {:name => "fileName", :type => "string"}
144
- ]
145
- })
146
- end
147
- end
148
-
149
- def self.create_read_error_meta(builder)
150
- builder.Metadata({:id => "reader_error_metadata"}) do |builder|
151
- csv_metadata(builder, {
152
- :name => "reader_error_metadata",
153
- :fields => [
154
- {:name => "line_number", :type => "integer"},
155
- {:name => "field_number", :type => "integer"},
156
- {:name => "record", :type => "string"},
157
- {:name => "message", :type => "string"},
158
- {:name => "file", :type => "string"}
159
- ]
160
- })
161
- end
162
- end
163
-
164
- def self.create_run_graph_failure_metadata(builder)
165
- builder.Metadata({:id => "run_graph_failure_metadata"}) do |builder|
166
- csv_metadata(builder, {
167
- :name => "run_graph_failure_metadata",
168
- :fields => [
169
- {:type => "string", :name => "graph"},
170
- {:type => "string", :name => "result"},
171
- {:type => "string", :name => "description"},
172
- {:type => "string", :name => "message"},
173
- {:type => "decimal", :name => "duration"}
174
- ]
175
- })
176
- end
177
- end
178
-
179
- def self.create_run_graph(file, options={})
180
- subgraphs = options[:subgraphs]
181
- flow = options[:flow]
182
- File.open(file, "w") do |file|
183
- builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
184
- builder.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
185
- builder.Graph({
186
- :name => "Run graph"
187
- }) do
188
- builder.Global do
189
- property_file(builder, {:id => "workspace_params", :fileURL => "workspace.prm"})
190
- property_file(builder, {:id => "params_params", :fileURL => "params.prm"})
191
- create_trash_meta(builder)
192
- create_lookup_meta(builder)
193
-
194
- end
195
- phase = 0
196
- subgraphs.each do |subgraph|
197
- name = GoodData::Bam::Step.step_name(GoodData::Bam::Graph.create(:path => subgraph))
198
- # Pathname(subgraph).basename.to_s.chomp(Pathname(subgraph).extname)
199
- builder.Phase(:number => phase+1) do
200
- id1 = GoodData::CloudConnect::Nodes.get_id
201
- id2 = GoodData::CloudConnect::Nodes.get_id
202
- ctl = "function integer generate() {$out.0.all = \"FLOW=#{flow}\";return OK;}"
203
- Core::build_node2(builder, Nodes.data_generator2({:name => id1, :id => id1, :generate => ctl}))
204
- Core::build_node2(builder, Nodes.edge2({:toNode => "#{id2}:0", :fromNode => "#{id1}:0", :metadata => "trash_metadata"}))
205
- Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id2}", :fileURL => "params.prm", :outputFieldNames => "false", :quotedStrings => "false"}))
206
- end
207
- builder.Phase(:number => phase+2) do
208
-
209
- id1 = GoodData::CloudConnect::Nodes.get_id
210
- id2 = GoodData::CloudConnect::Nodes.get_id
211
- ctl = "function integer generate() {$out.0.all = \"NAME=#{name}\";return OK;}"
212
- Core::build_node2(builder, Nodes.data_generator2({:name => id1, :id => id1, :generate => ctl}))
213
- Core::build_node2(builder, Nodes.edge2({:toNode => "#{id2}:0", :fromNode => "#{id1}:0", :metadata => "trash_metadata"}))
214
- Core::build_node2(builder, Nodes.writer2({:name => "PARAMS CSV Writer", :id => "#{id2}", :fileURL => "params.prm", :outputFieldNames => "false", :append => "true", :quotedStrings => "false"}))
215
- end
216
-
217
- builder.Phase(:number => phase+3) do
218
- Core::build_node2(builder, Nodes.run_graph2({:guiName => name, :name => name, :id => flow, :graphName => subgraph}))
219
- end
220
- phase += 4
221
- end
222
- end
223
- end
224
- end
225
-
226
-
227
- end
228
- end
229
- end