table_sync 4.0.0 → 4.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +4 -4
- data/docs/receiving.md +2 -2
- data/lib/table_sync/receiving/handler.rb +32 -27
- data/lib/table_sync/receiving/model/active_record.rb +11 -18
- data/lib/table_sync/receiving/model/sequel.rb +15 -25
- data/lib/table_sync/utils/interface_checker.rb +6 -0
- data/lib/table_sync/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73b565f881f6ae36dd659dd4d99d04bf0a739aa0456410c5b730eb7f0b107492
|
|
4
|
+
data.tar.gz: 95dee1cf9f11e6a05c04f3edd4cb5845e3819ea5aab694b3939b5b6e7e4b114d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5af5e1a66865f69ff220151e64649813c99af9a32323d7c3d246ae08a6e5962314bb911041b648898b02c6fc684f6312ce187647d5e0c0db8cbf9bef52cc435
|
|
7
|
+
data.tar.gz: 45b02a9f461b7cd406084bfe6fe2cd643bb43045f560cd06f2d4521e44067b1795a6ce231fbe6095a81d4ecfbf7bb678c8d05a61e4c369affd71a0abc6dd0d1c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [4.2.1] - 2020-11-20
|
|
5
|
+
### Fixed
|
|
6
|
+
- bug with sorting data in handler, it was bad idea to use `.hash` replaced to `.to_s`
|
|
7
|
+
|
|
8
|
+
## [4.2.0] - 2020-11-19
|
|
9
|
+
|
|
10
|
+
- No changes. Just stabilization release.
|
|
11
|
+
|
|
12
|
+
## [4.1.2] - 2020-11-19
|
|
13
|
+
### Fixed
|
|
14
|
+
- bug with sorting data in handler
|
|
15
|
+
|
|
16
|
+
## [4.1.1] - 2020-11-06
|
|
17
|
+
### Fixed
|
|
18
|
+
- dead locks in receiving module (see: `spec/receiving/handler_spec.rb#avoid dead locks`)
|
|
19
|
+
|
|
20
|
+
## [4.1.0] - 2020-11-02
|
|
21
|
+
### Changed
|
|
22
|
+
- move `TableSync::Instrument.notify` from models to the handler
|
|
23
|
+
- fire `TableSync::Instrument.notify` after commit insted of in transaction
|
|
24
|
+
|
|
4
25
|
## [4.0.0] - 2020-10-23
|
|
5
26
|
### Returned
|
|
6
27
|
- config inheritance
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
table_sync (4.
|
|
4
|
+
table_sync (4.2.1)
|
|
5
5
|
memery
|
|
6
6
|
rabbit_messaging (~> 0.3)
|
|
7
7
|
rails
|
|
@@ -84,7 +84,7 @@ GEM
|
|
|
84
84
|
crass (1.0.6)
|
|
85
85
|
diff-lcs (1.4.4)
|
|
86
86
|
docile (1.3.2)
|
|
87
|
-
erubi (1.
|
|
87
|
+
erubi (1.10.0)
|
|
88
88
|
exception_notification (4.4.3)
|
|
89
89
|
actionmailer (>= 4.0, < 7)
|
|
90
90
|
activesupport (>= 4.0, < 7)
|
|
@@ -119,11 +119,11 @@ GEM
|
|
|
119
119
|
pry (0.13.1)
|
|
120
120
|
coderay (~> 1.1)
|
|
121
121
|
method_source (~> 1.0)
|
|
122
|
-
rabbit_messaging (0.
|
|
122
|
+
rabbit_messaging (0.9.0)
|
|
123
123
|
bunny (~> 2.0)
|
|
124
124
|
exception_notification
|
|
125
125
|
lamian
|
|
126
|
-
rails
|
|
126
|
+
rails (>= 5.2)
|
|
127
127
|
sneakers (~> 2.0)
|
|
128
128
|
tainbox
|
|
129
129
|
rack (2.2.3)
|
data/docs/receiving.md
CHANGED
|
@@ -22,7 +22,7 @@ class Rabbit::Handler::MainProject::TableSync < TableSync::ReceivingHandler
|
|
|
22
22
|
receive "User", to_table: :clients, events: %i[update destroy] do
|
|
23
23
|
mapping_overrides email: :project_user_email, id: :project_user_id
|
|
24
24
|
|
|
25
|
-
only :project_user_email, :project_user_id
|
|
25
|
+
only :project_user_email, :project_user_id, :project_id
|
|
26
26
|
target_keys :project_id, :project_user_id
|
|
27
27
|
rest_key :project_user_rest
|
|
28
28
|
version_key :project_user_version
|
|
@@ -37,7 +37,7 @@ class Rabbit::Handler::MainProject::TableSync < TableSync::ReceivingHandler
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
receive "User", to_model: CustomModel.new(:users) do
|
|
40
|
-
rest_key
|
|
40
|
+
rest_key false
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
```
|
|
@@ -23,6 +23,8 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
|
23
23
|
|
|
24
24
|
validate_data(data, target_keys: target_keys)
|
|
25
25
|
|
|
26
|
+
data.sort_by! { |row| row.values_at(*target_keys).to_s }
|
|
27
|
+
|
|
26
28
|
params = { data: data, target_keys: target_keys, version_key: version_key }
|
|
27
29
|
|
|
28
30
|
if event == :update
|
|
@@ -53,16 +55,20 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
def configs
|
|
56
|
-
@configs ||=
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
@configs ||= begin
|
|
59
|
+
configs = self.class.configs[model]
|
|
60
|
+
configs = configs.sort_by { |config| "#{config.model.schema}.#{config.model.table}" }
|
|
61
|
+
configs.map do |config|
|
|
62
|
+
::TableSync::Receiving::ConfigDecorator.new(
|
|
63
|
+
config: config,
|
|
64
|
+
# next parameters will be send to each proc-options from config
|
|
65
|
+
event: event,
|
|
66
|
+
model: model,
|
|
67
|
+
version: version,
|
|
68
|
+
project_id: project_id,
|
|
69
|
+
raw_data: data,
|
|
70
|
+
)
|
|
71
|
+
end
|
|
66
72
|
end
|
|
67
73
|
end
|
|
68
74
|
|
|
@@ -99,9 +105,7 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
|
99
105
|
end
|
|
100
106
|
|
|
101
107
|
if data.uniq { |row| row.slice(*target_keys) }.size != data.size
|
|
102
|
-
raise TableSync::DataError.new(
|
|
103
|
-
data, target_keys, "Duplicate rows found!"
|
|
104
|
-
)
|
|
108
|
+
raise TableSync::DataError.new(data, target_keys, "Duplicate rows found!")
|
|
105
109
|
end
|
|
106
110
|
end
|
|
107
111
|
|
|
@@ -109,22 +113,23 @@ class TableSync::Receiving::Handler < Rabbit::EventHandler
|
|
|
109
113
|
model = config.model
|
|
110
114
|
|
|
111
115
|
model.transaction do
|
|
112
|
-
if event == :update
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
results = if event == :update
|
|
117
|
+
config.before_update(**params)
|
|
118
|
+
model.upsert(**params)
|
|
119
|
+
else
|
|
120
|
+
config.before_destroy(**params)
|
|
121
|
+
model.destroy(**params)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
model.after_commit do
|
|
125
|
+
TableSync::Instrument.notify table: model.table, schema: model.schema,
|
|
126
|
+
count: results.count, event: event, direction: :receive
|
|
127
|
+
end
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
end
|
|
129
|
+
if event == :update
|
|
130
|
+
model.after_commit { config.after_commit_on_update(**params.merge(results: results)) }
|
|
120
131
|
else
|
|
121
|
-
config.
|
|
122
|
-
|
|
123
|
-
results = model.destroy(**params)
|
|
124
|
-
|
|
125
|
-
model.after_commit do
|
|
126
|
-
config.after_commit_on_destroy(**params.merge(results: results))
|
|
127
|
-
end
|
|
132
|
+
model.after_commit { config.after_commit_on_destroy(**params.merge(results: results)) }
|
|
128
133
|
end
|
|
129
134
|
end
|
|
130
135
|
end
|
|
@@ -18,11 +18,18 @@ module TableSync::Receiving::Model
|
|
|
18
18
|
def trigger_transactional_callbacks?(*); end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
attr_reader :table, :schema
|
|
22
|
+
|
|
21
23
|
def initialize(table_name)
|
|
22
24
|
@raw_model = Class.new(::ActiveRecord::Base) do
|
|
23
25
|
self.table_name = table_name
|
|
24
26
|
self.inheritance_column = nil
|
|
25
27
|
end
|
|
28
|
+
|
|
29
|
+
model_naming = ::TableSync::NamingResolver::ActiveRecord.new(table_name: table_name)
|
|
30
|
+
|
|
31
|
+
@table = model_naming.table.to_sym
|
|
32
|
+
@schema = model_naming.schema.to_sym
|
|
26
33
|
end
|
|
27
34
|
|
|
28
35
|
def columns
|
|
@@ -45,15 +52,15 @@ module TableSync::Receiving::Model
|
|
|
45
52
|
AND kcu.constraint_name = tc.constraint_name
|
|
46
53
|
WHERE
|
|
47
54
|
t.table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
48
|
-
AND t.table_schema = '#{
|
|
49
|
-
AND t.table_name = '#{
|
|
55
|
+
AND t.table_schema = '#{schema}'
|
|
56
|
+
AND t.table_name = '#{table}'
|
|
50
57
|
ORDER BY
|
|
51
58
|
kcu.ordinal_position
|
|
52
59
|
SQL
|
|
53
60
|
end
|
|
54
61
|
|
|
55
62
|
def upsert(data:, target_keys:, version_key:, default_values:)
|
|
56
|
-
|
|
63
|
+
data.map do |datum|
|
|
57
64
|
conditions = datum.select { |k| target_keys.include?(k) }
|
|
58
65
|
|
|
59
66
|
row = raw_model.lock("FOR NO KEY UPDATE").where(conditions)
|
|
@@ -75,11 +82,6 @@ module TableSync::Receiving::Model
|
|
|
75
82
|
|
|
76
83
|
row_to_hash(row)
|
|
77
84
|
end.compact
|
|
78
|
-
|
|
79
|
-
TableSync::Instrument.notify(table: model_naming.table, schema: model_naming.schema,
|
|
80
|
-
event: :update, count: result.count, direction: :receive)
|
|
81
|
-
|
|
82
|
-
result
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
def destroy(data:, target_keys:, version_key:)
|
|
@@ -100,11 +102,6 @@ module TableSync::Receiving::Model
|
|
|
100
102
|
raise TableSync::DestroyError.new(data: data, target_keys: target_keys, result: result)
|
|
101
103
|
end
|
|
102
104
|
|
|
103
|
-
TableSync::Instrument.notify(
|
|
104
|
-
table: model_naming.table, schema: model_naming.schema,
|
|
105
|
-
event: :destroy, count: result.count, direction: :receive
|
|
106
|
-
)
|
|
107
|
-
|
|
108
105
|
result
|
|
109
106
|
end
|
|
110
107
|
|
|
@@ -121,11 +118,7 @@ module TableSync::Receiving::Model
|
|
|
121
118
|
attr_reader :raw_model
|
|
122
119
|
|
|
123
120
|
def db
|
|
124
|
-
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def model_naming
|
|
128
|
-
::TableSync::NamingResolver::ActiveRecord.new(table_name: raw_model.table_name)
|
|
121
|
+
raw_model.connection
|
|
129
122
|
end
|
|
130
123
|
|
|
131
124
|
def row_to_hash(row)
|
|
@@ -2,8 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
module TableSync::Receiving::Model
|
|
4
4
|
class Sequel
|
|
5
|
+
attr_reader :table, :schema
|
|
6
|
+
|
|
5
7
|
def initialize(table_name)
|
|
6
8
|
@raw_model = Class.new(::Sequel::Model(table_name)).tap(&:unrestrict_primary_key)
|
|
9
|
+
|
|
10
|
+
model_naming = ::TableSync::NamingResolver::Sequel.new(
|
|
11
|
+
table_name: table_name,
|
|
12
|
+
db: @raw_model.db,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
@table = model_naming.table.to_sym
|
|
16
|
+
@schema = model_naming.schema.to_sym
|
|
7
17
|
end
|
|
8
18
|
|
|
9
19
|
def columns
|
|
@@ -15,7 +25,7 @@ module TableSync::Receiving::Model
|
|
|
15
25
|
end
|
|
16
26
|
|
|
17
27
|
def upsert(data:, target_keys:, version_key:, default_values:)
|
|
18
|
-
qualified_version = ::Sequel.qualify(table_name, version_key)
|
|
28
|
+
qualified_version = ::Sequel.qualify(raw_model.table_name, version_key)
|
|
19
29
|
version_condition = ::Sequel.function(:coalesce, qualified_version, 0) <
|
|
20
30
|
::Sequel.qualify(:excluded, version_key)
|
|
21
31
|
|
|
@@ -24,18 +34,10 @@ module TableSync::Receiving::Model
|
|
|
24
34
|
|
|
25
35
|
insert_data = type_cast(data)
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
update_where: version_condition,
|
|
32
|
-
)
|
|
33
|
-
.multi_insert(insert_data)
|
|
34
|
-
|
|
35
|
-
TableSync::Instrument.notify table: model_naming.table, schema: model_naming.schema,
|
|
36
|
-
count: result.count, event: :update, direction: :receive
|
|
37
|
-
|
|
38
|
-
result
|
|
37
|
+
dataset
|
|
38
|
+
.returning
|
|
39
|
+
.insert_conflict(target: target_keys, update: upd_spec, update_where: version_condition)
|
|
40
|
+
.multi_insert(insert_data)
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def destroy(data:, target_keys:, version_key:)
|
|
@@ -47,10 +49,6 @@ module TableSync::Receiving::Model
|
|
|
47
49
|
raise TableSync::DestroyError.new(data: data, target_keys: target_keys, result: result)
|
|
48
50
|
end
|
|
49
51
|
|
|
50
|
-
TableSync::Instrument.notify table: model_naming.table, schema: model_naming.schema,
|
|
51
|
-
count: result.count,
|
|
52
|
-
event: :destroy, direction: :receive
|
|
53
|
-
|
|
54
52
|
result
|
|
55
53
|
end
|
|
56
54
|
|
|
@@ -66,14 +64,6 @@ module TableSync::Receiving::Model
|
|
|
66
64
|
|
|
67
65
|
attr_reader :raw_model
|
|
68
66
|
|
|
69
|
-
def table_name
|
|
70
|
-
raw_model.table_name
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def model_naming
|
|
74
|
-
::TableSync::NamingResolver::Sequel.new(table_name: table_name, db: db)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
67
|
def dataset
|
|
78
68
|
raw_model.dataset
|
|
79
69
|
end
|
|
@@ -95,3 +95,9 @@ __END__
|
|
|
95
95
|
:primary_keys:
|
|
96
96
|
:parameters: []
|
|
97
97
|
:description: "returns an array with the primary_keys"
|
|
98
|
+
:table:
|
|
99
|
+
:parameters: []
|
|
100
|
+
:description: "returns an instance of Symbol"
|
|
101
|
+
:schema:
|
|
102
|
+
:parameters: []
|
|
103
|
+
:description: "returns an instance of Symbol"
|
data/lib/table_sync/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: table_sync
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Umbrellio
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-11-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: memery
|
|
@@ -302,7 +302,7 @@ homepage: https://github.com/umbrellio/table_sync
|
|
|
302
302
|
licenses:
|
|
303
303
|
- MIT
|
|
304
304
|
metadata: {}
|
|
305
|
-
post_install_message:
|
|
305
|
+
post_install_message:
|
|
306
306
|
rdoc_options: []
|
|
307
307
|
require_paths:
|
|
308
308
|
- lib
|
|
@@ -318,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
318
318
|
version: '0'
|
|
319
319
|
requirements: []
|
|
320
320
|
rubygems_version: 3.2.0.rc.1
|
|
321
|
-
signing_key:
|
|
321
|
+
signing_key:
|
|
322
322
|
specification_version: 4
|
|
323
323
|
summary: DB Table synchronization between microservices based on Model's event system
|
|
324
324
|
and RabbitMQ messaging
|