pg-pglogical 1.0.0 → 1.1.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/.travis.yml +2 -2
- data/CHANGELOG.md +14 -0
- data/Gemfile +5 -0
- data/README.md +6 -0
- data/lib/pg/pglogical/client.rb +48 -29
- data/lib/pg/pglogical/version.rb +1 -1
- data/lib/pg-pglogical.rb +1 -0
- data/pg-pglogical.gemspec +6 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfe7f15d53fec94d58d8d5bfa0583c2b18ea9aed
|
4
|
+
data.tar.gz: 6e536b7b1897e26fd0dbe1bfe0d522dbb965fa52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0d27d37d79a48baa6b8a19fcca50310d9dabf0052ac0eb7c5e8ba4731466c24f1a2fde40d376e53e8c3fdec1b708bef2f230d1a3f15aa0a03a94c02e7819761
|
7
|
+
data.tar.gz: 757c12060ea5385d6842601a69f1185e1c195961bc1d15ec3af740533143d3e219fd72b64ce8c7df17dc3adbe6960f35c75e00fb2096b71c9076cc49d436e5b2
|
data/.travis.yml
CHANGED
@@ -6,7 +6,7 @@ rvm:
|
|
6
6
|
before_install:
|
7
7
|
- gem install bundler -v 1.13.6
|
8
8
|
- source ${TRAVIS_BUILD_DIR}/ci/before_install.sh
|
9
|
-
script:
|
10
|
-
|
9
|
+
script: bundle exec rake spec:setup spec
|
10
|
+
after_script: bundle exec codeclimate-test-reporter
|
11
11
|
addons:
|
12
12
|
postgresql: "9.5"
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [1.1.0] - 2017-02-27
|
10
|
+
### Added
|
11
|
+
- Add the remote and local lsn to the subscription status [[#8](https://github.com/ManageIQ/pg-pglogical/pull/8)]
|
12
|
+
|
13
|
+
[Unreleased]: https://github.com/ManageIQ/pg-pglogical/compare/v1.1.0...HEAD
|
14
|
+
[1.1.0]: https://github.com/ManageIQ/pg-pglogical/compare/v1.0.0...v1.1.0
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# PG::Pglogical
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/pg-pglogical)
|
4
|
+
[](https://travis-ci.org/ManageIQ/pg-pglogical)
|
5
|
+
[](https://codeclimate.com/github/ManageIQ/pg-pglogical)
|
6
|
+
[](https://codeclimate.com/github/ManageIQ/pg-pglogical/coverage)
|
7
|
+
[](https://gemnasium.com/ManageIQ/pg-pglogical)
|
8
|
+
|
3
9
|
This gem extends the ActiveRecord connection object to include methods which map directly to the SQL stored procedure APIs provided by pglogical.
|
4
10
|
|
5
11
|
## Installation
|
data/lib/pg/pglogical/client.rb
CHANGED
@@ -10,6 +10,7 @@ module PG
|
|
10
10
|
@connection = connection
|
11
11
|
end
|
12
12
|
|
13
|
+
# Returns whether the pglogical postgres extension is installed or not
|
13
14
|
def installed?
|
14
15
|
connection.select_value("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = 'pglogical')")
|
15
16
|
end
|
@@ -29,6 +30,7 @@ module PG
|
|
29
30
|
connection.enable_extension("pglogical")
|
30
31
|
end
|
31
32
|
|
33
|
+
# Disables pglogical postgres extensions
|
32
34
|
def disable
|
33
35
|
connection.disable_extension("pglogical")
|
34
36
|
connection.disable_extension("pglogical_origin") if connection.postgresql_version < 90_500
|
@@ -79,15 +81,14 @@ module PG
|
|
79
81
|
|
80
82
|
# Updates a node connection string
|
81
83
|
#
|
84
|
+
# NOTE: This method relies on the internals of the pglogical tables
|
85
|
+
# rather than a published API.
|
86
|
+
# NOTE: Disable subscriptions involving the node before calling this
|
87
|
+
# method for a provider node in a subscriber database.
|
88
|
+
#
|
82
89
|
# @param name [String]
|
83
90
|
# @param dsn [String] new external connection string to the node
|
84
91
|
# @return [Boolean] true if the dsn was updated, false otherwise
|
85
|
-
#
|
86
|
-
# NOTE: This method relies on the internals of the pglogical tables
|
87
|
-
# rather than a published API.
|
88
|
-
# NOTE: Disable subscriptions involving the node before
|
89
|
-
# calling this method for a provider node in a subscriber
|
90
|
-
# database.
|
91
92
|
def node_dsn_update(name, dsn)
|
92
93
|
res = typed_exec(<<-SQL, name, dsn)
|
93
94
|
UPDATE pglogical.node_interface
|
@@ -128,11 +129,12 @@ module PG
|
|
128
129
|
# @param replication_sets [Array<String>] replication set names to subscribe to
|
129
130
|
# @param sync_structure [Boolean] sync the schema structure when subscribing
|
130
131
|
# @param sync_data [Boolean] sync the data when subscribing
|
131
|
-
# @param forward_origins [Array<String>] names of non-provider nodes to replicate changes
|
132
|
-
|
132
|
+
# @param forward_origins [Array<String>] names of non-provider nodes to replicate changes
|
133
|
+
# from (cascading replication)
|
134
|
+
def subscription_create(name, dsn, replication_sets = %w(default default_insert_only), # rubocop:disable Metrics/ParameterLists
|
133
135
|
sync_structure = true, sync_data = true, forward_origins = ["all"])
|
134
|
-
|
135
|
-
|
136
|
+
typed_exec("SELECT pglogical.create_subscription($1, $2, $3, $4, $5, $6)",
|
137
|
+
name, dsn, replication_sets, sync_structure, sync_data, forward_origins)
|
136
138
|
end
|
137
139
|
|
138
140
|
# Disconnects the subscription and removes it
|
@@ -140,7 +142,8 @@ module PG
|
|
140
142
|
# @param name [String] subscription name
|
141
143
|
# @param ifexists [Boolean] if true an error is not thrown when the subscription does not exist
|
142
144
|
def subscription_drop(name, ifexists = false)
|
143
|
-
typed_exec("SELECT pglogical.drop_subscription($1, $2)",
|
145
|
+
typed_exec("SELECT pglogical.drop_subscription($1, $2)",
|
146
|
+
name, ifexists)
|
144
147
|
end
|
145
148
|
|
146
149
|
# Disables a subscription and disconnects it from the provider
|
@@ -148,7 +151,8 @@ module PG
|
|
148
151
|
# @param name [String] subscription name
|
149
152
|
# @param immediate [Boolean] do not wait for the current transaction before stopping
|
150
153
|
def subscription_disable(name, immediate = false)
|
151
|
-
typed_exec("SELECT pglogical.alter_subscription_disable($1, $2)",
|
154
|
+
typed_exec("SELECT pglogical.alter_subscription_disable($1, $2)",
|
155
|
+
name, immediate)
|
152
156
|
end
|
153
157
|
|
154
158
|
# Enables a previously disabled subscription
|
@@ -156,7 +160,8 @@ module PG
|
|
156
160
|
# @param name [String] subscription name
|
157
161
|
# @param immediate [Boolean] do not wait for the current transaction before starting
|
158
162
|
def subscription_enable(name, immediate = false)
|
159
|
-
typed_exec("SELECT pglogical.alter_subscription_enable($1, $2)",
|
163
|
+
typed_exec("SELECT pglogical.alter_subscription_enable($1, $2)",
|
164
|
+
name, immediate)
|
160
165
|
end
|
161
166
|
|
162
167
|
# Syncs all unsynchronized tables in all sets in a single operation.
|
@@ -165,7 +170,8 @@ module PG
|
|
165
170
|
# @param name [String] subscription name
|
166
171
|
# @param truncate [Boolean] truncate the tables before syncing
|
167
172
|
def subscription_sync(name, truncate = false)
|
168
|
-
typed_exec("SELECT pglogical.alter_subscription_synchronize($1, $2)",
|
173
|
+
typed_exec("SELECT pglogical.alter_subscription_synchronize($1, $2)",
|
174
|
+
name, truncate)
|
169
175
|
end
|
170
176
|
|
171
177
|
# Resyncs one existing table
|
@@ -174,7 +180,8 @@ module PG
|
|
174
180
|
# @param name [String] subscription name
|
175
181
|
# @param table [String] name of the table to resync
|
176
182
|
def subscription_resync_table(name, table)
|
177
|
-
typed_exec("SELECT pglogical.alter_subscription_resynchronize_table($1, $2)",
|
183
|
+
typed_exec("SELECT pglogical.alter_subscription_resynchronize_table($1, $2)",
|
184
|
+
name, table)
|
178
185
|
end
|
179
186
|
|
180
187
|
# Adds a replication set to a subscription
|
@@ -183,7 +190,8 @@ module PG
|
|
183
190
|
# @param name [String] subscription name
|
184
191
|
# @param set_name [String] replication set name
|
185
192
|
def subscription_add_replication_set(name, set_name)
|
186
|
-
typed_exec("SELECT pglogical.alter_subscription_add_replication_set($1, $2)",
|
193
|
+
typed_exec("SELECT pglogical.alter_subscription_add_replication_set($1, $2)",
|
194
|
+
name, set_name)
|
187
195
|
end
|
188
196
|
|
189
197
|
# Removes a replication set from a subscription
|
@@ -191,13 +199,14 @@ module PG
|
|
191
199
|
# @param name [String] subscription name
|
192
200
|
# @param set_name [String] replication set name
|
193
201
|
def subscription_remove_replication_set(name, set_name)
|
194
|
-
typed_exec("SELECT pglogical.alter_subscription_remove_replication_set($1, $2)",
|
202
|
+
typed_exec("SELECT pglogical.alter_subscription_remove_replication_set($1, $2)",
|
203
|
+
name, set_name)
|
195
204
|
end
|
196
205
|
|
197
206
|
# Shows status and basic information about a subscription
|
198
207
|
#
|
199
208
|
# @prarm name [String] subscription name
|
200
|
-
# @return a hash with the subscription information
|
209
|
+
# @return [Hash] a hash with the subscription information
|
201
210
|
# keys:
|
202
211
|
# subscription_name
|
203
212
|
# status
|
@@ -206,22 +215,29 @@ module PG
|
|
206
215
|
# slot_name
|
207
216
|
# replication_sets
|
208
217
|
# forward_origins
|
218
|
+
# remote_replication_lsn(Log Sequence Number)
|
219
|
+
# local_replication_lsn(Log Sequence Number)
|
209
220
|
def subscription_show_status(name)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
221
|
+
sql = <<-SQL
|
222
|
+
SELECT sub.*, stat.remote_lsn AS remote_replication_lsn, stat.local_lsn AS local_replication_lsn
|
223
|
+
FROM pglogical.show_subscription_status($1) sub
|
224
|
+
JOIN pg_replication_origin_status stat
|
225
|
+
ON sub.slot_name = stat.external_id
|
226
|
+
SQL
|
227
|
+
|
228
|
+
typed_exec(sql, name).first.tap do |s|
|
229
|
+
s["replication_sets"] = s["replication_sets"][1..-2].split(",")
|
230
|
+
s["forward_origins"] = s["forward_origins"][1..-2].split(",")
|
231
|
+
end
|
214
232
|
end
|
215
233
|
|
216
234
|
# Shows the status of all configured subscriptions
|
217
235
|
#
|
218
236
|
# @return Array<Hash> list of results from #subscription_show_status
|
219
237
|
def subscriptions
|
220
|
-
|
221
|
-
|
222
|
-
ret << subscription_show_status(s)
|
238
|
+
connection.select_values("SELECT sub_name FROM pglogical.subscription").collect do |s|
|
239
|
+
subscription_show_status(s)
|
223
240
|
end
|
224
|
-
ret
|
225
241
|
end
|
226
242
|
|
227
243
|
# Replication Sets
|
@@ -271,7 +287,8 @@ module PG
|
|
271
287
|
# @param table_name [String] table name to add
|
272
288
|
# @param sync [Boolean] sync the table on all subscribers to the given replication set
|
273
289
|
def replication_set_add_table(set_name, table_name, sync = false)
|
274
|
-
typed_exec("SELECT pglogical.replication_set_add_table($1, $2, $3)",
|
290
|
+
typed_exec("SELECT pglogical.replication_set_add_table($1, $2, $3)",
|
291
|
+
set_name, table_name, sync)
|
275
292
|
end
|
276
293
|
|
277
294
|
# Adds all tables in the given schemas to the replication set
|
@@ -289,7 +306,8 @@ module PG
|
|
289
306
|
# @param set_name [String] replication set name
|
290
307
|
# @param table_name [String] table to remove
|
291
308
|
def replication_set_remove_table(set_name, table_name)
|
292
|
-
typed_exec("SELECT pglogical.replication_set_remove_table($1, $2)",
|
309
|
+
typed_exec("SELECT pglogical.replication_set_remove_table($1, $2)",
|
310
|
+
set_name, table_name)
|
293
311
|
end
|
294
312
|
|
295
313
|
# Lists the tables currently in the replication set
|
@@ -321,7 +339,8 @@ module PG
|
|
321
339
|
private
|
322
340
|
|
323
341
|
def typed_exec(sql, *params)
|
324
|
-
|
342
|
+
type_map = PG::BasicTypeMapForQueries.new(connection.raw_connection)
|
343
|
+
connection.raw_connection.async_exec(sql, params, nil, type_map)
|
325
344
|
end
|
326
345
|
end
|
327
346
|
end
|
data/lib/pg/pglogical/version.rb
CHANGED
data/lib/pg-pglogical.rb
CHANGED
data/pg-pglogical.gemspec
CHANGED
@@ -9,8 +9,12 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Nick Carboni"]
|
10
10
|
spec.email = ["ncarboni@redhat.com"]
|
11
11
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
12
|
+
spec.summary = "A ruby gem for configuring and using pglogical"
|
13
|
+
spec.description = <<-EOS
|
14
|
+
This gem provides a class with methods which map directly to the SQL stored
|
15
|
+
procedure APIs provided by pglogical. It also provides a way to mix these
|
16
|
+
methods directly into the ActiveRecord connection object.
|
17
|
+
EOS
|
14
18
|
spec.homepage = "https://github.com/ManageIQ/pg-pglogical"
|
15
19
|
spec.license = "Apache-2.0"
|
16
20
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg-pglogical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Carboni
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -80,8 +80,9 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
|
-
description:
|
84
|
-
|
83
|
+
description: |
|
84
|
+
This gem provides a class with methods which map directly to the SQL stored
|
85
|
+
procedure APIs provided by pglogical. It also provides a way to mix these
|
85
86
|
methods directly into the ActiveRecord connection object.
|
86
87
|
email:
|
87
88
|
- ncarboni@redhat.com
|
@@ -92,6 +93,7 @@ files:
|
|
92
93
|
- ".gitignore"
|
93
94
|
- ".rspec"
|
94
95
|
- ".travis.yml"
|
96
|
+
- CHANGELOG.md
|
95
97
|
- Gemfile
|
96
98
|
- LICENSE.txt
|
97
99
|
- README.md
|