pgsync 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pgsync might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/pgsync.rb +60 -47
- data/lib/pgsync/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26c6ed8e9e75f8392d08f9c9930b659053bcb6bf
|
4
|
+
data.tar.gz: 67d1caf0199d8c2bbbe99322360d4f06347c3a1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 203a74151aa72e5aee142ccc6a5d96e9bf800cf2710e80da1a54126fdf16323135a4ce197db3bccf76a1ae5f8d591b2ee283124dd00e45d6056ec6a612ccac44
|
7
|
+
data.tar.gz: 4f51ce05bcfe128010850614cf64b0e17b9cac63ce7937b5cbed1bbf2824705e44db6a52c972548db3663860c25082f2e586b246492679d5017bc291e7d68aa1
|
data/CHANGELOG.md
CHANGED
data/lib/pgsync.rb
CHANGED
@@ -13,19 +13,9 @@ module PgSync
|
|
13
13
|
class Rollback < StandardError; end
|
14
14
|
|
15
15
|
class Client
|
16
|
-
attr_reader :config_file
|
17
|
-
|
18
16
|
def initialize(args)
|
19
17
|
$stdout.sync = true
|
20
18
|
@arguments, @options = parse_args(args)
|
21
|
-
@config_file =
|
22
|
-
if @options[:db]
|
23
|
-
db_config_file(@options[:db])
|
24
|
-
else
|
25
|
-
@options[:config] || ".pgsync.yml"
|
26
|
-
end
|
27
|
-
@config_file = search_tree(@config_file)
|
28
|
-
abort "Config not found" unless @config_file
|
29
19
|
@mutex = MultiProcessing::Mutex.new
|
30
20
|
end
|
31
21
|
|
@@ -57,14 +47,14 @@ module PgSync
|
|
57
47
|
if args[0] == "schema"
|
58
48
|
time =
|
59
49
|
benchmark do
|
60
|
-
|
50
|
+
log "* Dumping schema"
|
61
51
|
tables = to_arr(args[1]).map { |t| "-t #{t}" }.join(" ")
|
62
52
|
dump_command = "pg_dump --verbose --schema-only --no-owner --no-acl --clean #{tables} #{to_url(source_uri)}"
|
63
53
|
restore_command = "psql -q -d #{to_url(destination_uri)}"
|
64
54
|
system("#{dump_command} | #{restore_command}")
|
65
55
|
end
|
66
56
|
|
67
|
-
|
57
|
+
log "* DONE (#{time.round(1)}s)"
|
68
58
|
else
|
69
59
|
from_uri = source_uri
|
70
60
|
to_uri = destination_uri
|
@@ -127,51 +117,53 @@ module PgSync
|
|
127
117
|
where = opts[:where]
|
128
118
|
|
129
119
|
@mutex.synchronize do
|
130
|
-
|
120
|
+
log "* Syncing #{table}"
|
131
121
|
if where
|
132
|
-
|
122
|
+
log " #{where}"
|
133
123
|
where = " WHERE #{opts[:where]}"
|
134
124
|
end
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
125
|
+
log " Extra columns: #{extra_fields.join(", ")}" if extra_fields.any?
|
126
|
+
log " Missing columns: #{missing_fields.join(", ")}" if missing_fields.any?
|
127
|
+
log " Extra sequences: #{extra_sequences.join(", ")}" if extra_sequences.any?
|
128
|
+
log " Missing sequences: #{missing_sequences.join(", ")}" if missing_sequences.any?
|
140
129
|
|
141
|
-
|
142
|
-
|
130
|
+
if shared_fields.empty?
|
131
|
+
log " No fields to copy"
|
132
|
+
end
|
143
133
|
end
|
144
134
|
|
145
|
-
|
146
|
-
|
135
|
+
if shared_fields.any?
|
136
|
+
copy_fields = shared_fields.map { |f| f2 = bad_fields.to_a.find { |bf, bk| rule_match?(table, f, bf) }; f2 ? "#{apply_strategy(f2[1], f, from_connection)} AS #{escape_identifier(f)}" : escape_identifier(f) }.join(", ")
|
137
|
+
fields = shared_fields.map { |f| escape_identifier(f) }.join(", ")
|
147
138
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
139
|
+
seq_values = {}
|
140
|
+
shared_sequences.each do |seq|
|
141
|
+
seq_values[seq] = from_connection.exec("select last_value from #{seq}").to_a[0]["last_value"]
|
142
|
+
end
|
152
143
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
144
|
+
to_connection.exec("TRUNCATE #{table} CASCADE")
|
145
|
+
to_connection.copy_data "COPY #{table} (#{fields}) FROM STDIN" do
|
146
|
+
from_connection.copy_data "COPY (SELECT #{copy_fields} FROM #{table}#{where}) TO STDOUT" do
|
147
|
+
while row = from_connection.get_copy_data
|
148
|
+
to_connection.put_copy_data(row)
|
149
|
+
end
|
158
150
|
end
|
159
151
|
end
|
160
|
-
|
161
|
-
|
162
|
-
|
152
|
+
seq_values.each do |seq, value|
|
153
|
+
to_connection.exec("SELECT setval(#{escape(seq)}, #{escape(value)})")
|
154
|
+
end
|
163
155
|
end
|
164
156
|
end
|
165
157
|
end
|
166
158
|
end
|
167
159
|
|
168
160
|
@mutex.synchronize do
|
169
|
-
|
161
|
+
log "* DONE #{table} (#{time.round(1)}s)"
|
170
162
|
end
|
171
163
|
end
|
172
164
|
|
173
165
|
time = Time.now - start_time
|
174
|
-
|
166
|
+
log "Completed in #{time.round(1)}s"
|
175
167
|
end
|
176
168
|
end
|
177
169
|
true
|
@@ -191,11 +183,11 @@ module PgSync
|
|
191
183
|
# TODO much better name for this option
|
192
184
|
o.boolean "--to-safe", "accept danger", default: false
|
193
185
|
o.on "-v", "--version", "print the version" do
|
194
|
-
|
186
|
+
log PgSync::VERSION
|
195
187
|
exit
|
196
188
|
end
|
197
189
|
o.on "-h", "--help", "prints help" do
|
198
|
-
|
190
|
+
log o
|
199
191
|
exit
|
200
192
|
end
|
201
193
|
end
|
@@ -206,10 +198,14 @@ module PgSync
|
|
206
198
|
|
207
199
|
def config
|
208
200
|
@config ||= begin
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
201
|
+
if config_file
|
202
|
+
begin
|
203
|
+
YAML.load_file(config_file) || {}
|
204
|
+
rescue Psych::SyntaxError => e
|
205
|
+
raise PgSync::Error, e.message
|
206
|
+
end
|
207
|
+
else
|
208
|
+
{}
|
213
209
|
end
|
214
210
|
end
|
215
211
|
end
|
@@ -217,7 +213,7 @@ module PgSync
|
|
217
213
|
def parse_source(source)
|
218
214
|
if source && source[0..1] == "$(" && source[-1] == ")"
|
219
215
|
command = source[2..-2]
|
220
|
-
#
|
216
|
+
# log "Running #{command}"
|
221
217
|
source = `#{command}`.chomp
|
222
218
|
unless $?.success?
|
223
219
|
abort "Command exited with non-zero status:\n#{command}"
|
@@ -231,7 +227,7 @@ module PgSync
|
|
231
227
|
abort "#{config_file} exists."
|
232
228
|
else
|
233
229
|
FileUtils.cp(File.dirname(__FILE__) + "/../config.yml", config_file)
|
234
|
-
|
230
|
+
log "#{config_file} created. Add your database credentials."
|
235
231
|
end
|
236
232
|
end
|
237
233
|
|
@@ -256,7 +252,7 @@ module PgSync
|
|
256
252
|
conn.close
|
257
253
|
end
|
258
254
|
rescue PG::ConnectionBad => e
|
259
|
-
|
255
|
+
log
|
260
256
|
abort e.message
|
261
257
|
end
|
262
258
|
|
@@ -352,7 +348,7 @@ module PgSync
|
|
352
348
|
end
|
353
349
|
|
354
350
|
def print_uri(prefix, uri)
|
355
|
-
|
351
|
+
log "#{prefix}: #{uri.path.sub(/\A\//, '')} on #{uri.host}:#{uri.port}"
|
356
352
|
end
|
357
353
|
|
358
354
|
def to_url(uri)
|
@@ -374,10 +370,27 @@ module PgSync
|
|
374
370
|
end
|
375
371
|
end
|
376
372
|
|
373
|
+
def config_file
|
374
|
+
return @config_file if instance_variable_get(:@config_file)
|
375
|
+
|
376
|
+
@config_file =
|
377
|
+
search_tree(
|
378
|
+
if @options[:db]
|
379
|
+
db_config_file(@options[:db])
|
380
|
+
else
|
381
|
+
@options[:config] || ".pgsync.yml"
|
382
|
+
end
|
383
|
+
)
|
384
|
+
end
|
385
|
+
|
377
386
|
def abort(message)
|
378
387
|
raise PgSync::Error, message
|
379
388
|
end
|
380
389
|
|
390
|
+
def log(message)
|
391
|
+
$stderr.puts message
|
392
|
+
end
|
393
|
+
|
381
394
|
def sequences(conn, table, columns)
|
382
395
|
conn.exec("SELECT #{columns.map { |f| "pg_get_serial_sequence(#{escape(table)}, #{escape(f)}) AS #{f}" }.join(", ")}").to_a[0].values.compact
|
383
396
|
end
|
data/lib/pgsync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgsync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|