pg 1.2.2-x64-mingw32 → 1.3.0.rc3-x64-mingw32
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
- checksums.yaml.gz.sig +0 -0
- data/.appveyor.yml +36 -0
- data/.gems +6 -0
- data/.github/workflows/binary-gems.yml +85 -0
- data/.github/workflows/source-gem.yml +129 -0
- data/.gitignore +13 -0
- data/.hgsigs +34 -0
- data/.hgtags +41 -0
- data/.irbrc +23 -0
- data/.pryrc +23 -0
- data/.tm_properties +21 -0
- data/.travis.yml +49 -0
- data/Gemfile +14 -0
- data/History.rdoc +86 -7
- data/Manifest.txt +0 -1
- data/README.rdoc +8 -7
- data/Rakefile +28 -139
- data/Rakefile.cross +17 -17
- data/certs/ged.pem +24 -0
- data/ext/errorcodes.def +8 -0
- data/ext/errorcodes.txt +3 -1
- data/ext/extconf.rb +90 -19
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +23 -0
- data/ext/pg.c +59 -4
- data/ext/pg.h +18 -0
- data/ext/pg_coder.c +90 -24
- data/ext/pg_connection.c +615 -533
- data/ext/pg_copy_coder.c +45 -15
- data/ext/pg_record_coder.c +38 -9
- data/ext/pg_result.c +61 -31
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +6 -6
- data/ext/pg_tuple.c +47 -21
- data/ext/pg_type_map.c +41 -8
- data/ext/pg_type_map_all_strings.c +14 -1
- data/ext/pg_type_map_by_class.c +50 -21
- data/ext/pg_type_map_by_column.c +64 -28
- data/ext/pg_type_map_by_mri_type.c +47 -18
- data/ext/pg_type_map_by_oid.c +52 -23
- data/ext/pg_type_map_in_ruby.c +50 -19
- data/ext/pg_util.c +2 -2
- data/lib/2.5/pg_ext.so +0 -0
- data/lib/2.6/pg_ext.so +0 -0
- data/lib/2.7/pg_ext.so +0 -0
- data/lib/3.0/pg_ext.so +0 -0
- data/lib/pg/basic_type_map_based_on_result.rb +47 -0
- data/lib/pg/basic_type_map_for_queries.rb +193 -0
- data/lib/pg/basic_type_map_for_results.rb +81 -0
- data/lib/pg/basic_type_registry.rb +296 -0
- data/lib/pg/coder.rb +1 -1
- data/lib/pg/connection.rb +586 -57
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +40 -27
- data/lib/x64-mingw32/libpq.dll +0 -0
- data/misc/openssl-pg-segfault.rb +31 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +21 -0
- data/misc/postgres/lib/postgres.rb +16 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +21 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
- data/pg.gemspec +32 -0
- data/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +106 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/async_mixed.rb +56 -0
- data/sample/check_conn.rb +21 -0
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/disk_usage_report.rb +177 -0
- data/sample/issue-119.rb +94 -0
- data/sample/losample.rb +69 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/notify_wait.rb +72 -0
- data/sample/pg_statistics.rb +285 -0
- data/sample/replication_monitor.rb +222 -0
- data/sample/test_binary_values.rb +33 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +311 -0
- data.tar.gz.sig +0 -0
- metadata +92 -233
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -0
- data/lib/2.2/pg_ext.so +0 -0
- data/lib/2.3/pg_ext.so +0 -0
- data/lib/2.4/pg_ext.so +0 -0
- data/lib/pg/basic_type_mapping.rb +0 -522
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -382
- data/spec/pg/basic_type_mapping_spec.rb +0 -645
- data/spec/pg/connection_spec.rb +0 -1911
- data/spec/pg/connection_sync_spec.rb +0 -41
- data/spec/pg/result_spec.rb +0 -681
- data/spec/pg/tuple_spec.rb +0 -333
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -226
- data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
- data/spec/pg/type_map_by_oid_spec.rb +0 -149
- data/spec/pg/type_map_in_ruby_spec.rb +0 -164
- data/spec/pg/type_map_spec.rb +0 -22
- data/spec/pg/type_spec.rb +0 -1123
- data/spec/pg_spec.rb +0 -50
data/spec/helpers.rb
DELETED
@@ -1,382 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
|
-
require 'pathname'
|
4
|
-
require 'rspec'
|
5
|
-
require 'shellwords'
|
6
|
-
require 'pg'
|
7
|
-
|
8
|
-
DEFAULT_TEST_DIR_STR = File.join(Dir.pwd, "tmp_test_specs")
|
9
|
-
TEST_DIR_STR = ENV['RUBY_PG_TEST_DIR'] || DEFAULT_TEST_DIR_STR
|
10
|
-
TEST_DIRECTORY = Pathname.new(TEST_DIR_STR)
|
11
|
-
|
12
|
-
module PG::TestingHelpers
|
13
|
-
|
14
|
-
### Automatically set up the database when it's used, and wrap a transaction around
|
15
|
-
### examples that don't disable it.
|
16
|
-
def self::included( mod )
|
17
|
-
super
|
18
|
-
|
19
|
-
if mod.respond_to?( :around )
|
20
|
-
|
21
|
-
mod.before( :all ) { @conn = setup_testing_db(described_class ? described_class.name : mod.description) }
|
22
|
-
|
23
|
-
mod.around( :each ) do |example|
|
24
|
-
begin
|
25
|
-
@conn.set_default_encoding
|
26
|
-
@conn.exec( 'BEGIN' ) unless example.metadata[:without_transaction]
|
27
|
-
desc = example.source_location.join(':')
|
28
|
-
@conn.exec %Q{SET application_name TO '%s'} %
|
29
|
-
[@conn.escape_string(desc.slice(-60))]
|
30
|
-
example.run
|
31
|
-
ensure
|
32
|
-
@conn.exec( 'ROLLBACK' ) unless example.metadata[:without_transaction]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
mod.after( :all ) { teardown_testing_db(@conn) }
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
#
|
43
|
-
# Examples
|
44
|
-
#
|
45
|
-
|
46
|
-
# Set some ANSI escape code constants (Shamelessly stolen from Perl's
|
47
|
-
# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
|
48
|
-
ANSI_ATTRIBUTES = {
|
49
|
-
'clear' => 0,
|
50
|
-
'reset' => 0,
|
51
|
-
'bold' => 1,
|
52
|
-
'dark' => 2,
|
53
|
-
'underline' => 4,
|
54
|
-
'underscore' => 4,
|
55
|
-
'blink' => 5,
|
56
|
-
'reverse' => 7,
|
57
|
-
'concealed' => 8,
|
58
|
-
|
59
|
-
'black' => 30, 'on_black' => 40,
|
60
|
-
'red' => 31, 'on_red' => 41,
|
61
|
-
'green' => 32, 'on_green' => 42,
|
62
|
-
'yellow' => 33, 'on_yellow' => 43,
|
63
|
-
'blue' => 34, 'on_blue' => 44,
|
64
|
-
'magenta' => 35, 'on_magenta' => 45,
|
65
|
-
'cyan' => 36, 'on_cyan' => 46,
|
66
|
-
'white' => 37, 'on_white' => 47
|
67
|
-
}
|
68
|
-
|
69
|
-
|
70
|
-
###############
|
71
|
-
module_function
|
72
|
-
###############
|
73
|
-
|
74
|
-
### Create a string that contains the ANSI codes specified and return it
|
75
|
-
def ansi_code( *attributes )
|
76
|
-
attributes.flatten!
|
77
|
-
attributes.collect! {|at| at.to_s }
|
78
|
-
|
79
|
-
return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
|
80
|
-
attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
|
81
|
-
|
82
|
-
# $stderr.puts " attr is: %p" % [attributes]
|
83
|
-
if attributes.empty?
|
84
|
-
return ''
|
85
|
-
else
|
86
|
-
return "\e[%sm" % attributes
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
### Colorize the given +string+ with the specified +attributes+ and return it, handling
|
92
|
-
### line-endings, color reset, etc.
|
93
|
-
def colorize( *args )
|
94
|
-
string = ''
|
95
|
-
|
96
|
-
if block_given?
|
97
|
-
string = yield
|
98
|
-
else
|
99
|
-
string = args.shift
|
100
|
-
end
|
101
|
-
|
102
|
-
ending = string[/(\s)$/] || ''
|
103
|
-
string = string.rstrip
|
104
|
-
|
105
|
-
return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
### Output a message with highlighting.
|
110
|
-
def message( *msg )
|
111
|
-
$stderr.puts( colorize(:bold) { msg.flatten.join(' ') } )
|
112
|
-
end
|
113
|
-
|
114
|
-
|
115
|
-
### Output a logging message if $VERBOSE is true
|
116
|
-
def trace( *msg )
|
117
|
-
return unless $VERBOSE
|
118
|
-
output = colorize( msg.flatten.join(' '), 'yellow' )
|
119
|
-
$stderr.puts( output )
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
### Return the specified args as a string, quoting any that have a space.
|
124
|
-
def quotelist( *args )
|
125
|
-
return args.flatten.collect {|part| part.to_s =~ /\s/ ? part.to_s.inspect : part.to_s }
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
### Run the specified command +cmd+ with system(), failing if the execution
|
130
|
-
### fails.
|
131
|
-
def run( *cmd )
|
132
|
-
cmd.flatten!
|
133
|
-
|
134
|
-
if cmd.length > 1
|
135
|
-
trace( quotelist(*cmd) )
|
136
|
-
else
|
137
|
-
trace( cmd )
|
138
|
-
end
|
139
|
-
|
140
|
-
system( *cmd )
|
141
|
-
raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
### Run the specified command +cmd+ after redirecting stdout and stderr to the specified
|
146
|
-
### +logpath+, failing if the execution fails.
|
147
|
-
def log_and_run( logpath, *cmd )
|
148
|
-
cmd.flatten!
|
149
|
-
|
150
|
-
if cmd.length > 1
|
151
|
-
trace( quotelist(*cmd) )
|
152
|
-
else
|
153
|
-
trace( cmd )
|
154
|
-
end
|
155
|
-
|
156
|
-
# Eliminate the noise of creating/tearing down the database by
|
157
|
-
# redirecting STDERR/STDOUT to a logfile
|
158
|
-
logfh = File.open( logpath, File::WRONLY|File::CREAT|File::APPEND )
|
159
|
-
system( *cmd, [STDOUT, STDERR] => logfh )
|
160
|
-
|
161
|
-
raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
|
162
|
-
end
|
163
|
-
|
164
|
-
|
165
|
-
### Check the current directory for directories that look like they're
|
166
|
-
### testing directories from previous tests, and tell any postgres instances
|
167
|
-
### running in them to shut down.
|
168
|
-
def stop_existing_postmasters
|
169
|
-
# tmp_test_0.22329534700318
|
170
|
-
pat = Pathname.getwd + 'tmp_test_*'
|
171
|
-
Pathname.glob( pat.to_s ).each do |testdir|
|
172
|
-
datadir = testdir + 'data'
|
173
|
-
pidfile = datadir + 'postmaster.pid'
|
174
|
-
if pidfile.exist? && pid = pidfile.read.chomp.to_i
|
175
|
-
trace "pidfile (%p) exists: %d" % [ pidfile, pid ]
|
176
|
-
begin
|
177
|
-
Process.kill( 0, pid )
|
178
|
-
rescue Errno::ESRCH
|
179
|
-
trace "No postmaster running for %s" % [ datadir ]
|
180
|
-
# Process isn't alive, so don't try to stop it
|
181
|
-
else
|
182
|
-
trace "Stopping lingering database at PID %d" % [ pid ]
|
183
|
-
run 'pg_ctl', '-D', datadir.to_s, '-m', 'fast', 'stop'
|
184
|
-
end
|
185
|
-
else
|
186
|
-
trace "No pidfile (%p)" % [ pidfile ]
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
|
192
|
-
### Set up a PostgreSQL database instance for testing.
|
193
|
-
def setup_testing_db( description )
|
194
|
-
require 'pg'
|
195
|
-
stop_existing_postmasters()
|
196
|
-
|
197
|
-
trace "Setting up test database for #{description}"
|
198
|
-
@test_pgdata = TEST_DIRECTORY + 'data'
|
199
|
-
@test_pgdata.mkpath
|
200
|
-
|
201
|
-
ENV['PGPORT'] ||= "54321"
|
202
|
-
@port = ENV['PGPORT'].to_i
|
203
|
-
ENV['PGHOST'] = 'localhost'
|
204
|
-
@conninfo = "host=localhost port=#{@port} dbname=test"
|
205
|
-
|
206
|
-
@logfile = TEST_DIRECTORY + 'setup.log'
|
207
|
-
trace "Command output logged to #{@logfile}"
|
208
|
-
|
209
|
-
begin
|
210
|
-
unless (@test_pgdata+"postgresql.conf").exist?
|
211
|
-
FileUtils.rm_rf( @test_pgdata, :verbose => $DEBUG )
|
212
|
-
trace "Running initdb"
|
213
|
-
log_and_run @logfile, 'initdb', '-E', 'UTF8', '--no-locale', '-D', @test_pgdata.to_s
|
214
|
-
end
|
215
|
-
|
216
|
-
trace "Starting postgres"
|
217
|
-
log_and_run @logfile, 'pg_ctl', '-w', '-o', "-k #{TEST_DIRECTORY.to_s.dump}",
|
218
|
-
'-D', @test_pgdata.to_s, 'start'
|
219
|
-
sleep 2
|
220
|
-
|
221
|
-
trace "Creating the test DB"
|
222
|
-
log_and_run @logfile, 'psql', '-e', '-c', 'DROP DATABASE IF EXISTS test', 'postgres'
|
223
|
-
log_and_run @logfile, 'createdb', '-e', 'test'
|
224
|
-
|
225
|
-
rescue => err
|
226
|
-
$stderr.puts "%p during test setup: %s" % [ err.class, err.message ]
|
227
|
-
$stderr.puts "See #{@logfile} for details."
|
228
|
-
$stderr.puts *err.backtrace if $DEBUG
|
229
|
-
fail
|
230
|
-
end
|
231
|
-
|
232
|
-
conn = PG.connect( @conninfo )
|
233
|
-
conn.set_notice_processor do |message|
|
234
|
-
$stderr.puts( description + ':' + message ) if $DEBUG
|
235
|
-
end
|
236
|
-
|
237
|
-
return conn
|
238
|
-
end
|
239
|
-
|
240
|
-
|
241
|
-
def teardown_testing_db( conn )
|
242
|
-
trace "Tearing down test database"
|
243
|
-
|
244
|
-
if conn
|
245
|
-
check_for_lingering_connections( conn )
|
246
|
-
conn.finish
|
247
|
-
end
|
248
|
-
|
249
|
-
log_and_run @logfile, 'pg_ctl', '-D', @test_pgdata.to_s, 'stop'
|
250
|
-
end
|
251
|
-
|
252
|
-
|
253
|
-
def check_for_lingering_connections( conn )
|
254
|
-
conn.exec( "SELECT * FROM pg_stat_activity" ) do |res|
|
255
|
-
conns = res.find_all {|row| row['pid'].to_i != conn.backend_pid && ["client backend", nil].include?(row["backend_type"]) }
|
256
|
-
unless conns.empty?
|
257
|
-
puts "Lingering connections remain:"
|
258
|
-
conns.each do |row|
|
259
|
-
puts " [%s] {%s} %s -- %s" % row.values_at( 'pid', 'state', 'application_name', 'query' )
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
|
266
|
-
# Retrieve the names of the column types of a given result set.
|
267
|
-
def result_typenames(res)
|
268
|
-
@conn.exec_params( "SELECT " + res.nfields.times.map{|i| "format_type($#{i*2+1},$#{i*2+2})"}.join(","),
|
269
|
-
res.nfields.times.map{|i| [res.ftype(i), res.fmod(i)] }.flatten ).
|
270
|
-
values[0]
|
271
|
-
end
|
272
|
-
|
273
|
-
|
274
|
-
# A matcher for checking the status of a PG::Connection to ensure it's still
|
275
|
-
# usable.
|
276
|
-
class ConnStillUsableMatcher
|
277
|
-
|
278
|
-
def initialize
|
279
|
-
@conn = nil
|
280
|
-
@problem = nil
|
281
|
-
end
|
282
|
-
|
283
|
-
def matches?( conn )
|
284
|
-
@conn = conn
|
285
|
-
@problem = self.check_for_problems
|
286
|
-
return @problem.nil?
|
287
|
-
end
|
288
|
-
|
289
|
-
def check_for_problems
|
290
|
-
return "is finished" if @conn.finished?
|
291
|
-
return "has bad status" unless @conn.status == PG::CONNECTION_OK
|
292
|
-
return "has bad transaction status (%d)" % [ @conn.transaction_status ] unless
|
293
|
-
@conn.transaction_status.between?( PG::PQTRANS_IDLE, PG::PQTRANS_INTRANS )
|
294
|
-
return "is not usable." unless self.can_exec_query?
|
295
|
-
return nil
|
296
|
-
end
|
297
|
-
|
298
|
-
def can_exec_query?
|
299
|
-
@conn.send_query( "VALUES (1)" )
|
300
|
-
@conn.get_last_result.values == [["1"]]
|
301
|
-
end
|
302
|
-
|
303
|
-
def failure_message
|
304
|
-
return "expected %p to be usable, but it %s" % [ @conn, @problem ]
|
305
|
-
end
|
306
|
-
|
307
|
-
def failure_message_when_negated
|
308
|
-
"expected %p not to be usable, but it still is" % [ @conn ]
|
309
|
-
end
|
310
|
-
|
311
|
-
end
|
312
|
-
|
313
|
-
|
314
|
-
### Return a ConnStillUsableMatcher to be used like:
|
315
|
-
###
|
316
|
-
### expect( pg_conn ).to still_be_usable
|
317
|
-
###
|
318
|
-
def still_be_usable
|
319
|
-
return ConnStillUsableMatcher.new
|
320
|
-
end
|
321
|
-
|
322
|
-
def wait_for_polling_ok(conn, meth = :connect_poll)
|
323
|
-
status = conn.send(meth)
|
324
|
-
|
325
|
-
while status != PG::PGRES_POLLING_OK
|
326
|
-
if status == PG::PGRES_POLLING_READING
|
327
|
-
select( [conn.socket_io], [], [], 5.0 ) or
|
328
|
-
raise "Asynchronous connection timed out!"
|
329
|
-
|
330
|
-
elsif status == PG::PGRES_POLLING_WRITING
|
331
|
-
select( [], [conn.socket_io], [], 5.0 ) or
|
332
|
-
raise "Asynchronous connection timed out!"
|
333
|
-
end
|
334
|
-
status = conn.send(meth)
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def wait_for_query_result(conn)
|
339
|
-
result = nil
|
340
|
-
loop do
|
341
|
-
# Buffer any incoming data on the socket until a full result is ready.
|
342
|
-
conn.consume_input
|
343
|
-
while conn.is_busy
|
344
|
-
select( [conn.socket_io], nil, nil, 5.0 ) or
|
345
|
-
raise "Timeout waiting for query response."
|
346
|
-
conn.consume_input
|
347
|
-
end
|
348
|
-
|
349
|
-
# Fetch the next result. If there isn't one, the query is finished
|
350
|
-
result = conn.get_result || break
|
351
|
-
end
|
352
|
-
result
|
353
|
-
end
|
354
|
-
|
355
|
-
end
|
356
|
-
|
357
|
-
|
358
|
-
RSpec.configure do |config|
|
359
|
-
config.include( PG::TestingHelpers )
|
360
|
-
|
361
|
-
config.run_all_when_everything_filtered = true
|
362
|
-
config.filter_run :focus
|
363
|
-
config.order = 'random'
|
364
|
-
config.mock_with( :rspec ) do |mock|
|
365
|
-
mock.syntax = :expect
|
366
|
-
end
|
367
|
-
|
368
|
-
if RUBY_PLATFORM =~ /mingw|mswin/
|
369
|
-
config.filter_run_excluding :unix
|
370
|
-
else
|
371
|
-
config.filter_run_excluding :windows
|
372
|
-
end
|
373
|
-
config.filter_run_excluding :socket_io unless
|
374
|
-
PG::Connection.instance_methods.map( &:to_sym ).include?( :socket_io )
|
375
|
-
|
376
|
-
config.filter_run_excluding( :postgresql_93 ) if PG.library_version < 90300
|
377
|
-
config.filter_run_excluding( :postgresql_94 ) if PG.library_version < 90400
|
378
|
-
config.filter_run_excluding( :postgresql_95 ) if PG.library_version < 90500
|
379
|
-
config.filter_run_excluding( :postgresql_96 ) if PG.library_version < 90600
|
380
|
-
config.filter_run_excluding( :postgresql_10 ) if PG.library_version < 100000
|
381
|
-
config.filter_run_excluding( :postgresql_12 ) if PG.library_version < 120000
|
382
|
-
end
|