table_sync 6.1.0 → 6.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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