db_blaster 0.1.0 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8d31a519addfa74e6a2ca3c2d41f58b05e2b4551802948b5a4dc0fe20278dca
4
- data.tar.gz: 33a1e76574a2b8e70c681beebf544af587ff143252b08d0dd1a8dbc0b3615864
3
+ metadata.gz: 9313d3abe0bd4dcaa756dab6b07b1d65eb6438b435c914d18f9d38964f08a29d
4
+ data.tar.gz: c694940facb41fb3656d011baba720ffb5f66cf124472f945d7de45661ba90b5
5
5
  SHA512:
6
- metadata.gz: 378969c9223acf49c50a055b566b1f3f2bff3a0b032bbc9e1aebbb64b5031c9d1a2af6c539d55efc7e90a8254d0ca4cf413be762ab41dbdd1fd4e01efd723d33
7
- data.tar.gz: afabd1c77490c8c80bdd1d0a49965026ae69a77d727ffe7da475c5683391dafc4cd9f91d7880ecc5c0818a4c5afeacd4403844a198f932c0c4d448b0c53cb2dc
6
+ metadata.gz: c045adce6f5a4fb70be59194f6f4630879761011be805dbed09c9be225a415a807ffe60a2b33ccf5361e49ce595b87250f8b0e67f370c29d867254928a36e41f
7
+ data.tar.gz: 4b509898ced3205b588248700a75a375ddc6c614611298f0af347ef1a45b35f4c3d1adc9ae0a70d357c56050f47a7225d454564c22a350a21cec45da0effe322
data/README.md CHANGED
@@ -2,15 +2,15 @@
2
2
  # DbBlaster
3
3
  ![Image of DB to SNS](https://lucid.app/publicSegments/view/c70feed3-2f48-46ee-8734-423474488feb/image.png)
4
4
 
5
- DbBlaster publishes changed database rows to AWS SNS. The first time `DbBlaster::PublishAllJob.perform_later` is ran,
6
- the entire database will be incrementally published to SNS. Subsequent runs will publish rows whose `updated_at` column
5
+ DbBlaster can either publish changed database rows to AWS SNS or push the changes to S#. The first time `DbBlaster::PublishAllJob.perform_later` is ran,
6
+ the entire database will be incrementally published. Subsequent runs will publish rows whose `updated_at` column
7
7
  is more recent than the last run.
8
8
 
9
9
  Consuming the published messages is functionality not provided by DbBlaster.
10
10
 
11
11
  ## Usage
12
12
 
13
- Update `config/initializers/db_blaster_config.rb` with valid AWS credentials, topics, and options.
13
+ Update `config/initializers/db_blaster_config.rb` with valid AWS credentials and options. Either `sns_topic` or `s3_bucket` must be set!
14
14
 
15
15
  Schedule `DbBlaster::PublishAllJob.perform_later` to run periodically with something
16
16
  like [sidekiq-cron](https://github.com/ondrejbartas/sidekiq-cron) or [whenever](https://github.com/javan/whenever)
@@ -13,8 +13,12 @@ module DbBlaster
13
13
  .build_all(DbBlaster.configuration))
14
14
 
15
15
  DbBlaster::SourceTable.pluck(:id).each do |source_table_id|
16
- PublishSourceTableJob.perform_later(source_table_id)
16
+ PublishSourceTableJob.perform_later(source_table_id, batch_start_time)
17
17
  end
18
18
  end
19
+
20
+ def batch_start_time
21
+ @batch_start_time ||= DateTime.now.utc.strftime(DbBlaster::Configuration::DEFAULT_DATETIME_FORMAT)
22
+ end
19
23
  end
20
24
  end
@@ -6,11 +6,11 @@ module DbBlaster
6
6
  class PublishSourceTableJob < ApplicationJob
7
7
  queue_as 'default'
8
8
 
9
- def perform(source_table_id)
9
+ def perform(source_table_id, batch_start_time)
10
10
  source_table = SourceTable.find_by(id: source_table_id)
11
11
  return unless source_table
12
12
 
13
- PublishSourceTable.execute(source_table)
13
+ PublishSourceTable.execute(source_table: source_table, batch_start_time: batch_start_time)
14
14
  end
15
15
  end
16
16
  end
@@ -3,24 +3,24 @@
3
3
  {
4
4
  "warning_type": "SQL Injection",
5
5
  "warning_code": 0,
6
- "fingerprint": "6f4d3da0707c3f5f5c5bf5a002a254fee246210248aafa655cb2f15adfb47aa7",
6
+ "fingerprint": "3fef6d99f896e29ef9346d81a1557bd3819fbc762b2aa91d44dfa25a5c095485",
7
7
  "check_name": "SQL",
8
8
  "message": "Possible SQL injection",
9
9
  "file": "lib/db_blaster/finder.rb",
10
- "line": 38,
10
+ "line": 39,
11
11
  "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
12
- "code": "ActiveRecord::Base.connection.execute(\"#{select_sql} OFFSET #{offset}\")",
12
+ "code": "ActiveRecord::Base.connection.execute(\"#{FinderSql.sql_for_source_table(source_table)} OFFSET #{offset}\")",
13
13
  "render_path": null,
14
14
  "location": {
15
15
  "type": "method",
16
16
  "class": "DbBlaster::Finder",
17
17
  "method": "find_records_in_batches"
18
18
  },
19
- "user_input": "select_sql",
19
+ "user_input": "FinderSql.sql_for_source_table(source_table)",
20
20
  "confidence": "Medium",
21
- "note": "No SQL injection can occur"
21
+ "note": "no sql injection"
22
22
  }
23
23
  ],
24
- "updated": "2021-08-09 11:03:06 -0600",
24
+ "updated": "2021-08-11 13:14:00 -0600",
25
25
  "brakeman_version": "5.1.1"
26
26
  }
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # publish records to SNS topic
4
+ module DbBlaster
5
+ # Base class for publishing
6
+ class BasePublisher
7
+ attr_reader :source_table, :records, :batch_start_time
8
+
9
+ def initialize(source_table, records, batch_start_time)
10
+ @source_table = source_table
11
+ @records = records
12
+ @batch_start_time = batch_start_time
13
+ end
14
+
15
+ def self.publish(source_table:, records:, batch_start_time:)
16
+ publisher_class =
17
+ if DbBlaster.configuration.sns_topic
18
+ SnsPublisher
19
+ else
20
+ S3Publisher
21
+ end
22
+ publisher_class.new(source_table, records, batch_start_time).publish
23
+ end
24
+
25
+ def publish
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+ end
@@ -2,17 +2,56 @@
2
2
 
3
3
  module DbBlaster
4
4
  # Configuration class for providing credentials, topics, and customizations.
5
+ # Either the `sns_topic` or `s3_bucket' must be set
5
6
  class Configuration
6
7
  DEFAULT_BATCH_SIZE = 100
7
8
  DEFAULT_MAX_MESSAGE_SIZE_IN_KILOBYTES = 256 # max size allowed by AWS SNS
9
+ DEFAULT_S3_KEY = '<batch_date>/<batch_time>/db_blaster/<table_name>/<uuid>.json'
10
+ DEFAULT_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%LZ'
8
11
 
9
12
  # The required configuration fields
10
- REQUIRED_FIELDS = %i[aws_access_key aws_access_secret aws_region sns_topic].freeze
13
+ REQUIRED_FIELDS = %i[aws_access_key aws_access_secret aws_region].freeze
14
+
15
+ # exactly one of these fields needs to be set
16
+ EITHER_OR_FIELDS = %i[sns_topic s3_bucket].freeze
11
17
 
12
18
  # The topic to which messages will be published
13
19
  attr_accessor :sns_topic
20
+ # The s3 bucket name
21
+ attr_accessor :s3_bucket
14
22
  attr_accessor :aws_access_key, :aws_access_secret, :aws_region
15
23
 
24
+ # Optional
25
+ # Applicable only when `sns_topic` is set
26
+ # Extra [SNS message_attributes](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html)
27
+ # Attributes set here will be included in every published message
28
+ # example: config.extra_sns_message_attributes = {'infra_id' => {data_type: 'String', value: '061'}}
29
+ attr_accessor :extra_sns_message_attributes
30
+
31
+ # Optional
32
+ # Applicable only when `s3_bucket' is set
33
+ # The value set here will be included in every payload pushed to S3
34
+ # example: config.s3_meta = {'infra_id' => '061', 'source_app' => 'kcp-api'}}
35
+ # The resulting JSON:
36
+ # {"meta" : {"infra_id" : "061", "src_app" : "kcp-api", "src_table" : "the-table"}, "records" : [] }
37
+ attr_accessor :s3_meta
38
+
39
+ # Optional
40
+ # Applicable only when `s3_bucket` is set
41
+ # The S3 key. The following values will get substituted:
42
+ # <batch_timestamp> - a timestamp signifying the beginning of the batch processing
43
+ # <timestamp> - the current time
44
+ # <table_name> - the name of the table associated with the S3 body
45
+ # <uuid> - a universal identifier
46
+ # '<batch_timestamp>/kcp-api/001/<table_name>/<uuid>.json'
47
+ attr_accessor :s3_key
48
+
49
+ # Optional
50
+ # Applicable only when `s3_bucket` is set
51
+ # S3 Tags
52
+ # example: config.s3_tags = { infra_id: '001', source_app: 'kcp-api', source_table: 'meetings' }
53
+ attr_accessor :s3_tags
54
+
16
55
  # Global list of column names not to include in published SNS messages
17
56
  # example: config.ignored_column_names = ['email', 'phone_number']
18
57
  attr_accessor :ignored_column_names
@@ -22,6 +61,11 @@ module DbBlaster
22
61
  # example: config.only_source_tables = ['posts', 'tags', 'comments']
23
62
  attr_accessor :only_source_tables
24
63
 
64
+ # Optional
65
+ # If set, ignore source tables specified.
66
+ # example: config.ignore_source_tables = ['active_storage_blobs']
67
+ attr_accessor :ignore_source_tables
68
+
25
69
  # Optional
26
70
  # Customize batch_size and/or ignored_columns
27
71
  # example:
@@ -29,12 +73,6 @@ module DbBlaster
29
73
  # { source_table_name: 'comments', ignored_column_names: ['tags'] }]
30
74
  attr_accessor :source_table_options
31
75
 
32
- # Optional
33
- # Extra [SNS message_attributes](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html)
34
- # Attributes set here will be included in every published message
35
- # example: config.extra_sns_message_attributes = {'infra_id' => {data_type: 'String', value: '061'}}
36
- attr_accessor :extra_sns_message_attributes
37
-
38
76
  # Optional
39
77
  # db_blaster will select and then publish `batch_size` rows at a time
40
78
  # Default value is 100
@@ -47,12 +85,22 @@ module DbBlaster
47
85
 
48
86
  # Raises error if a required field is not set
49
87
  def verify!
50
- no_values = REQUIRED_FIELDS.select do |attribute|
88
+ verify_required
89
+ verify_either_or
90
+ end
91
+
92
+ def verify_either_or
93
+ either_or = EITHER_OR_FIELDS.select do |attribute|
51
94
  send(attribute).nil? || send(attribute).strip.empty?
52
95
  end
53
- return if no_values.empty?
96
+ raise "only one of [#{either_or.join(', ')}] should be set" unless either_or.length == 1
97
+ end
54
98
 
55
- raise "missing configuration values for [#{no_values.join(', ')}]"
99
+ def verify_required
100
+ no_values = REQUIRED_FIELDS.select do |attribute|
101
+ send(attribute).nil? || send(attribute).strip.empty?
102
+ end
103
+ raise "missing configuration values for [#{no_values.join(', ')}]" unless no_values.empty?
56
104
  end
57
105
  end
58
106
  end
@@ -12,7 +12,7 @@ module DbBlaster
12
12
  @offset = 0
13
13
  end
14
14
 
15
- delegate :batch_size, :name, :last_published_updated_at, to: :source_table, prefix: true
15
+ delegate :batch_size, :name, to: :source_table, prefix: true
16
16
 
17
17
  def self.find(source_table, &block)
18
18
  new(source_table, &block).find
@@ -34,6 +34,7 @@ module DbBlaster
34
34
  private
35
35
 
36
36
  def find_records_in_batches
37
+ select_sql = FinderSql.sql_for_source_table(source_table)
37
38
  loop do
38
39
  result = ActiveRecord::Base.connection.execute("#{select_sql} OFFSET #{offset}")
39
40
  yield(result)
@@ -54,17 +55,5 @@ module DbBlaster
54
55
  def invalid_source_table_message
55
56
  "source_table.name: '#{source_table_name}' does not exist!"
56
57
  end
57
-
58
- def select_sql
59
- "SELECT * FROM #{source_table_name} #{where} ORDER BY updated_at ASC LIMIT #{source_table_batch_size}"
60
- end
61
-
62
- def where
63
- return '' unless source_table_last_published_updated_at
64
-
65
- ActiveRecord::Base.sanitize_sql_for_conditions(
66
- ['WHERE updated_at >= :updated_at', { updated_at: source_table_last_published_updated_at.to_s(:db) }]
67
- )
68
- end
69
58
  end
70
59
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DbBlaster
4
+ # Creates the SQL needed to find records for the provided source_table
5
+ class FinderSql
6
+ attr_reader :source_table
7
+
8
+ def initialize(source_table)
9
+ @source_table = source_table
10
+ end
11
+
12
+ def self.sql_for_source_table(source_table)
13
+ new(source_table).select_sql
14
+ end
15
+
16
+ def select_sql
17
+ "SELECT * FROM #{source_table.name} #{where} ORDER BY updated_at ASC LIMIT #{source_table.batch_size}"
18
+ end
19
+
20
+ def where
21
+ return '' unless from_updated_at
22
+
23
+ ActiveRecord::Base.sanitize_sql_for_conditions(
24
+ ['WHERE updated_at >= :updated_at', { updated_at: from_updated_at.to_s(:db) }]
25
+ )
26
+ end
27
+
28
+ def from_updated_at
29
+ @from_updated_at ||= source_table.last_published_updated_at
30
+ end
31
+ end
32
+ end
@@ -4,14 +4,15 @@ module DbBlaster
4
4
  # Given a `source_table` providing the table name,
5
5
  # finds rows in `batch_size` chunks that are published to SNS
6
6
  class PublishSourceTable
7
- attr_reader :source_table
7
+ attr_reader :source_table, :batch_start_time
8
8
 
9
- def initialize(source_table)
9
+ def initialize(source_table, batch_start_time)
10
10
  @source_table = source_table
11
+ @batch_start_time = batch_start_time
11
12
  end
12
13
 
13
- def self.execute(source_table)
14
- new(source_table).execute
14
+ def self.execute(source_table:, batch_start_time:)
15
+ new(source_table, batch_start_time).execute
15
16
  end
16
17
 
17
18
  def execute
@@ -20,7 +21,7 @@ module DbBlaster
20
21
  # pessimistically lock row for the duration
21
22
  source_table.with_lock do
22
23
  Finder.find(source_table) do |records|
23
- Publisher.publish(source_table, records)
24
+ BasePublisher.publish(source_table: source_table, records: records, batch_start_time: batch_start_time)
24
25
  source_table.update(last_published_updated_at: records.last['updated_at'])
25
26
  end
26
27
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DbBlaster
4
+ # Builds the key to be used for the uploaded S3 Object
5
+ class S3KeyBuilder
6
+ attr_reader :source_table_name, :batch_start_time
7
+
8
+ def initialize(source_table_name, batch_start_time)
9
+ @source_table_name = source_table_name
10
+ @batch_start_time = batch_start_time
11
+ end
12
+
13
+ def self.build(source_table_name:, batch_start_time:)
14
+ new(source_table_name, batch_start_time).build
15
+ end
16
+
17
+ def build
18
+ key = starting_key
19
+ substitutions.each do |replace, value|
20
+ key = key.gsub(replace, value)
21
+ end
22
+ key
23
+ end
24
+
25
+ def substitutions
26
+ date, time = batch_start_time.split('T')
27
+ { '<batch_date_time>' => batch_start_time,
28
+ '<batch_date>' => date,
29
+ '<batch_time>' => time,
30
+ '<uuid>' => SecureRandom.uuid,
31
+ '<table_name>' => source_table_name }
32
+ end
33
+
34
+ def starting_key
35
+ DbBlaster.configuration.s3_key.presence || Configuration::DEFAULT_S3_KEY
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-s3'
4
+
5
+ module DbBlaster
6
+ # Pushes records to S3
7
+ class S3Publisher < BasePublisher
8
+ def publish
9
+ client.put_object(bucket: DbBlaster.configuration.s3_bucket,
10
+ key: S3KeyBuilder.build(source_table_name: source_table.name,
11
+ batch_start_time: batch_start_time),
12
+ tagging: tagging,
13
+ body: content.to_json)
14
+ end
15
+
16
+ def content
17
+ { meta: meta,
18
+ records: records }
19
+ end
20
+
21
+ def tagging
22
+ URI.encode_www_form(tags_hash)
23
+ end
24
+
25
+ def tags_hash
26
+ @tags_hash ||= { source_table: source_table.name }
27
+ .merge(DbBlaster.configuration.s3_tags.presence || {})
28
+ end
29
+
30
+ def meta
31
+ (DbBlaster.configuration.s3_meta.presence || {}).merge(source_table: source_table.name)
32
+ end
33
+
34
+ def client
35
+ @client ||= Aws::S3::Client.new(region: DbBlaster.configuration.aws_region,
36
+ credentials: Aws::Credentials.new(DbBlaster.configuration.aws_access_key,
37
+ DbBlaster.configuration.aws_access_secret))
38
+ end
39
+ end
40
+ end
@@ -1,20 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # publish records to SNS topic
4
- module DbBlaster
5
- # Publishes records to AWS SNS
6
- class Publisher
7
- attr_reader :source_table, :records
8
-
9
- def initialize(source_table, records)
10
- @source_table = source_table
11
- @records = records
12
- end
3
+ require 'aws-sdk-sns'
13
4
 
14
- def self.publish(source_table, records)
15
- new(source_table, records).publish
16
- end
5
+ # frozen_string_literal: true
17
6
 
7
+ module DbBlaster
8
+ # Publishes records to AWS SNS
9
+ class SnsPublisher < BasePublisher
18
10
  def publish
19
11
  topic.publish(message_attributes: message_attributes,
20
12
  message: records.to_json)
@@ -45,11 +45,12 @@ module DbBlaster
45
45
  end
46
46
 
47
47
  def table_names_for_configuration
48
- if configuration.only_source_tables&.length&.positive?
49
- available_tables & configuration.only_source_tables
50
- else
51
- available_tables
52
- end
48
+ table_names = if configuration.only_source_tables&.length&.positive?
49
+ available_tables & configuration.only_source_tables
50
+ else
51
+ available_tables
52
+ end
53
+ table_names - (configuration.ignore_source_tables || [])
53
54
  end
54
55
  end
55
56
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DbBlaster
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.4'
5
5
  end
data/lib/db_blaster.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'aws-sdk-sns'
4
3
  require 'db_blaster/version'
5
4
  require 'db_blaster/engine'
6
5
  require 'db_blaster/one_record_too_large_error'
@@ -8,9 +7,13 @@ require 'db_blaster/available_tables'
8
7
  require 'db_blaster/configuration'
9
8
  require 'db_blaster/source_table_configuration'
10
9
  require 'db_blaster/source_table_configuration_builder'
11
- require 'db_blaster/publisher'
10
+ require 'db_blaster/base_publisher'
11
+ require 'db_blaster/s3_key_builder'
12
+ require 'db_blaster/s3_publisher'
13
+ require 'db_blaster/sns_publisher'
12
14
  require 'db_blaster/publish_source_table'
13
15
  require 'db_blaster/chunker'
16
+ require 'db_blaster/finder_sql'
14
17
  require 'db_blaster/finder'
15
18
 
16
19
  # Top-level module that serves as an entry point
@@ -1,12 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Either `sns_topic` or `s3_bucket` must be set
3
4
  DbBlaster.configure do |config|
4
- # SNS topic to receive database changes
5
+ # SNS topic to receive database changes. Either `sns_topic` or `s3_bucket` must be set
5
6
  config.sns_topic = 'the-topic'
6
7
  config.aws_access_key = 'access-key'
7
8
  config.aws_access_secret = 'secret'
8
9
  config.aws_region = 'region'
9
10
 
11
+ # Optional
12
+ # Applicable only when `sns_topic` is set
13
+ # Extra [SNS message_attributes](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html)
14
+ # Attributes set here will be included in every published message
15
+ # config.extra_sns_message_attributes = {'infra_id' => {data_type: 'String', value: '061'}}
16
+
17
+ # S3 bucket where JSON will be pushed. Either `sns_topic` or `s3_bucket` must be set
18
+ # config.s3_bucket = 'bucket-name'
19
+
20
+ # Optional
21
+ # Applicable only when `s3_bucket` is set
22
+ # The S3 key path. The following values will get substituted:
23
+ # <batch_date_time> - a timestamp signifying the beginning of the batch processing
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
27
+ # <table_name> - the name of the table associated with the S3 body
28
+ # <uuid> - a universal identifier
29
+ # config.s3_key = '<batch_timestamp>/kcp-api/001/<table_name>/<uuid>.json'
30
+
31
+ # Optional
32
+ # Applicable only when `s3_bucket' is set
33
+ # Extra meta values sent along with each payload
34
+ # example: config.s3_meta = {'infra_id' => '061'}
35
+ # The resulting JSON:
36
+ # {"meta" : {"infra_id" : "061", "source_app" : "kcp-api", "src_table" : "the-table"}, "records" : [] }
37
+ # config.s3_meta = {'infra_id' => '061'}
38
+
10
39
  # Optional
11
40
  # db_blaster will select and then publish `batch_size` rows at a time
12
41
  # config.batch_size = 100
@@ -14,12 +43,7 @@ DbBlaster.configure do |config|
14
43
  # Optional
15
44
  # db_blaster will publish no messages larger than this value
16
45
  # Default value is 256
17
- # attr_accessor :max_message_size_in_kilobytes
18
-
19
- # Optional
20
- # Extra [SNS message_attributes](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html)
21
- # Attributes set here will be included in every published message
22
- # config.extra_sns_message_attributes = {'infra_id' => {data_type: 'String', value: '061'}}
46
+ # config.max_message_size_in_kilobytes = 256
23
47
 
24
48
  # Global list of column names not to include in published SNS messages
25
49
  # example: config.ignored_column_names = ['email', 'phone_number']
@@ -29,6 +53,10 @@ DbBlaster.configure do |config|
29
53
  # If set, only publish tables specified.
30
54
  # config.only_source_tables = ['posts', 'tags', 'comments']
31
55
 
56
+ # Optional
57
+ # If set, ignore source tables specified.
58
+ # config.ignore_source_tables = ['active_storage_blobs']
59
+
32
60
  # Optional
33
61
  # Customize batch_size and/or ignored_columns
34
62
  # example:
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_blaster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.4
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-08-09 00:00:00.000000000 Z
11
+ date: 2021-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: aws-sdk-sns
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -119,14 +133,18 @@ files:
119
133
  - db/migrate/20210727222252_create_source_tables.rb
120
134
  - lib/db_blaster.rb
121
135
  - lib/db_blaster/available_tables.rb
136
+ - lib/db_blaster/base_publisher.rb
122
137
  - lib/db_blaster/chunker.rb
123
138
  - lib/db_blaster/configuration.rb
124
139
  - lib/db_blaster/engine.rb
125
140
  - lib/db_blaster/finder.rb
141
+ - lib/db_blaster/finder_sql.rb
126
142
  - lib/db_blaster/one_record_too_large_error.rb
127
143
  - lib/db_blaster/publish_source_table.rb
128
- - lib/db_blaster/publisher.rb
129
144
  - lib/db_blaster/rspec.rb
145
+ - lib/db_blaster/s3_key_builder.rb
146
+ - lib/db_blaster/s3_publisher.rb
147
+ - lib/db_blaster/sns_publisher.rb
130
148
  - lib/db_blaster/source_table_configuration.rb
131
149
  - lib/db_blaster/source_table_configuration_builder.rb
132
150
  - lib/db_blaster/version.rb