table_sync 6.1.0 → 6.6.1

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.
@@ -124,7 +124,11 @@ module TableSync::Publishing::Helpers
124
124
  end
125
125
 
126
126
  def cache_next_sync_time
127
- Rails.cache.write(cache_key, next_sync_time)
127
+ Rails.cache.write(
128
+ cache_key,
129
+ next_sync_time,
130
+ expires_at: next_sync_time + debounce_time.seconds,
131
+ )
128
132
  end
129
133
 
130
134
  def cache_key
@@ -6,6 +6,7 @@ module TableSync::Publishing::Message
6
6
 
7
7
  attr_reader :objects
8
8
 
9
+ attribute :custom_version
9
10
  attribute :object_class
10
11
  attribute :original_attributes
11
12
  attribute :event
@@ -32,19 +33,21 @@ module TableSync::Publishing::Message
32
33
 
33
34
  def find_or_init_objects
34
35
  TableSync::Publishing::Helpers::Objects.new(
35
- object_class: object_class, original_attributes: original_attributes, event: event,
36
+ object_class:, original_attributes:, event:,
36
37
  ).construct_list
37
38
  end
38
39
 
39
40
  # MESSAGE PARAMS
40
41
 
41
42
  def message_params
42
- params.merge(data: data)
43
+ params.merge(data:)
43
44
  end
44
45
 
45
46
  def data
46
47
  TableSync::Publishing::Data::Objects.new(
47
- objects: objects, event: event,
48
+ objects:,
49
+ event:,
50
+ custom_version:,
48
51
  ).construct
49
52
  end
50
53
 
@@ -60,7 +63,7 @@ module TableSync::Publishing::Message
60
63
  TableSync::Instrument.notify(
61
64
  table: model_naming.table,
62
65
  schema: model_naming.schema,
63
- event: event,
66
+ event:,
64
67
  direction: :publish,
65
68
  count: objects.count,
66
69
  )
@@ -11,7 +11,7 @@ module TableSync::Publishing::Message
11
11
 
12
12
  attribute :routing_key
13
13
  attribute :headers
14
-
14
+ attribute :custom_version
15
15
  attribute :event
16
16
 
17
17
  def publish
@@ -26,7 +26,7 @@ module TableSync::Publishing::Message
26
26
  TableSync::Instrument.notify(
27
27
  table: table_name,
28
28
  schema: schema_name,
29
- event: event,
29
+ event:,
30
30
  count: original_attributes.count,
31
31
  direction: :publish,
32
32
  )
@@ -35,12 +35,15 @@ module TableSync::Publishing::Message
35
35
  # MESSAGE PARAMS
36
36
 
37
37
  def message_params
38
- params.merge(data: data)
38
+ params.merge(data:)
39
39
  end
40
40
 
41
41
  def data
42
42
  TableSync::Publishing::Data::Raw.new(
43
- model_name: model_name, attributes_for_sync: original_attributes, event: event,
43
+ model_name:,
44
+ attributes_for_sync: original_attributes,
45
+ event:,
46
+ custom_version:,
44
47
  ).construct
45
48
  end
46
49
 
@@ -7,7 +7,7 @@ module TableSync::Publishing::Message
7
7
  end
8
8
 
9
9
  def params
10
- TableSync::Publishing::Params::Single.new(object: object).construct
10
+ TableSync::Publishing::Params::Single.new(object:).construct
11
11
  end
12
12
  end
13
13
  end
@@ -10,9 +10,9 @@ module TableSync::Publishing::Params
10
10
 
11
11
  def construct
12
12
  DEFAULT_PARAMS.merge(
13
- routing_key: routing_key,
14
- headers: headers,
15
- exchange_name: exchange_name,
13
+ routing_key:,
14
+ headers:,
15
+ exchange_name:,
16
16
  )
17
17
  end
18
18
 
@@ -2,17 +2,20 @@
2
2
 
3
3
  class TableSync::Publishing::Raw
4
4
  include Tainbox
5
+ include TableSync::Utils::RequiredValidator
5
6
 
6
7
  attribute :model_name
7
8
  attribute :table_name
8
9
  attribute :schema_name
9
10
  attribute :original_attributes
10
-
11
+ attribute :custom_version
11
12
  attribute :routing_key
12
13
  attribute :headers
13
14
 
14
15
  attribute :event, default: :update
15
16
 
17
+ require_attributes :model_name, :original_attributes
18
+
16
19
  def publish_now
17
20
  message.publish
18
21
  end
@@ -7,7 +7,7 @@ class TableSync::Publishing::Single
7
7
  attribute :object_class
8
8
  attribute :original_attributes
9
9
  attribute :debounce_time
10
-
10
+ attribute :custom_version
11
11
  attribute :event, Symbol, default: :update
12
12
 
13
13
  # expect job to have perform_at method
@@ -31,10 +31,10 @@ class TableSync::Publishing::Single
31
31
 
32
32
  memoize def debounce
33
33
  TableSync::Publishing::Helpers::Debounce.new(
34
- object_class: object_class,
34
+ object_class:,
35
35
  needle: message.object.needle,
36
- debounce_time: debounce_time,
37
- event: event,
36
+ debounce_time:,
37
+ event:,
38
38
  )
39
39
  end
40
40
 
@@ -10,18 +10,18 @@ module TableSync::Receiving
10
10
  @config = config
11
11
 
12
12
  @default_params = {
13
- event: event,
14
- model: model,
15
- version: version,
16
- project_id: project_id,
17
- raw_data: raw_data,
13
+ event:,
14
+ model:,
15
+ version:,
16
+ project_id:,
17
+ raw_data:,
18
18
  }
19
19
  end
20
20
  # rubocop:enable Metrics/ParameterLists
21
21
 
22
- def method_missing(name, **additional_params, &block)
22
+ def method_missing(name, **additional_params, &)
23
23
  value = @config.send(name)
24
- value.is_a?(Proc) ? value.call(@default_params.merge(additional_params), &block) : value
24
+ value.is_a?(Proc) ? value.call(@default_params.merge(additional_params), &) : value
25
25
  end
26
26
  end
27
27
  end
@@ -16,7 +16,7 @@ module TableSync::Receiving
16
16
 
17
17
  TableSync::Utils::InterfaceChecker.new(model).implements(:receiving_model)
18
18
 
19
- config = ::TableSync::Receiving::Config.new(model: model, events: events)
19
+ config = ::TableSync::Receiving::Config.new(model:, events:)
20
20
 
21
21
  config.instance_exec(&block) if block
22
22
 
@@ -16,22 +16,22 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
16
16
 
17
17
  next if data.empty?
18
18
 
19
- version_key = config.version_key(data: data)
19
+ version_key = config.version_key(data:)
20
20
  data.each { |row| row[version_key] = version }
21
21
 
22
- target_keys = config.target_keys(data: data)
22
+ target_keys = config.target_keys(data:)
23
23
 
24
- validate_data(data, target_keys: target_keys)
24
+ validate_data(data, target_keys:)
25
25
 
26
- data.sort_by! { |row| row.values_at(*target_keys).to_s }
26
+ data.sort_by! { |row| row.values_at(*target_keys).map { |value| sort_key(value) } }
27
27
 
28
- params = { data: data, target_keys: target_keys, version_key: version_key }
28
+ params = { data:, target_keys:, version_key: }
29
29
 
30
30
  if event == :update
31
- params[:default_values] = config.default_values(data: data)
31
+ params[:default_values] = config.default_values(data:)
32
32
  end
33
33
 
34
- config.wrap_receiving(event: event, **params) do
34
+ config.wrap_receiving(event:, **params) do
35
35
  perform(config, params)
36
36
  end
37
37
  end
@@ -64,12 +64,12 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
64
64
  configs = configs.sort_by { |config| "#{config.model.schema}.#{config.model.table}" }
65
65
  configs.map do |config|
66
66
  ::TableSync::Receiving::ConfigDecorator.new(
67
- config: config,
67
+ config:,
68
68
  # next parameters will be send to each proc-options from config
69
- event: event,
70
- model: model,
71
- version: version,
72
- project_id: project_id,
69
+ event:,
70
+ model:,
71
+ version:,
72
+ project_id:,
73
73
  raw_data: data,
74
74
  )
75
75
  end
@@ -78,22 +78,22 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
78
78
 
79
79
  def processed_data(config)
80
80
  data.filter_map do |row|
81
- next if config.skip(row: row)
81
+ next if config.skip(row:)
82
82
 
83
83
  row = row.dup
84
84
 
85
- config.mapping_overrides(row: row).each do |before, after|
85
+ config.mapping_overrides(row:).each do |before, after|
86
86
  row[after] = row.delete(before)
87
87
  end
88
88
 
89
- config.except(row: row).each { |x| row.delete(x) }
89
+ config.except(row:).each { |x| row.delete(x) }
90
90
 
91
- row.merge!(config.additional_data(row: row))
91
+ row.merge!(config.additional_data(row:))
92
92
 
93
- only = config.only(row: row)
93
+ only = config.only(row:)
94
94
  row, rest = row.partition { |key, _| key.in?(only) }.map(&:to_h)
95
95
 
96
- rest_key = config.rest_key(row: row, rest: rest)
96
+ rest_key = config.rest_key(row:, rest:)
97
97
  (row[rest_key] ||= {}).merge!(rest) if rest_key
98
98
 
99
99
  row
@@ -139,14 +139,18 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
139
139
 
140
140
  model.after_commit do
141
141
  TableSync::Instrument.notify table: model.table, schema: model.schema,
142
- count: results.count, event: event, direction: :receive
142
+ count: results.count, event:, direction: :receive
143
143
  end
144
144
 
145
145
  if event == :update
146
- model.after_commit { config.after_commit_on_update(**params.merge(results: results)) }
146
+ model.after_commit { config.after_commit_on_update(**params.merge(results:)) }
147
147
  else
148
- model.after_commit { config.after_commit_on_destroy(**params.merge(results: results)) }
148
+ model.after_commit { config.after_commit_on_destroy(**params.merge(results:)) }
149
149
  end
150
150
  end
151
151
  end
152
+
153
+ def sort_key(value)
154
+ value.is_a?(Comparable) ? value : value.to_s
155
+ end
152
156
  end
@@ -26,7 +26,7 @@ module TableSync::Receiving::Model
26
26
  self.inheritance_column = nil
27
27
  end
28
28
 
29
- model_naming = ::TableSync::NamingResolver::ActiveRecord.new(table_name: table_name)
29
+ model_naming = ::TableSync::NamingResolver::ActiveRecord.new(table_name:)
30
30
 
31
31
  @table = model_naming.table.to_sym
32
32
  @schema = model_naming.schema.to_sym
@@ -66,7 +66,7 @@ module TableSync::Receiving::Model
66
66
  row = raw_model.lock("FOR NO KEY UPDATE").where(conditions)
67
67
 
68
68
  if row.to_a.size > 1
69
- raise TableSync::UpsertError.new(data: datum, target_keys: target_keys, result: row)
69
+ raise TableSync::UpsertError.new(data: datum, target_keys:, result: row)
70
70
  end
71
71
 
72
72
  row = row.first
@@ -99,18 +99,18 @@ module TableSync::Receiving::Model
99
99
  result = query.destroy_all.map { |x| row_to_hash(x) }
100
100
 
101
101
  if result.size > data.size
102
- raise TableSync::DestroyError.new(data: data, target_keys: target_keys, result: result)
102
+ raise TableSync::DestroyError.new(data:, target_keys:, result:)
103
103
  end
104
104
 
105
105
  result
106
106
  end
107
107
 
108
- def transaction(&block)
109
- ::ActiveRecord::Base.transaction(&block)
108
+ def transaction(&)
109
+ ::ActiveRecord::Base.transaction(&)
110
110
  end
111
111
 
112
- def after_commit(&block)
113
- db.add_transaction_record(AfterCommitWrap.new(&block))
112
+ def after_commit(&)
113
+ db.add_transaction_record(AfterCommitWrap.new(&))
114
114
  end
115
115
 
116
116
  private
@@ -8,7 +8,7 @@ module TableSync::Receiving::Model
8
8
  @raw_model = Class.new(::Sequel::Model(table_name)).tap(&:unrestrict_primary_key)
9
9
 
10
10
  model_naming = ::TableSync::NamingResolver::Sequel.new(
11
- table_name: table_name,
11
+ table_name:,
12
12
  db: @raw_model.db,
13
13
  )
14
14
 
@@ -46,18 +46,18 @@ module TableSync::Receiving::Model
46
46
  result = dataset.returning.where(::Sequel.|(*sanitized_data)).delete
47
47
 
48
48
  if result.size > data.size
49
- raise TableSync::DestroyError.new(data: data, target_keys: target_keys, result: result)
49
+ raise TableSync::DestroyError.new(data:, target_keys:, result:)
50
50
  end
51
51
 
52
52
  result
53
53
  end
54
54
 
55
- def transaction(&block)
56
- db.transaction(&block)
55
+ def transaction(&)
56
+ db.transaction(&)
57
57
  end
58
58
 
59
- def after_commit(&block)
60
- db.after_commit(&block)
59
+ def after_commit(&)
60
+ db.after_commit(&)
61
61
  end
62
62
 
63
63
  private
@@ -14,7 +14,7 @@ module TableSync::Setup
14
14
  TableSync::Publishing::Single.new(
15
15
  object_class: self.class.name,
16
16
  original_attributes: attributes,
17
- event: event,
17
+ event:,
18
18
  debounce_time: options[:debounce_time],
19
19
  ).publish_later
20
20
  end
@@ -60,7 +60,7 @@ module TableSync::Setup
60
60
  {
61
61
  if: if_condition,
62
62
  unless: unless_condition,
63
- debounce_time: debounce_time,
63
+ debounce_time:,
64
64
  }
65
65
  end
66
66
  end
@@ -13,7 +13,7 @@ module TableSync::Setup
13
13
  TableSync::Publishing::Single.new(
14
14
  object_class: self.class.name,
15
15
  original_attributes: values,
16
- event: event,
16
+ event:,
17
17
  debounce_time: options[:debounce_time],
18
18
  ).publish_later
19
19
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TableSync::Utils::ProcArray < Proc
4
- def initialize(&block)
4
+ def initialize(&)
5
5
  @array = []
6
- super(&block)
6
+ super(&)
7
7
  end
8
8
 
9
9
  def push(&block)
@@ -11,7 +11,7 @@ class TableSync::Utils::ProcArray < Proc
11
11
  self
12
12
  end
13
13
 
14
- def call(*args, &block)
15
- super(@array, args, &block)
14
+ def call(*args, &)
15
+ super(@array, args, &)
16
16
  end
17
17
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableSync::Utils::RequiredValidator
4
+ module PrependedInitialization
5
+ def initialize(*)
6
+ super
7
+
8
+ not_filled_attrs = calculate_not_filled_attributes
9
+ if not_filled_attrs.present?
10
+ raise(
11
+ ArgumentError,
12
+ "Some of required attributes is not provided: #{not_filled_attrs.inspect}",
13
+ )
14
+ end
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ def require_attributes(*attributes)
20
+ _required_attributes.push(*attributes)
21
+ end
22
+
23
+ def _required_attributes
24
+ @_required_attributes ||= []
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+ private
30
+
31
+ def calculate_not_filled_attributes
32
+ attributes
33
+ .select { |key, value| key.in?(self.class._required_attributes) && value.nil? }
34
+ .keys
35
+ end
36
+ end
37
+
38
+ def self.included(klass)
39
+ klass.prepend(PrependedInitialization)
40
+ klass.extend(ClassMethods)
41
+ klass.include(InstanceMethods)
42
+ end
43
+ end
@@ -5,5 +5,6 @@ module TableSync
5
5
  require_relative "utils/proc_array"
6
6
  require_relative "utils/proc_keywords_resolver"
7
7
  require_relative "utils/interface_checker"
8
+ require_relative "utils/required_validator"
8
9
  end
9
10
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableSync
4
- VERSION = "6.1.0"
4
+ VERSION = "6.6.1"
5
5
  end
data/lib/table_sync.rb CHANGED
@@ -47,7 +47,7 @@ module TableSync
47
47
 
48
48
  def sync(object_class, **options)
49
49
  setup.new(
50
- object_class: object_class,
50
+ object_class:,
51
51
  on: options[:on],
52
52
  if_condition: options[:if],
53
53
  unless_condition: options[:unless],
data/table_sync.gemspec CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "table_sync/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.required_ruby_version = ">= 2.7.0"
8
+ spec.required_ruby_version = ">= 3.1.0"
9
9
 
10
10
  spec.name = "table_sync"
11
11
  spec.version = TableSync::VERSION
@@ -27,23 +27,7 @@ Gem::Specification.new do |spec|
27
27
  end
28
28
 
29
29
  spec.add_runtime_dependency "memery"
30
- spec.add_runtime_dependency "rabbit_messaging"
30
+ spec.add_runtime_dependency "rabbit_messaging", ">= 1.1.0"
31
31
  spec.add_runtime_dependency "rails"
32
32
  spec.add_runtime_dependency "self_data"
33
-
34
- spec.add_development_dependency "rspec"
35
- spec.add_development_dependency "rubocop-config-umbrellio"
36
- spec.add_development_dependency "simplecov"
37
- spec.add_development_dependency "simplecov-lcov"
38
-
39
- spec.add_development_dependency "activejob"
40
- spec.add_development_dependency "activerecord"
41
- spec.add_development_dependency "pg"
42
- spec.add_development_dependency "sequel"
43
- spec.add_development_dependency "timecop"
44
-
45
- spec.add_development_dependency "bundler"
46
- spec.add_development_dependency "bundler-audit"
47
- spec.add_development_dependency "pry"
48
- spec.add_development_dependency "rake"
49
33
  end