db_blaster 0.1.5 → 0.1.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2de00cf222282fde0e0a3e38078ccc398a80ff19c41ccf7b79ecd043450db6b1
4
- data.tar.gz: 66b93222044a44bcd7dd35a6233de5c4839a58d5106e527a7d540be2daee9821
3
+ metadata.gz: 7e58f97f7c15cb1bb2d1bf1d4235e68e5d256adaf48f72481cb3c754f1d85aae
4
+ data.tar.gz: ffa443a609d6d2b10b7e7e3b65bdc45da8abfc8485b7f3fb46fa638ea1b0cd98
5
5
  SHA512:
6
- metadata.gz: 7305baf42dff923be85d8105625bf3ccf8200988d7895c80202a32232b062a9c613863a002a7b8e57d7e57a3660725ab4ed6765d2b2d3ba49f3b216da2614dac
7
- data.tar.gz: 8652430ce86f2ee275997ec35e52bf2ba99befa4c3a8630b13e0ca57f309d4b0fb013974806e52882bc37bd95a6c4e9e9d4ea51fa5a2096d2767df0d3608b796
6
+ metadata.gz: fd27fea13565a8f90a3d0b4db4fcac631453fc9579b35f5ad7e4061e7f4cc7bea01e12307efd5a865583f781cb793ceb50f6646708912edcef8742b5a3551f53
7
+ data.tar.gz: ca998517216be98f3c3d47d9e0f393aa230dd04a08cf54a0dfeb1fb734246f7e1d388c00b698b92eab7bded131addded3ffc413b9d029e1aa2f5ac3aadf78928
@@ -9,8 +9,7 @@ module DbBlaster
9
9
  queue_as 'default'
10
10
 
11
11
  def perform
12
- SourceTable.sync(SourceTableConfigurationBuilder
13
- .build_all(DbBlaster.configuration))
12
+ SyncSourceTablesWithConfiguration.sync
14
13
 
15
14
  DbBlaster::SourceTable.pluck(:id).each do |source_table_id|
16
15
  PublishSourceTableJob.perform_later(source_table_id, batch_start_time)
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adding last_published_id to avoid dupes in selecting sourcetables
4
+ class AddLastPublishedId < ActiveRecord::Migration[6.1]
5
+ def change
6
+ add_column :db_blaster_source_tables, :last_published_id, :string, default: '0'
7
+ end
8
+ end
@@ -8,6 +8,8 @@ module DbBlaster
8
8
  DEFAULT_MAX_MESSAGE_SIZE_IN_KILOBYTES = 256 # max size allowed by AWS SNS
9
9
  DEFAULT_S3_KEY = '<batch_date>/<batch_time>/db_blaster/<table_name>/<uuid>.json'
10
10
  DEFAULT_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%LZ'
11
+ ATTRIBUTE_S3_META_FORMAT = 'attribute' # { meta: {your: :value}, records: [] }
12
+ INLINE_S3_META_FORMAT = 'inline' # records.collect{|record| record.merge(meta) }
11
13
 
12
14
  # The required configuration fields
13
15
  REQUIRED_FIELDS = %i[aws_access_key aws_access_secret aws_region].freeze
@@ -32,14 +34,22 @@ module DbBlaster
32
34
  # Applicable only when `s3_bucket' is set
33
35
  # The value set here will be included in every payload pushed to S3
34
36
  # example: config.s3_meta = {'infra_id' => '061', 'source_app' => 'kcp-api'}}
35
- # The resulting JSON will include the `meta` merged into every record
36
37
  attr_accessor :s3_meta
37
38
 
39
+ # Optional
40
+ # Options: ['attribute', 'inline']
41
+ # Defaults to 'attribute'
42
+ # 'attribute' payload: { meta: `s3_meta`, records: [source_table_records] }
43
+ # 'inline' payload: records.collect{|record| record.merge(meta) }
44
+ attr_accessor :s3_meta_format
45
+
38
46
  # Optional
39
47
  # Applicable only when `s3_bucket` is set
40
48
  # The S3 key. The following values will get substituted:
41
- # <batch_timestamp> - a timestamp signifying the beginning of the batch processing
42
- # <timestamp> - the current time
49
+ # <batch_date_time> - date time when batch started
50
+ # <batch_date> - date when batch started
51
+ # <batch_time - time when batch started
52
+ # <date_time> - the datetime just before pushing to S3
43
53
  # <table_name> - the name of the table associated with the S3 body
44
54
  # <uuid> - a universal identifier
45
55
  # '<batch_timestamp>/kcp-api/001/<table_name>/<uuid>.json'
@@ -17,16 +17,26 @@ module DbBlaster
17
17
  "SELECT * FROM #{source_table.name} #{where} ORDER BY updated_at ASC LIMIT #{source_table.batch_size}"
18
18
  end
19
19
 
20
+ # if we just use updated_at > from_updated_at, it's possible to miss records
21
+ # that share the same `updated_at`
22
+ # if we use updated_at >= from_updated_at, we'll get redundant records on every run
23
+ # settled on the approach below
20
24
  def where
21
25
  return '' unless from_updated_at
22
26
 
23
27
  ActiveRecord::Base.sanitize_sql_for_conditions(
24
- ['WHERE updated_at >= :updated_at', { updated_at: from_updated_at.to_s(:db) }]
28
+ ['WHERE updated_at > :updated_at OR (updated_at = :updated_at AND id <> :updated_id)',
29
+ { updated_at: from_updated_at,
30
+ updated_id: last_published_id }]
25
31
  )
26
32
  end
27
33
 
28
34
  def from_updated_at
29
35
  @from_updated_at ||= source_table.last_published_updated_at
30
36
  end
37
+
38
+ def last_published_id
39
+ @last_published_id ||= source_table.last_published_id
40
+ end
31
41
  end
32
42
  end
@@ -22,7 +22,8 @@ module DbBlaster
22
22
  source_table.with_lock do
23
23
  Finder.find(source_table) do |records|
24
24
  BasePublisher.publish(source_table: source_table, records: records, batch_start_time: batch_start_time)
25
- source_table.update(last_published_updated_at: records.last['updated_at'])
25
+ source_table.update(last_published_updated_at: records.last['updated_at'],
26
+ last_published_id: records.last['id'])
26
27
  end
27
28
  end
28
29
  self
@@ -23,10 +23,12 @@ module DbBlaster
23
23
  end
24
24
 
25
25
  def substitutions
26
+ date_time = DateTime.now.utc.strftime(DbBlaster::Configuration::DEFAULT_DATETIME_FORMAT)
26
27
  date, time = batch_start_time.split('T')
27
28
  { '<batch_date_time>' => batch_start_time,
28
29
  '<batch_date>' => date,
29
30
  '<batch_time>' => time,
31
+ '<date_time>' => date_time,
30
32
  '<uuid>' => SecureRandom.uuid,
31
33
  '<table_name>' => source_table_name }
32
34
  end
@@ -14,7 +14,10 @@ module DbBlaster
14
14
  end
15
15
 
16
16
  def content
17
- meta_records
17
+ return meta_records if DbBlaster.configuration.s3_meta_format == Configuration::INLINE_S3_META_FORMAT
18
+
19
+ { meta: meta,
20
+ records: records }
18
21
  end
19
22
 
20
23
  def tagging
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DbBlaster
4
+ # Builds an array of tables and their columns
5
+ class SourceTablesSchemaBuilder
6
+ def self.build_schema
7
+ new.build_schema
8
+ end
9
+
10
+ def build_schema
11
+ SyncSourceTablesWithConfiguration.sync
12
+
13
+ DbBlaster::SourceTable.all.each_with_object({}) do |source_table, hash|
14
+ hash[source_table.name] = build_columns_from_source_table(source_table)
15
+ end
16
+ end
17
+
18
+ def build_columns_from_source_table(source_table)
19
+ ActiveRecord::Base.connection.columns(source_table.name).collect do |column|
20
+ next if source_table.ignored_columns.include?(column.name)
21
+
22
+ { name: column.name,
23
+ type: column.type,
24
+ limit: column.limit }
25
+ end.compact
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DbBlaster
4
+ # Update the db-blaster source tables based on provided configuration
5
+ module SyncSourceTablesWithConfiguration
6
+ def self.sync
7
+ SourceTable.sync(SourceTableConfigurationBuilder
8
+ .build_all(DbBlaster.configuration))
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DbBlaster
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.9'
5
5
  end
data/lib/db_blaster.rb CHANGED
@@ -15,6 +15,8 @@ require 'db_blaster/publish_source_table'
15
15
  require 'db_blaster/chunker'
16
16
  require 'db_blaster/finder_sql'
17
17
  require 'db_blaster/finder'
18
+ require 'db_blaster/source_tables_schema_builder'
19
+ require 'db_blaster/sync_source_tables_with_configuration'
18
20
 
19
21
  # Top-level module that serves as an entry point
20
22
  # into the engine gem
@@ -22,8 +22,7 @@ DbBlaster.configure do |config|
22
22
  # The S3 key path. The following values will get substituted:
23
23
  # <batch_date_time> - a timestamp signifying the beginning of the batch processing
24
24
  # <batch_date> - a date signifying the beginning of the batch processing
25
- # <batch_time> - a time signifying the beginning of the batch processing
26
- # <timestamp> - the current time
25
+ # <date_time> - the datetime just before pushing to S3
27
26
  # <table_name> - the name of the table associated with the S3 body
28
27
  # <uuid> - a universal identifier
29
28
  # config.s3_key = '<batch_timestamp>/kcp-api/001/<table_name>/<uuid>.json'
@@ -1,5 +1,14 @@
1
1
  # frozen_string_literal: true
2
- # desc "Explaining what the task does"
3
- # task :db_blaster do
4
- # # Task goes here
5
- # end
2
+
3
+ require 'db_blaster'
4
+
5
+ namespace :db_blaster do
6
+ desc 'generate table schema'
7
+ task generate_table_schema: :environment do
8
+ schema_name = 'kcp-api-schema.json'
9
+ puts "Generating #{schema_name}......."
10
+ built = DbBlaster::SourceTablesSchemaBuilder.build_schema
11
+ File.open(schema_name, 'w') { |f| f << built.to_json }
12
+ puts 'Success!'
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_blaster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Perry Hertler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-02 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -131,6 +131,7 @@ files:
131
131
  - config/brakeman.ignore
132
132
  - config/routes.rb
133
133
  - db/migrate/20210727222252_create_source_tables.rb
134
+ - db/migrate/20210908214439_add_last_published_id.rb
134
135
  - lib/db_blaster.rb
135
136
  - lib/db_blaster/available_tables.rb
136
137
  - lib/db_blaster/base_publisher.rb
@@ -147,6 +148,8 @@ files:
147
148
  - lib/db_blaster/sns_publisher.rb
148
149
  - lib/db_blaster/source_table_configuration.rb
149
150
  - lib/db_blaster/source_table_configuration_builder.rb
151
+ - lib/db_blaster/source_tables_schema_builder.rb
152
+ - lib/db_blaster/sync_source_tables_with_configuration.rb
150
153
  - lib/db_blaster/version.rb
151
154
  - lib/generators/db_blaster/install/install_generator.rb
152
155
  - lib/generators/db_blaster/install/templates/db_blaster_config.rb