table_sync 4.2.1 → 6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +52 -0
- data/CHANGELOG.md +75 -9
- data/Gemfile.lock +159 -152
- data/README.md +4 -1
- data/docs/message_protocol.md +3 -3
- data/docs/publishing/configuration.md +143 -0
- data/docs/publishing/manual.md +155 -0
- data/docs/publishing/publishers.md +162 -0
- data/docs/publishing.md +35 -119
- data/docs/receiving.md +11 -6
- data/lib/table_sync/errors.rb +31 -22
- data/lib/table_sync/event.rb +35 -0
- data/lib/table_sync/orm_adapter/active_record.rb +25 -0
- data/lib/table_sync/orm_adapter/base.rb +92 -0
- data/lib/table_sync/orm_adapter/sequel.rb +29 -0
- data/lib/table_sync/publishing/batch.rb +53 -0
- data/lib/table_sync/publishing/data/objects.rb +50 -0
- data/lib/table_sync/publishing/data/raw.rb +27 -0
- data/lib/table_sync/publishing/helpers/attributes.rb +63 -0
- data/lib/table_sync/publishing/helpers/debounce.rb +134 -0
- data/lib/table_sync/publishing/helpers/objects.rb +39 -0
- data/lib/table_sync/publishing/message/base.rb +73 -0
- data/lib/table_sync/publishing/message/batch.rb +14 -0
- data/lib/table_sync/publishing/message/raw.rb +54 -0
- data/lib/table_sync/publishing/message/single.rb +13 -0
- data/lib/table_sync/publishing/params/base.rb +66 -0
- data/lib/table_sync/publishing/params/batch.rb +23 -0
- data/lib/table_sync/publishing/params/raw.rb +7 -0
- data/lib/table_sync/publishing/params/single.rb +31 -0
- data/lib/table_sync/publishing/raw.rb +21 -0
- data/lib/table_sync/publishing/single.rb +65 -0
- data/lib/table_sync/publishing.rb +20 -5
- data/lib/table_sync/receiving/config.rb +6 -4
- data/lib/table_sync/receiving/handler.rb +25 -9
- data/lib/table_sync/receiving/model/active_record.rb +1 -1
- data/lib/table_sync/receiving.rb +0 -2
- data/lib/table_sync/setup/active_record.rb +22 -0
- data/lib/table_sync/setup/base.rb +67 -0
- data/lib/table_sync/setup/sequel.rb +26 -0
- data/lib/table_sync/utils/interface_checker.rb +2 -2
- data/lib/table_sync/version.rb +1 -1
- data/lib/table_sync.rb +31 -8
- data/table_sync.gemspec +7 -7
- metadata +58 -37
- data/.travis.yml +0 -34
- data/lib/table_sync/publishing/base_publisher.rb +0 -114
- data/lib/table_sync/publishing/batch_publisher.rb +0 -109
- data/lib/table_sync/publishing/orm_adapter/active_record.rb +0 -32
- data/lib/table_sync/publishing/orm_adapter/sequel.rb +0 -57
- data/lib/table_sync/publishing/publisher.rb +0 -129
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Base
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attr_reader :objects
|
8
|
+
|
9
|
+
attribute :object_class
|
10
|
+
attribute :original_attributes
|
11
|
+
attribute :event
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
super(params)
|
15
|
+
|
16
|
+
@objects = find_or_init_objects
|
17
|
+
|
18
|
+
raise TableSync::NoObjectsForSyncError if objects.empty? && TableSync.raise_on_empty_message
|
19
|
+
end
|
20
|
+
|
21
|
+
def publish
|
22
|
+
return if original_attributes.blank?
|
23
|
+
|
24
|
+
Rabbit.publish(message_params)
|
25
|
+
|
26
|
+
notify!
|
27
|
+
end
|
28
|
+
|
29
|
+
def empty?
|
30
|
+
objects.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_or_init_objects
|
34
|
+
TableSync::Publishing::Helpers::Objects.new(
|
35
|
+
object_class: object_class, original_attributes: original_attributes, event: event,
|
36
|
+
).construct_list
|
37
|
+
end
|
38
|
+
|
39
|
+
# MESSAGE PARAMS
|
40
|
+
|
41
|
+
def message_params
|
42
|
+
params.merge(data: data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def data
|
46
|
+
TableSync::Publishing::Data::Objects.new(
|
47
|
+
objects: objects, event: event,
|
48
|
+
).construct
|
49
|
+
end
|
50
|
+
|
51
|
+
# :nocov:
|
52
|
+
def params
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
# :nocov:
|
56
|
+
|
57
|
+
# NOTIFY
|
58
|
+
|
59
|
+
def notify!
|
60
|
+
TableSync::Instrument.notify(
|
61
|
+
table: model_naming.table,
|
62
|
+
schema: model_naming.schema,
|
63
|
+
event: event,
|
64
|
+
direction: :publish,
|
65
|
+
count: objects.count,
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def model_naming
|
70
|
+
TableSync.publishing_adapter.model_naming(objects.first.object_class)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Batch < Base
|
5
|
+
attribute :headers
|
6
|
+
attribute :routing_key
|
7
|
+
|
8
|
+
def params
|
9
|
+
TableSync::Publishing::Params::Batch.new(
|
10
|
+
object_class: object_class, headers: headers, routing_key: routing_key,
|
11
|
+
).construct
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Message
|
4
|
+
class Raw
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
attribute :original_attributes
|
9
|
+
attribute :routing_key
|
10
|
+
attribute :headers
|
11
|
+
|
12
|
+
attribute :event
|
13
|
+
|
14
|
+
def publish
|
15
|
+
Rabbit.publish(message_params)
|
16
|
+
|
17
|
+
notify!
|
18
|
+
end
|
19
|
+
|
20
|
+
# NOTIFY
|
21
|
+
|
22
|
+
def notify!
|
23
|
+
TableSync::Instrument.notify(
|
24
|
+
table: model_naming.table,
|
25
|
+
schema: model_naming.schema,
|
26
|
+
event: event,
|
27
|
+
count: original_attributes.count,
|
28
|
+
direction: :publish,
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def model_naming
|
33
|
+
TableSync.publishing_adapter.model_naming(object_class.constantize)
|
34
|
+
end
|
35
|
+
|
36
|
+
# MESSAGE PARAMS
|
37
|
+
|
38
|
+
def message_params
|
39
|
+
params.merge(data: data)
|
40
|
+
end
|
41
|
+
|
42
|
+
def data
|
43
|
+
TableSync::Publishing::Data::Raw.new(
|
44
|
+
object_class: object_class, attributes_for_sync: original_attributes, event: event,
|
45
|
+
).construct
|
46
|
+
end
|
47
|
+
|
48
|
+
def params
|
49
|
+
TableSync::Publishing::Params::Raw.new(
|
50
|
+
object_class: object_class, routing_key: routing_key, headers: headers,
|
51
|
+
).construct
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Base
|
5
|
+
DEFAULT_PARAMS = {
|
6
|
+
confirm_select: true,
|
7
|
+
realtime: true,
|
8
|
+
event: :table_sync,
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
def construct
|
12
|
+
DEFAULT_PARAMS.merge(
|
13
|
+
routing_key: routing_key,
|
14
|
+
headers: headers,
|
15
|
+
exchange_name: exchange_name,
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def calculated_routing_key
|
22
|
+
if TableSync.routing_key_callable
|
23
|
+
TableSync.routing_key_callable.call(object_class, attributes_for_routing_key)
|
24
|
+
else
|
25
|
+
raise TableSync::NoCallableError.new("routing_key")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def calculated_headers
|
30
|
+
if TableSync.headers_callable
|
31
|
+
TableSync.headers_callable.call(object_class, attributes_for_headers)
|
32
|
+
else
|
33
|
+
raise TableSync::NoCallableError.new("headers")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# NOT IMPLEMENTED
|
38
|
+
|
39
|
+
# name of the model being synced in the string format
|
40
|
+
# :nocov:
|
41
|
+
def object_class
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
def routing_key
|
46
|
+
raise NotImplementedError
|
47
|
+
end
|
48
|
+
|
49
|
+
def headers
|
50
|
+
raise NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
def exchange_name
|
54
|
+
raise NotImplementedError
|
55
|
+
end
|
56
|
+
|
57
|
+
def attributes_for_routing_key
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
def attributes_for_headers
|
62
|
+
raise NotImplementedError
|
63
|
+
end
|
64
|
+
# :nocov:
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Batch < Base
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
|
9
|
+
attribute :exchange_name, default: -> { TableSync.exchange_name }
|
10
|
+
attribute :routing_key, default: -> { calculated_routing_key }
|
11
|
+
attribute :headers, default: -> { calculated_headers }
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def attributes_for_routing_key
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes_for_headers
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Publishing::Params
|
4
|
+
class Single < Base
|
5
|
+
attr_reader :object, :routing_key, :headers
|
6
|
+
|
7
|
+
def initialize(object:)
|
8
|
+
@object = object
|
9
|
+
@routing_key = calculated_routing_key
|
10
|
+
@headers = calculated_headers
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def object_class
|
16
|
+
object.object_class.name
|
17
|
+
end
|
18
|
+
|
19
|
+
def attributes_for_routing_key
|
20
|
+
object.attributes_for_routing_key
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes_for_headers
|
24
|
+
object.attributes_for_headers
|
25
|
+
end
|
26
|
+
|
27
|
+
def exchange_name
|
28
|
+
TableSync.exchange_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TableSync::Publishing::Raw
|
4
|
+
include Tainbox
|
5
|
+
|
6
|
+
attribute :object_class
|
7
|
+
attribute :original_attributes
|
8
|
+
|
9
|
+
attribute :routing_key
|
10
|
+
attribute :headers
|
11
|
+
|
12
|
+
attribute :event, default: :update
|
13
|
+
|
14
|
+
def publish_now
|
15
|
+
message.publish
|
16
|
+
end
|
17
|
+
|
18
|
+
def message
|
19
|
+
TableSync::Publishing::Message::Raw.new(attributes)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TableSync::Publishing::Single
|
4
|
+
include Tainbox
|
5
|
+
include Memery
|
6
|
+
|
7
|
+
attribute :object_class
|
8
|
+
attribute :original_attributes
|
9
|
+
attribute :debounce_time
|
10
|
+
|
11
|
+
attribute :event, Symbol, default: :update
|
12
|
+
|
13
|
+
# expect job to have perform_at method
|
14
|
+
# debounce destroyed event
|
15
|
+
# because otherwise update event could be sent after destroy
|
16
|
+
def publish_later
|
17
|
+
return if debounce.skip?
|
18
|
+
|
19
|
+
job.perform_at(job_attributes)
|
20
|
+
|
21
|
+
debounce.cache_next_sync_time
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish_now
|
25
|
+
message.publish unless message.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
memoize def message
|
29
|
+
TableSync::Publishing::Message::Single.new(attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
memoize def debounce
|
33
|
+
TableSync::Publishing::Helpers::Debounce.new(
|
34
|
+
object_class: object_class,
|
35
|
+
needle: message.object.needle,
|
36
|
+
debounce_time: debounce_time,
|
37
|
+
event: event,
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# JOB
|
44
|
+
|
45
|
+
def job
|
46
|
+
if TableSync.single_publishing_job_class_callable
|
47
|
+
TableSync.single_publishing_job_class_callable.call
|
48
|
+
else
|
49
|
+
raise TableSync::NoCallableError.new("single_publishing_job_class")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def job_attributes
|
54
|
+
attributes.merge(
|
55
|
+
original_attributes: serialized_original_attributes,
|
56
|
+
perform_at: debounce.next_sync_time,
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def serialized_original_attributes
|
61
|
+
TableSync::Publishing::Helpers::Attributes
|
62
|
+
.new(original_attributes)
|
63
|
+
.serialize
|
64
|
+
end
|
65
|
+
end
|
@@ -2,10 +2,25 @@
|
|
2
2
|
|
3
3
|
module TableSync
|
4
4
|
module Publishing
|
5
|
-
require_relative "publishing/
|
6
|
-
require_relative "publishing/
|
7
|
-
|
8
|
-
require_relative "publishing/
|
9
|
-
require_relative "publishing/
|
5
|
+
require_relative "publishing/data/objects"
|
6
|
+
require_relative "publishing/data/raw"
|
7
|
+
|
8
|
+
require_relative "publishing/helpers/attributes"
|
9
|
+
require_relative "publishing/helpers/debounce"
|
10
|
+
require_relative "publishing/helpers/objects"
|
11
|
+
|
12
|
+
require_relative "publishing/params/base"
|
13
|
+
require_relative "publishing/params/batch"
|
14
|
+
require_relative "publishing/params/raw"
|
15
|
+
require_relative "publishing/params/single"
|
16
|
+
|
17
|
+
require_relative "publishing/message/base"
|
18
|
+
require_relative "publishing/message/batch"
|
19
|
+
require_relative "publishing/message/raw"
|
20
|
+
require_relative "publishing/message/single"
|
21
|
+
|
22
|
+
require_relative "publishing/batch"
|
23
|
+
require_relative "publishing/raw"
|
24
|
+
require_relative "publishing/single"
|
10
25
|
end
|
11
26
|
end
|
@@ -4,20 +4,22 @@ module TableSync::Receiving
|
|
4
4
|
class Config
|
5
5
|
attr_reader :model, :events
|
6
6
|
|
7
|
-
def initialize(model:, events:
|
7
|
+
def initialize(model:, events: TableSync::Event::VALID_RESOLVED_EVENTS)
|
8
8
|
@model = model
|
9
9
|
|
10
10
|
@events = [events].flatten.map(&:to_sym)
|
11
11
|
|
12
|
-
|
13
|
-
raise TableSync::UndefinedEvent.new(events)
|
14
|
-
end
|
12
|
+
raise TableSync::UndefinedEvent.new(events) if invalid_events.any?
|
15
13
|
|
16
14
|
self.class.default_values_for_options.each do |ivar, default_value_generator|
|
17
15
|
instance_variable_set(ivar, default_value_generator.call(self))
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
19
|
+
def invalid_events
|
20
|
+
events - TableSync::Event::VALID_RESOLVED_EVENTS
|
21
|
+
end
|
22
|
+
|
21
23
|
class << self
|
22
24
|
attr_reader :default_values_for_options
|
23
25
|
|
@@ -31,7 +31,7 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
31
31
|
params[:default_values] = config.default_values(data: data)
|
32
32
|
end
|
33
33
|
|
34
|
-
config.wrap_receiving(**params) do
|
34
|
+
config.wrap_receiving(event: event, **params) do
|
35
35
|
perform(config, params)
|
36
36
|
end
|
37
37
|
end
|
@@ -44,14 +44,18 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
44
44
|
super(Array.wrap(data[:attributes]))
|
45
45
|
end
|
46
46
|
|
47
|
-
def event=(
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
def event=(event_name)
|
48
|
+
event_name = event_name.to_sym
|
49
|
+
|
50
|
+
if event_name.in?(TableSync::Event::VALID_RESOLVED_EVENTS)
|
51
|
+
super(event_name)
|
52
|
+
else
|
53
|
+
raise TableSync::UndefinedEvent.new(event)
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
|
-
def model=(
|
54
|
-
super(
|
57
|
+
def model=(model_name)
|
58
|
+
super(model_name.to_s)
|
55
59
|
end
|
56
60
|
|
57
61
|
def configs
|
@@ -82,7 +86,7 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
82
86
|
row[after] = row.delete(before)
|
83
87
|
end
|
84
88
|
|
85
|
-
config.except(row: row).each
|
89
|
+
config.except(row: row).each { |x| row.delete(x) }
|
86
90
|
|
87
91
|
row.merge!(config.additional_data(row: row))
|
88
92
|
|
@@ -98,7 +102,8 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
98
102
|
|
99
103
|
def validate_data(data, target_keys:)
|
100
104
|
data.each do |row|
|
101
|
-
next if target_keys.all?
|
105
|
+
next if target_keys.all? { |x| row.key?(x) }
|
106
|
+
|
102
107
|
raise TableSync::DataError.new(
|
103
108
|
data, target_keys, "Some target keys not found in received attributes!"
|
104
109
|
)
|
@@ -107,6 +112,17 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
107
112
|
if data.uniq { |row| row.slice(*target_keys) }.size != data.size
|
108
113
|
raise TableSync::DataError.new(data, target_keys, "Duplicate rows found!")
|
109
114
|
end
|
115
|
+
|
116
|
+
keys_sample = data[0].keys
|
117
|
+
keys_diff = data.each_with_object(Set.new) do |row, set|
|
118
|
+
(row.keys - keys_sample | keys_sample - row.keys).each { |x| set.add(x) }
|
119
|
+
end
|
120
|
+
|
121
|
+
unless keys_diff.empty?
|
122
|
+
raise TableSync::DataError.new(data, target_keys, <<~MESSAGE)
|
123
|
+
Bad batch structure, check keys: #{keys_diff.to_a}
|
124
|
+
MESSAGE
|
125
|
+
end
|
110
126
|
end
|
111
127
|
|
112
128
|
def perform(config, params)
|
@@ -96,7 +96,7 @@ module TableSync::Receiving::Model
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
result = query.destroy_all.map(
|
99
|
+
result = query.destroy_all.map { |x| row_to_hash(x) }
|
100
100
|
|
101
101
|
if result.size > data.size
|
102
102
|
raise TableSync::DestroyError.new(data: data, target_keys: target_keys, result: result)
|
data/lib/table_sync/receiving.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Setup
|
4
|
+
class ActiveRecord < Base
|
5
|
+
private
|
6
|
+
|
7
|
+
def define_after_commit(event)
|
8
|
+
options = options_exposed_for_block
|
9
|
+
|
10
|
+
object_class.after_commit(on: event) do
|
11
|
+
if instance_eval(&options[:if]) && !instance_eval(&options[:unless])
|
12
|
+
TableSync::Publishing::Single.new(
|
13
|
+
object_class: self.class.name,
|
14
|
+
original_attributes: attributes,
|
15
|
+
event: event,
|
16
|
+
debounce_time: options[:debounce_time],
|
17
|
+
).publish_later
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Setup
|
4
|
+
class Base
|
5
|
+
include Tainbox
|
6
|
+
|
7
|
+
EVENTS = %i[create update destroy].freeze
|
8
|
+
INVALID_EVENT = Class.new(StandardError)
|
9
|
+
INVALID_CONDITION = Class.new(StandardError)
|
10
|
+
|
11
|
+
attribute :object_class
|
12
|
+
attribute :debounce_time
|
13
|
+
attribute :on
|
14
|
+
attribute :if_condition
|
15
|
+
attribute :unless_condition
|
16
|
+
|
17
|
+
def initialize(attrs)
|
18
|
+
super(attrs)
|
19
|
+
|
20
|
+
self.on = Array.wrap(on).map(&:to_sym)
|
21
|
+
|
22
|
+
self.if_condition ||= proc { true }
|
23
|
+
self.unless_condition ||= proc { false }
|
24
|
+
|
25
|
+
raise INVALID_EVENTS unless valid_events?
|
26
|
+
raise INVALID_CONDITION unless valid_conditions?
|
27
|
+
end
|
28
|
+
|
29
|
+
def register_callbacks
|
30
|
+
applicable_events.each { |event| define_after_commit(event) }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# VALIDATION
|
36
|
+
|
37
|
+
def valid_events?
|
38
|
+
on.all? { |event| event.in?(EVENTS) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid_conditions?
|
42
|
+
if_condition.is_a?(Proc) && unless_condition.is_a?(Proc)
|
43
|
+
end
|
44
|
+
|
45
|
+
# EVENTS
|
46
|
+
|
47
|
+
def applicable_events
|
48
|
+
on.presence || EVENTS
|
49
|
+
end
|
50
|
+
|
51
|
+
# CREATING HOOKS
|
52
|
+
|
53
|
+
# :nocov:
|
54
|
+
def define_after_commit(event)
|
55
|
+
raise NotImplementedError
|
56
|
+
end
|
57
|
+
# :nocov:
|
58
|
+
|
59
|
+
def options_exposed_for_block
|
60
|
+
{
|
61
|
+
if: if_condition,
|
62
|
+
unless: unless_condition,
|
63
|
+
debounce_time: debounce_time,
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module TableSync::Setup
|
4
|
+
class Sequel < Base
|
5
|
+
private
|
6
|
+
|
7
|
+
def define_after_commit(event)
|
8
|
+
options = options_exposed_for_block
|
9
|
+
|
10
|
+
object_class.define_method("after_#{event}".to_sym) do
|
11
|
+
if instance_eval(&options[:if]) && !instance_eval(&options[:unless])
|
12
|
+
db.after_commit do
|
13
|
+
TableSync::Publishing::Single.new(
|
14
|
+
object_class: self.class.name,
|
15
|
+
original_attributes: values,
|
16
|
+
event: event,
|
17
|
+
debounce_time: options[:debounce_time],
|
18
|
+
).publish_later
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
super()
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -54,8 +54,8 @@ class TableSync::Utils::InterfaceChecker
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def filter(parameters)
|
57
|
-
# for req and block parameters types we can ignore names
|
58
|
-
parameters.map { |param|
|
57
|
+
ignored_keys = %i[req block] # for req and block parameters types we can ignore names
|
58
|
+
parameters.map { |param| ignored_keys.include?(param.first) ? [param.first] : param }
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
data/lib/table_sync/version.rb
CHANGED