gd_bam 0.1.28 → 0.1.29

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.
data/lib/bam/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bam
2
- VERSION = '0.1.28'
2
+ VERSION = '0.1.29'
3
3
  end
data/lib/base/graph.rb CHANGED
@@ -16,7 +16,6 @@ module GoodData
16
16
  })
17
17
  else
18
18
  # it is a URI
19
- # binding.pry
20
19
  {
21
20
  :inputs => [],
22
21
  :outputs => []
data/lib/base/project.rb CHANGED
@@ -81,6 +81,12 @@ module GoodData
81
81
  Project.create(project.merge({:sinks => sinks}))
82
82
  end
83
83
 
84
+ def self.mark_deleted_taps(project, options)
85
+ taps = project[:taps]
86
+ enriched_taps = Taps.get_deleted_records_info(taps, GoodData::Bam::Commands.get_sf_client(options))
87
+ Project.create(project.merge({:taps => enriched_taps}))
88
+ end
89
+
84
90
  def self.load_flows_definitions(project, path)
85
91
  p = Pathname(path)
86
92
  flows = Pathname.glob(p + "*.rb").map do |p|
@@ -96,6 +102,7 @@ module GoodData
96
102
  p = Project.load_taps(project, home + 'taps')
97
103
  p = Project.load_sinks(p, home + 'sinks')
98
104
  p = Project.set_graph_repos(p, paths)
105
+ p = Project.mark_deleted_taps(p, options)
99
106
  p = Project.load_flows_definitions(p, home + "flows")
100
107
  p = Compiler.compile_dsl(p)
101
108
  end
data/lib/base/tap.rb CHANGED
@@ -161,7 +161,9 @@ module GoodData
161
161
  def self.prepare_for_es_downloader(tap)
162
162
  tap = Tap.pull_id_from_output_to_input(tap)
163
163
  tap = Tap.remove_timestamp_field(Tap.pull_timestamp_from_output_to_input(tap))
164
- tap[:snapshots] == true ? Tap.add_field(tap, {:name => "Snapshot"}) : tap
164
+ tap = tap[:snapshots] == true ? Tap.add_field(tap, {:name => "Snapshot"}) : tap
165
+ tap = tap[:has_deleted_records] == true ? Tap.add_field(tap, {:name => "IsDeleted"}) : tap
166
+ tap = tap[:has_deleted_records] == true ? Tap.add_field(tap, {:name => "DeletedAt"}) : tap
165
167
  end
166
168
 
167
169
  def self.prepare_for_s3_backup(tap)
data/lib/base/taps.rb CHANGED
@@ -14,6 +14,17 @@ module GoodData
14
14
  taps.find_all {|t| [:web, :file].include?(t[:source_type]) }
15
15
  end
16
16
 
17
+ def self.get_deleted_records_info(taps, client)
18
+ deleted = client.modules.map {|i| {:name => i[:name], :flag => i[:replicateable]}}.reduce({}) {|memo, x| memo.merge({x[:name] => x[:flag]})}
19
+ taps.map do |t|
20
+ if t[:source_type] == :salesforce
21
+ t.merge({:has_deleted_records => deleted[t[:object]]})
22
+ else
23
+ t.merge({:has_deleted_records => false})
24
+ end
25
+ end
26
+ end
27
+
17
28
  end
18
29
  end
19
30
  end
@@ -17,6 +17,18 @@ module GoodData
17
17
  })
18
18
  end
19
19
 
20
+ def self.create_deleted_records_meta(builder)
21
+ builder.Metadata({:id => "deleted_records_metadata"}) do |builder|
22
+ csv_metadata(builder, {
23
+ :name => "deleted_records_metadata",
24
+ :fields => [
25
+ {:type => "string", :name => "Id"},
26
+ {:type => "string", :name => "Timestamp"}
27
+ ]
28
+ })
29
+ end
30
+ end
31
+
20
32
  def self.create_trash_meta(builder)
21
33
  builder.Metadata({:id => "trash_metadata"}) do |builder|
22
34
  csv_metadata(builder, {
@@ -8,6 +8,7 @@ module GoodData
8
8
  DEDUP = "DEDUP"
9
9
  READER = "DATA_READER"
10
10
  SF_READER = "SF_READER"
11
+ SF_DELETED_READER = "SF_DELETED_READER"
11
12
  REFORMAT = "REFORMAT"
12
13
  FILE_BACKUP = "FILE_BACKUP"
13
14
  PERSISTENT_LOOKUP = "persistentLookup"
@@ -189,7 +190,23 @@ HEREDOC
189
190
  :required => []
190
191
  })
191
192
  end
192
-
193
+
194
+
195
+ def self.sfdc_deleted_records(data, options={})
196
+ local_defaults = {
197
+ :type => SF_DELETED_READER,
198
+ :retryDelay => 100,
199
+ :startDateTime => "`date2str(dateadd(today(), -20, day), \"yyyy-MM-dd'T'00:00:00.000'Z'\")`"
200
+ }
201
+ defaults = local_defaults.merge(options[:defaults] || {})
202
+
203
+ base_node(defaults.merge(data), {
204
+ :allowed => [:entity, :sfdcConnection],
205
+ :defaults => defaults,
206
+ :required => [:entity, :sfdcConnection, :startDateTime]
207
+ })
208
+ end
209
+
193
210
 
194
211
  def self.sfdc_reader2(data, options={})
195
212
  local_defaults = {
@@ -55,7 +55,7 @@ long ten_mins_ago = now - (60 * 10) ;
55
55
 
56
56
  function integer transform(integer idx) {
57
57
  if (last_run == null) {
58
- last_run = $in.0.value;
58
+ last_run = jodaDate2str(jodaStr2date($in.0.value, ["yyyy-MM-dd'T'HH:mm:ss.SSSZZ"], 'en_US', 'UTC', 'UTC'), "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", "en_US", 'UTC');
59
59
  last_run_ts = date2long(jodaStr2date(last_run, ["yyyy-MM-dd'T'HH:mm:ss.SSSZZ"], 'en_US', 'UTC', 'UTC'));
60
60
  }
61
61
 
@@ -203,6 +203,18 @@ HEREDOC
203
203
  Helpers::property_file(builder, {:id => "workspace_params", :fileURL => "workspace.prm"})
204
204
 
205
205
  Helpers::create_lookup_meta(builder)
206
+ Helpers::create_deleted_records_meta(builder)
207
+ builder.Metadata({:id => "reformat_deleted_records"}) do |builder|
208
+ Helpers::csv_metadata(builder, {
209
+ :name => "reformat_deleted_records",
210
+ :fields => [
211
+ {:type => "string", :name => "Id"},
212
+ {:type => "date", :name => "Timestamp"},
213
+ {:type => "string", :name => "DeletedAt"},
214
+ {:type => "string", :name => "IsDeleted"}]
215
+ })
216
+ end
217
+
206
218
  taps.each do |tap|
207
219
  module_name = tap[:object]
208
220
  file = tap[:id] || module_name
@@ -246,10 +258,52 @@ HEREDOC
246
258
  timestamp_field = Tap.find_output_field(tap, "Timestamp")
247
259
  id_field = Tap.find_output_field(tap, "Id")
248
260
  tap = Tap.prepare_for_sf_downloader(tap)
261
+ deleted_records_tap = Tap.create({
262
+ :source => "salesforce",
263
+ :object => module_name,
264
+ :id => dataset,
265
+ :fields => [
266
+ {:name => "Id"},
267
+ {:name => "Timestamp"},
268
+ {:name => "DeletedAt"},
269
+ {:name => "IsDeleted"}]
270
+ })
271
+
272
+ if tap[:has_deleted_records]
273
+ # binding.pry
274
+ builder.Phase(:number => phase += 1) do
275
+ ctl = "function integer generate() {$out.0.Id = \"GD_FAKE_DELETED_RECORD\";$out.0.Timestamp = $out.0.Timestamp = str2date(\"2038-01-01T00:00:00.000+0000\", \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\");$out.0.IsDeleted = \"true\";$out.0.DeletedAt = \"2038-01-01T00:00:00.000+0000\";return OK;}"
276
+ Core::build_node2(builder, Nodes.data_generator2({:name => "#{file}_fake_deleted_records_generator", :id => "#{file}_fake_deleted_records_generator", :generate => ctl}))
277
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_fake_deleted_records_es:0", :fromNode => "#{file}_fake_deleted_records_generator:0", :metadata => "reformat_deleted_records"}))
278
+ Core::build_node2(builder, Nodes.es_writer2({:name => "#{file} es Writer", :id => "#{file}_fake_deleted_records_es", :store => store, :entityFieldsMapping => Helpers::create_es_write_json(deleted_records_tap).to_json}))
279
+ end
280
+ end
281
+
249
282
  builder.Phase(:number => phase += 1) do
250
283
  Core::build_node2(builder, Nodes.es_truncate2({:guiName => dataset, :store => store, :entity => dataset, :timestamp => "${#{dataset}_TRUNCATE_DATE}", :name => "#{module_name} es truncate", :id => "#{module_name}_es_truncate"}))
251
284
  end
252
285
 
286
+ if tap[:has_deleted_records]
287
+ builder.Phase(:number => phase += 1) do
288
+ Core::build_node2(builder, Nodes.sfdc_deleted_records({
289
+ :sfdcConnection => "SFDC",
290
+ :entity => module_name,
291
+ :id => "#{file}_deleted_records_downlader",
292
+ :startDateTime => "`iif((${GRAPH_STARTED_TIMESTAMP} - 3600 * 20 * 24 * 1000) > date2long(str2date(replace(\"${#{dataset}_START}\", \"\\\\+00:00\", \"\+0000\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\")), date2str(long2date(${GRAPH_STARTED_TIMESTAMP} - 20 * 3600 * 24 * 1000), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"), date2str(str2date(replace(\"${#{dataset}_START}\", \"\\\\+00:00\", \"\+0000\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"))`",
293
+ :endDateTime => "${#{dataset}_END}"
294
+ # "`str2date(replace(\"${#{dataset}_END}\", \"\\\\+00:00\", \"\+0900\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"))`"
295
+ }))
296
+
297
+ es_transformation_source = "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Timestamp = str2date($in.0.Timestamp,\"joda:yyyy-MM-dd'T'HH:mm:ss.SSSZZ\");\n$out.0.DeletedAt = jodaDate2str(jodaStr2date($in.0.Timestamp, [\"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"], 'en_US', 'UTC', 'UTC'), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\", \"en_US\", 'UTC');\n$out.0.IsDeleted = \"true\";\nreturn OK;\n}"
298
+ Core::build_node2(builder, Nodes.reformat2({:name => "#{file} Reformat", :id => "#{file}_deleted_records_reformat", :transformation => es_transformation_source}))
299
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_reformat:0", :fromNode => "#{file}_deleted_records_downlader:0", :metadata => "deleted_records_metadata"}))
300
+ Core::build_node2(builder, Nodes.sort2({:sortKey => "Timestamp(a)",:name => "#{file} es Sort", :id => "#{file}_deleted_records_es_sort"}))
301
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_es_sort:0", :fromNode => "#{file}_deleted_records_reformat:0", :metadata => "reformat_deleted_records"}))
302
+ Core::build_node2(builder, Nodes.es_writer2({:name => "#{file} es Writer", :id => "#{file}_deleted_records_es", :store => store, :entityFieldsMapping => Helpers::create_es_write_json(deleted_records_tap).to_json}))
303
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_es:0", :fromNode => "#{file}_deleted_records_es_sort:0", :metadata => "reformat_deleted_records"}))
304
+ end
305
+ end
306
+
253
307
  builder.Phase(:number => phase += 1) do
254
308
  fields = tap[:fields]
255
309
  mapping = "{\"xmlFieldsMapping\":{\"xmlFields\":["
@@ -340,6 +394,18 @@ HEREDOC
340
394
  Helpers::property_file(builder, {:id => "params_params", :fileURL => "params.prm"})
341
395
  Helpers::property_file(builder, {:id => "workspace_params", :fileURL => "workspace.prm"})
342
396
 
397
+ Helpers::create_deleted_records_meta(builder)
398
+ builder.Metadata({:id => "reformat_deleted_records"}) do |builder|
399
+ Helpers::csv_metadata(builder, {
400
+ :name => "reformat_deleted_records",
401
+ :fields => [
402
+ {:type => "string", :name => "Id"},
403
+ {:type => "date", :name => "Timestamp"},
404
+ {:type => "string", :name => "DeletedAt"},
405
+ {:type => "string", :name => "IsDeleted"}]
406
+ })
407
+ end
408
+
343
409
  Helpers::create_lookup_meta(builder)
344
410
  builder.Metadata({:id => "data_metadata"}) do |builder|
345
411
  Helpers::csv_metadata(builder, {:name => "data_metadata",:fields => [{:name => "Id"}, {:name => "Timestamp"}, {:name => "Value"}]})
@@ -509,7 +575,43 @@ HEREDOC
509
575
  end
510
576
  end
511
577
  end
512
- taps_with_history.each do |tap|
578
+
579
+ taps_with_history.uniq_by {|x| x[:id]}.each do |tap|
580
+
581
+ # Download the Deleted records for these taps. since we will not have a chance to download them later
582
+
583
+ if tap[:has_deleted_records]
584
+ module_name = tap[:object]
585
+ dataset = file = tap[:id]
586
+ builder.Phase(:number => phase += 1) do
587
+ Core::build_node2(builder, Nodes.sfdc_deleted_records({
588
+ :sfdcConnection => "SFDC",
589
+ :entity => module_name,
590
+ :id => "#{file}_deleted_records_downlader",
591
+ :startDateTime => "`iif((${GRAPH_STARTED_TIMESTAMP} - 3600 * 20 * 24 * 1000) > date2long(str2date(replace(\"${#{dataset}_START}\", \"\\\\+00:00\", \"\+0000\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\")), date2str(long2date(${GRAPH_STARTED_TIMESTAMP} - 20 * 3600 * 24 * 1000), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"), date2str(str2date(replace(\"${#{dataset}_START}\", \"\\\\+00:00\", \"\+0000\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"))`",
592
+ :endDateTime => "${#{dataset}_END}"
593
+ # "`str2date(replace(\"${#{dataset}_END}\", \"\\\\+00:00\", \"\+0900\"), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"))`"
594
+ }))
595
+ deleted_records_tap = Tap.create({
596
+ :source => "salesforce",
597
+ :object => module_name,
598
+ :id => dataset,
599
+ :fields => [
600
+ {:name => "Id"},
601
+ {:name => "Timestamp"},
602
+ {:name => "DeletedAt"},
603
+ {:name => "IsDeleted"}]
604
+ })
605
+ es_transformation_source = "function integer transform() {\n$out.0.* = $in.0.*;\n$out.0.Timestamp = str2date($in.0.Timestamp,\"joda:yyyy-MM-dd'T'HH:mm:ss.SSSZZ\");\n$out.0.DeletedAt = jodaDate2str(jodaStr2date($in.0.Timestamp, [\"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\"], 'en_US', 'UTC', 'UTC'), \"yyyy-MM-dd'T'HH:mm:ss.SSSZZ\", \"en_US\", 'UTC');\n$out.0.IsDeleted = \"true\";\nreturn OK;\n}"
606
+ Core::build_node2(builder, Nodes.reformat2({:name => "#{file} Reformat", :id => "#{file}_deleted_records_reformat", :transformation => es_transformation_source}))
607
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_reformat:0", :fromNode => "#{file}_deleted_records_downlader:0", :metadata => "deleted_records_metadata"}))
608
+ Core::build_node2(builder, Nodes.sort2({:sortKey => "Timestamp(a)",:name => "#{file} es Sort", :id => "#{file}_deleted_records_es_sort"}))
609
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_es_sort:0", :fromNode => "#{file}_deleted_records_reformat:0", :metadata => "reformat_deleted_records"}))
610
+ Core::build_node2(builder, Nodes.es_writer2({:name => "#{file} es Writer", :id => "#{file}_deleted_records_es", :store => store, :entityFieldsMapping => Helpers::create_es_write_json(deleted_records_tap).to_json}))
611
+ Core::build_node2(builder, Nodes.edge2({:toNode => "#{file}_deleted_records_es:0", :fromNode => "#{file}_deleted_records_es_sort:0", :metadata => "reformat_deleted_records"}))
612
+ end
613
+ end
614
+
513
615
  # puts "#{tap[:id]}_LAST_RUN"
514
616
  builder.Phase(:number => phase += 1) do
515
617
  generate_func = <<HEREDOC
@@ -221,7 +221,7 @@ HEREDOC
221
221
  }) do
222
222
  builder.Global do
223
223
 
224
- builder.Metadata({:id => "clover_metadata"}) do |builder|
224
+ builder.Metadata({:id => "clover_metadata"}) do |builder|
225
225
  Helpers::csv_metadata(builder, Metadata.get_target_metadata(tap))
226
226
  end
227
227
 
@@ -311,9 +311,17 @@ HEREDOC
311
311
  end
312
312
  Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "reformat", :transformation => transformation_source}))
313
313
  Core::build_node2(builder, Nodes.edge2({:toNode => "reformat:0", :fromNode => "es:0", :metadata => "es_metadata"}))
314
+ if tap[:has_deleted_records] == true
315
+ filter_deleted_function = "function integer transform() {\nif ($in.0.IsDeleted == \"true\") {return SKIP;} else {$out.0.* = $in.0.*; return OK;};\n}"
316
+ Core::build_node2(builder, Nodes.reformat2({:name => "Reformat", :id => "filter_deleted", :transformation => filter_deleted_function}))
317
+ 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"}))
319
+ else
320
+ Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
321
+ end
314
322
 
315
323
  Core::build_node2(builder, Nodes.copy2({:name => "Copy", :id => "copy"}))
316
- Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
324
+ # Core::build_node2(builder, Nodes.edge2({:toNode => "copy:0", :fromNode => "reformat:0", :metadata => "output_metadata"}))
317
325
  Core::build_node2(builder, Nodes.writer2({:name => "CSV Writer", :id => "csv", :fileURL => "${PROJECT}/data/#{tap[:id]}.csv", :outputFieldNames => "true", :makeDirs => "true"}))
318
326
  Core::build_node2(builder, Nodes.edge2({:toNode => "csv:0", :fromNode => "copy:0", :metadata => "output_metadata"}))
319
327
  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.28
4
+ version: 0.1.29
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-09-05 00:00:00.000000000 Z
12
+ date: 2013-09-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake