table_sync 2.3.0 → 4.2.0
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 +4 -4
- data/.rubocop.yml +21 -0
- data/CHANGELOG.md +57 -0
- data/Gemfile.lock +85 -80
- data/README.md +4 -2
- data/docs/message_protocol.md +24 -0
- data/docs/notifications.md +45 -0
- data/docs/publishing.md +147 -0
- data/docs/receiving.md +341 -0
- data/lib/table_sync.rb +16 -31
- data/lib/table_sync/errors.rb +39 -23
- data/lib/table_sync/publishing.rb +11 -0
- data/lib/table_sync/{base_publisher.rb → publishing/base_publisher.rb} +1 -1
- data/lib/table_sync/{batch_publisher.rb → publishing/batch_publisher.rb} +4 -4
- data/lib/table_sync/{orm_adapter → publishing/orm_adapter}/active_record.rb +3 -7
- data/lib/table_sync/{orm_adapter → publishing/orm_adapter}/sequel.rb +2 -6
- data/lib/table_sync/{publisher.rb → publishing/publisher.rb} +4 -4
- data/lib/table_sync/receiving.rb +14 -0
- data/lib/table_sync/receiving/config.rb +218 -0
- data/lib/table_sync/receiving/config_decorator.rb +27 -0
- data/lib/table_sync/receiving/dsl.rb +28 -0
- data/lib/table_sync/receiving/handler.rb +136 -0
- data/lib/table_sync/{model → receiving/model}/active_record.rb +43 -36
- data/lib/table_sync/receiving/model/sequel.rb +83 -0
- data/lib/table_sync/utils.rb +9 -0
- data/lib/table_sync/utils/interface_checker.rb +103 -0
- data/lib/table_sync/utils/proc_array.rb +17 -0
- data/lib/table_sync/utils/proc_keywords_resolver.rb +46 -0
- data/lib/table_sync/version.rb +1 -1
- data/table_sync.gemspec +2 -1
- metadata +45 -33
- data/docs/development.md +0 -43
- data/docs/synopsis.md +0 -336
- data/lib/table_sync/config.rb +0 -105
- data/lib/table_sync/config/callback_registry.rb +0 -53
- data/lib/table_sync/config_decorator.rb +0 -38
- data/lib/table_sync/dsl.rb +0 -25
- data/lib/table_sync/event_actions.rb +0 -96
- data/lib/table_sync/event_actions/data_wrapper.rb +0 -7
- data/lib/table_sync/event_actions/data_wrapper/base.rb +0 -23
- data/lib/table_sync/event_actions/data_wrapper/destroy.rb +0 -19
- data/lib/table_sync/event_actions/data_wrapper/update.rb +0 -21
- data/lib/table_sync/model/sequel.rb +0 -88
- data/lib/table_sync/plugins.rb +0 -72
- data/lib/table_sync/plugins/abstract.rb +0 -55
- data/lib/table_sync/plugins/access_mixin.rb +0 -49
- data/lib/table_sync/plugins/registry.rb +0 -153
- data/lib/table_sync/receiving_handler.rb +0 -76
data/lib/table_sync/plugins.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# @api public
|
4
|
-
# @since 2.2.0
|
5
|
-
module TableSync::Plugins
|
6
|
-
require_relative "plugins/registry"
|
7
|
-
require_relative "plugins/access_mixin"
|
8
|
-
require_relative "plugins/abstract"
|
9
|
-
|
10
|
-
# @since 2.2.0
|
11
|
-
@plugin_registry = Registry.new
|
12
|
-
# @since 2.2.0
|
13
|
-
@access_lock = Mutex.new
|
14
|
-
|
15
|
-
class << self
|
16
|
-
# @param plugin_name [Symbol, String]
|
17
|
-
# @return [void]
|
18
|
-
#
|
19
|
-
# @api public
|
20
|
-
# @since 2.2.0
|
21
|
-
def load(plugin_name)
|
22
|
-
thread_safe { plugin_registry[plugin_name].load! }
|
23
|
-
end
|
24
|
-
|
25
|
-
# @return [Array<String>]
|
26
|
-
#
|
27
|
-
# @api public
|
28
|
-
# @since 2.2.0
|
29
|
-
def loaded_plugins
|
30
|
-
thread_safe { plugin_registry.loaded.keys }
|
31
|
-
end
|
32
|
-
|
33
|
-
# @return [Array<String>]
|
34
|
-
#
|
35
|
-
# @api public
|
36
|
-
# @since 2.2.0
|
37
|
-
def names
|
38
|
-
thread_safe { plugin_registry.names }
|
39
|
-
end
|
40
|
-
|
41
|
-
# @param plugin_name [Symbol, String]
|
42
|
-
# @return [void]
|
43
|
-
#
|
44
|
-
# @api private
|
45
|
-
# @since 2.2.0
|
46
|
-
def register_plugin(plugin_name, plugin_module)
|
47
|
-
thread_safe { plugin_registry[plugin_name] = plugin_module }
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
# @return [TableSync::Plugins::Registry]
|
53
|
-
#
|
54
|
-
# @api private
|
55
|
-
# @since 2.2.0
|
56
|
-
attr_reader :plugin_registry
|
57
|
-
|
58
|
-
# @return [Mutex]
|
59
|
-
#
|
60
|
-
# @api private
|
61
|
-
# @since 2.2.0
|
62
|
-
attr_reader :access_lock
|
63
|
-
|
64
|
-
# @return [void]
|
65
|
-
#
|
66
|
-
# @api private
|
67
|
-
# @since 2.2.0
|
68
|
-
def thread_safe
|
69
|
-
access_lock.synchronize { yield if block_given? }
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# @api private
|
4
|
-
# @since 2.2.0
|
5
|
-
class TableSync::Plugins::Abstract
|
6
|
-
class << self
|
7
|
-
# @param child_klass [Class]
|
8
|
-
# @return [void]
|
9
|
-
#
|
10
|
-
# @api private
|
11
|
-
# @since 2.2.0
|
12
|
-
def inherited(child_klass)
|
13
|
-
child_klass.instance_variable_set(:@__loaded__, false)
|
14
|
-
child_klass.instance_variable_set(:@__lock__, Mutex.new)
|
15
|
-
super
|
16
|
-
end
|
17
|
-
|
18
|
-
# @return [void]
|
19
|
-
#
|
20
|
-
# @api private
|
21
|
-
# @since 2.2.0
|
22
|
-
def load!
|
23
|
-
__thread_safe__ do
|
24
|
-
unless @__loaded__
|
25
|
-
@__loaded__ = true
|
26
|
-
install!
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# @return [Boolean]
|
32
|
-
#
|
33
|
-
# @api private
|
34
|
-
# @since 2.2.0
|
35
|
-
def loaded?
|
36
|
-
__thread_safe__ { @__loaded__ }
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
# @return [void]
|
42
|
-
#
|
43
|
-
# @api private
|
44
|
-
# @since 2.2.0
|
45
|
-
def install!; end
|
46
|
-
|
47
|
-
# @return [Any]
|
48
|
-
#
|
49
|
-
# @api private
|
50
|
-
# @since 2.2.0
|
51
|
-
def __thread_safe__
|
52
|
-
@__lock__.synchronize { yield }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# @api private
|
4
|
-
# @since 2.2.0
|
5
|
-
module TableSync::Plugins::AccessMixin
|
6
|
-
# @param plugin_name [Symbol, String]
|
7
|
-
# @return [void]
|
8
|
-
#
|
9
|
-
# @see TableSync::Plugins
|
10
|
-
#
|
11
|
-
# @api public
|
12
|
-
# @since 2.2.0
|
13
|
-
def plugin(plugin_name)
|
14
|
-
TableSync::Plugins.load(plugin_name)
|
15
|
-
end
|
16
|
-
alias_method :enable, :plugin
|
17
|
-
alias_method :load, :plugin
|
18
|
-
|
19
|
-
# @return [Array<String>]
|
20
|
-
#
|
21
|
-
# @see TableSync::Plugins
|
22
|
-
#
|
23
|
-
# @api public
|
24
|
-
# @since 2.2.0
|
25
|
-
def plugins
|
26
|
-
TableSync::Plugins.names
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [Hash<String,Class<TableSync::Plugins::Abstract>>]
|
30
|
-
#
|
31
|
-
# @api private
|
32
|
-
# @since 2.2.0
|
33
|
-
def loaded_plugins
|
34
|
-
TableSync::Plugins.loaded_plugins
|
35
|
-
end
|
36
|
-
alias_method :enabled_plugins, :loaded_plugins
|
37
|
-
|
38
|
-
# @param plugin_name [String, Symbol]
|
39
|
-
# @param plugin_klass [Class<TableSync::Plugins::Abstract>]
|
40
|
-
# @return [void]
|
41
|
-
#
|
42
|
-
# @see TableSync::Plugins
|
43
|
-
#
|
44
|
-
# @api public
|
45
|
-
# @since 2.2.0
|
46
|
-
def register_plugin(plugin_name, plugin_klass)
|
47
|
-
TableSync::Plugins.register_plugin(plugin_name, plugin_klass)
|
48
|
-
end
|
49
|
-
end
|
@@ -1,153 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# @api private
|
4
|
-
# @since 2.2.0
|
5
|
-
class TableSync::Plugins::Registry
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
# @return [void]
|
9
|
-
#
|
10
|
-
# @api private
|
11
|
-
# @since 2.2.0
|
12
|
-
def initialize
|
13
|
-
@plugin_set = {}
|
14
|
-
@access_lock = Mutex.new
|
15
|
-
end
|
16
|
-
|
17
|
-
# @param plugin_name [Symbol, String]
|
18
|
-
# @return [TableSync::Plugins::Abstract]
|
19
|
-
#
|
20
|
-
# @api private
|
21
|
-
# @since 2.2.0
|
22
|
-
def [](plugin_name)
|
23
|
-
thread_safe { fetch(plugin_name) }
|
24
|
-
end
|
25
|
-
|
26
|
-
# @param plugin_name [Symbol, String]
|
27
|
-
# @param plugin_module [TableSync::Plugins::Abstract]
|
28
|
-
# @return [void]
|
29
|
-
#
|
30
|
-
# @api private
|
31
|
-
# @since 2.2.0
|
32
|
-
def register(plugin_name, plugin_module)
|
33
|
-
thread_safe { apply(plugin_name, plugin_module) }
|
34
|
-
end
|
35
|
-
alias_method :[]=, :register
|
36
|
-
|
37
|
-
# @return [Array<String>]
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
# @since 2.2.0
|
41
|
-
def names
|
42
|
-
thread_safe { plugin_names }
|
43
|
-
end
|
44
|
-
|
45
|
-
# @return [Hash<String,Class<TableSync::Plugins::Abstract>>]
|
46
|
-
#
|
47
|
-
# @api private
|
48
|
-
# @since 2.2.0
|
49
|
-
def loaded
|
50
|
-
thread_safe { loaded_plugins }
|
51
|
-
end
|
52
|
-
|
53
|
-
# @param block [Block]
|
54
|
-
# @return [Enumerable]
|
55
|
-
#
|
56
|
-
# @api private
|
57
|
-
# @since 2.2.0
|
58
|
-
def each(&block)
|
59
|
-
thread_safe { iterate(&block) }
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
# @return [Hash]
|
65
|
-
#
|
66
|
-
# @api private
|
67
|
-
# @since 2.2.0
|
68
|
-
attr_reader :plugin_set
|
69
|
-
|
70
|
-
# @return [Mutex]
|
71
|
-
#
|
72
|
-
# @api private
|
73
|
-
# @since 2.2.0
|
74
|
-
attr_reader :access_lock
|
75
|
-
|
76
|
-
# @return [void]
|
77
|
-
#
|
78
|
-
# @api private
|
79
|
-
# @since 2.2.0
|
80
|
-
def thread_safe
|
81
|
-
access_lock.synchronize { yield if block_given? }
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [Array<String>]
|
85
|
-
#
|
86
|
-
# @api private
|
87
|
-
# @since 2.2.0
|
88
|
-
def plugin_names
|
89
|
-
plugin_set.keys
|
90
|
-
end
|
91
|
-
|
92
|
-
# @param block [Block]
|
93
|
-
# @return [Enumerable]
|
94
|
-
#
|
95
|
-
# @api private
|
96
|
-
# @since 2.2.0
|
97
|
-
def iterate(&block)
|
98
|
-
block_given? ? plugin_set.each_pair(&block) : plugin_set.each_pair
|
99
|
-
end
|
100
|
-
|
101
|
-
# @param plugin_name [String]
|
102
|
-
# @return [Boolean]
|
103
|
-
#
|
104
|
-
# @api private
|
105
|
-
# @since 2.2.0
|
106
|
-
def registered?(plugin_name)
|
107
|
-
plugin_set.key?(plugin_name)
|
108
|
-
end
|
109
|
-
|
110
|
-
# @return [Array<TableSync::Plugins::Abstract>]
|
111
|
-
#
|
112
|
-
# @api private
|
113
|
-
# @since 2.2.0
|
114
|
-
def loaded_plugins
|
115
|
-
plugin_set.select { |_plugin_name, plugin_module| plugin_module.loaded? }
|
116
|
-
end
|
117
|
-
|
118
|
-
# @param plugin_name [Symbol, String]
|
119
|
-
# @param plugin_module [TableSync::Plugins::Abstract]
|
120
|
-
# @return [void]
|
121
|
-
#
|
122
|
-
# @raise [TableSync::AlreadyRegisteredPluginError]
|
123
|
-
#
|
124
|
-
# @api private
|
125
|
-
# @since 2.2.0
|
126
|
-
def apply(plugin_name, plugin_module)
|
127
|
-
plugin_name = indifferently_accessible_plugin_name(plugin_name)
|
128
|
-
raise(TableSync::AlreadyRegisteredPluginError.new(plugin_name)) if registered?(plugin_name)
|
129
|
-
plugin_set[plugin_name] = plugin_module
|
130
|
-
end
|
131
|
-
|
132
|
-
# @param plugin_name [Symbol, String]
|
133
|
-
# @return [TableSync::Plugins::Abstract]
|
134
|
-
#
|
135
|
-
# @raise [TableSync::UnregisteredPluginError]
|
136
|
-
#
|
137
|
-
# @api private
|
138
|
-
# @since 2.2.0
|
139
|
-
def fetch(plugin_name)
|
140
|
-
plugin_name = indifferently_accessible_plugin_name(plugin_name)
|
141
|
-
raise(TableSync::UnregisteredPluginError.new(plugin_name)) unless registered?(plugin_name)
|
142
|
-
plugin_set[plugin_name]
|
143
|
-
end
|
144
|
-
|
145
|
-
# @param key [Symbol, String]
|
146
|
-
# @return [String]
|
147
|
-
#
|
148
|
-
# @api private
|
149
|
-
# @since 2.2.0
|
150
|
-
def indifferently_accessible_plugin_name(plugin_name)
|
151
|
-
plugin_name.to_s
|
152
|
-
end
|
153
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class TableSync::ReceivingHandler < Rabbit::EventHandler
|
4
|
-
extend TableSync::DSL
|
5
|
-
|
6
|
-
attribute :event
|
7
|
-
attribute :model
|
8
|
-
attribute :version
|
9
|
-
|
10
|
-
def call
|
11
|
-
raise TableSync::UndefinedConfig.new(model) if configs.blank?
|
12
|
-
|
13
|
-
configs.each do |config|
|
14
|
-
next unless config.allow_event?(event)
|
15
|
-
|
16
|
-
data = processed_data(config)
|
17
|
-
next if data.empty?
|
18
|
-
|
19
|
-
case event
|
20
|
-
when :update
|
21
|
-
config.model.transaction do
|
22
|
-
config.update(data)
|
23
|
-
end
|
24
|
-
when :destroy
|
25
|
-
config.destroy(data.values.first)
|
26
|
-
else
|
27
|
-
raise "Unknown event: #{event}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def data=(data)
|
35
|
-
@data = data[:attributes]
|
36
|
-
end
|
37
|
-
|
38
|
-
def event=(name)
|
39
|
-
super(name.to_sym)
|
40
|
-
end
|
41
|
-
|
42
|
-
def model=(name)
|
43
|
-
super(name.to_s)
|
44
|
-
end
|
45
|
-
|
46
|
-
def configs
|
47
|
-
@configs ||= self.class.configs[model]
|
48
|
-
&.map { |c| ::TableSync::ConfigDecorator.new(c, self) }
|
49
|
-
end
|
50
|
-
|
51
|
-
def processed_data(config)
|
52
|
-
parts = config.partitions&.transform_keys { |k| config.model.class.new(k) } ||
|
53
|
-
{ config.model => Array.wrap(data) }
|
54
|
-
|
55
|
-
parts.transform_values! do |data_part|
|
56
|
-
data_part.map do |row|
|
57
|
-
original_row_for_data = row.dup
|
58
|
-
row = row.dup
|
59
|
-
|
60
|
-
config.mapping_overrides.each do |before, after|
|
61
|
-
row[after] = row.delete(before)
|
62
|
-
end
|
63
|
-
|
64
|
-
only = config.only
|
65
|
-
row, missed = row.partition { |key, _| key.in?(only) }.map(&:to_h)
|
66
|
-
|
67
|
-
row.deep_merge!(config.rest_key => missed) if config.rest_key
|
68
|
-
row[config.version_key] = version
|
69
|
-
|
70
|
-
row.merge!(config.additional_data(original_row_for_data))
|
71
|
-
|
72
|
-
row unless config.skip(original_row_for_data)
|
73
|
-
end.compact.presence
|
74
|
-
end.compact
|
75
|
-
end
|
76
|
-
end
|