pg 1.5.5 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.appveyor.yml +1 -1
- data/.github/workflows/source-gem.yml +3 -0
- data/Gemfile +6 -0
- data/History.md +24 -4
- data/Rakefile.cross +3 -3
- data/certs/larskanis-2024.pem +24 -0
- data/ext/extconf.rb +3 -0
- data/ext/pg.c +1 -1
- data/ext/pg_connection.c +41 -12
- data/ext/pg_copy_coder.c +6 -6
- data/ext/pg_record_coder.c +5 -5
- data/ext/pg_result.c +2 -2
- data/ext/pg_text_decoder.c +1 -1
- data/ext/pg_text_encoder.c +11 -11
- data/lib/pg/basic_type_map_for_queries.rb +8 -4
- data/lib/pg/basic_type_registry.rb +13 -2
- data/lib/pg/connection.rb +51 -34
- data/lib/pg/exceptions.rb +6 -0
- data/lib/pg/version.rb +1 -1
- data/lib/pg.rb +10 -0
- data.tar.gz.sig +0 -0
- metadata +25 -23
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ce5015b40014ff0d189b2d76645f2ca16abb10d97c87f41b082bedc0e42777a
|
4
|
+
data.tar.gz: 98eef5ac5c50c2e53f38ab1a275935d19a2273346ade5b914c1c4fe59e5aa85b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0112ab86c6581bfdbf0fd7365d973257b6009fcf09595cc450f100858fba6e304ff1e9bbf65d488501bcb8d4fbebeda2c37a957d2fae39dfdb5fff3c00ae249
|
7
|
+
data.tar.gz: fa68b4779ff5b30600e12930ea5ba9e01377fdc65c34a27226b80b0d3a909f65cccec6ea48b1e8833724596aa1cb4f532c706915362b3012453ed5e22283ad11
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.appveyor.yml
CHANGED
@@ -120,6 +120,7 @@ jobs:
|
|
120
120
|
wget https://get.enterprisedb.com/postgresql/postgresql-$PGVERSION-binaries.zip && \
|
121
121
|
sudo mkdir -p /Library/PostgreSQL && \
|
122
122
|
sudo unzip postgresql-$PGVERSION-binaries.zip -d /Library/PostgreSQL/$PGVER && \
|
123
|
+
sudo mv /Library/PostgreSQL/$PGVER/pgsql/* /Library/PostgreSQL/$PGVER/ && \
|
123
124
|
echo /Library/PostgreSQL/$PGVER/bin >> $GITHUB_PATH
|
124
125
|
|
125
126
|
- run: gem update --system 3.3.26
|
@@ -130,6 +131,8 @@ jobs:
|
|
130
131
|
- name: Run specs
|
131
132
|
env:
|
132
133
|
PG_DEBUG: 0
|
134
|
+
# Temprary fix only for Truffleruby-24.0.0:
|
135
|
+
TRUFFLERUBYOPT: --experimental-options --keep-handles-alive
|
133
136
|
run: ruby -rpg -S rspec spec/**/*_spec.rb -cfdoc
|
134
137
|
|
135
138
|
- name: Print logs if job failed
|
data/Gemfile
CHANGED
@@ -11,4 +11,10 @@ group :development, :test do
|
|
11
11
|
gem "rake-compiler-dock", "~> 1.0"
|
12
12
|
gem "rdoc", "~> 6.4"
|
13
13
|
gem "rspec", "~> 3.5"
|
14
|
+
gem "ostruct", "~> 0.5" # for Rakefile.cross
|
15
|
+
# "bigdecimal" is a gem on ruby-3.4+ and it's optional for ruby-pg.
|
16
|
+
# Specs should succeed without it, but 4 examples are then excluded.
|
17
|
+
# With bigdecimal commented out here, corresponding tests are omitted on ruby-3.4+ but are executed on ruby < 3.4.
|
18
|
+
# That way we can check both situations in CI.
|
19
|
+
# gem "bigdecimal", "~> 3.0"
|
14
20
|
end
|
data/History.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## v1.5.7 [2024-07-28] Lars Kanis <lars@greiz-reinsdorf.de>
|
2
|
+
|
3
|
+
- Remove deprecated use of fptr->fd.[#562](https://github.com/ged/ruby-pg/pull/562)
|
4
|
+
Direct access is disallowed since ruby-3.4.
|
5
|
+
- Make `pgconn_connect_poll` close the socket prior to calling `PQconnectPoll`. [#564](https://github.com/ged/ruby-pg/pull/564)
|
6
|
+
This could result in an exception while connecting when used multi threaded.
|
7
|
+
- Fix several typos and improve spelling in documentation and code. [#566](https://github.com/ged/ruby-pg/pull/566)
|
8
|
+
- Add missing PG::RollbackTransaction as an option to exit conn.transaction. [#560](https://github.com/ged/ruby-pg/pull/560)
|
9
|
+
Usage like in rails: https://api.rubyonrails.org/classes/ActiveRecord/Rollback.html
|
10
|
+
- Don't print a warning when bigdecimal is required on ruby-3.4+ [#574](https://github.com/ged/ruby-pg/pull/574)
|
11
|
+
|
12
|
+
|
13
|
+
## v1.5.6 [2024-03-01] Lars Kanis <lars@greiz-reinsdorf.de>
|
14
|
+
|
15
|
+
- Renew address resolution (DNS) in conn.reset. [#558](https://github.com/ged/ruby-pg/pull/558)
|
16
|
+
This is important, if DNS is used for load balancing, etc.
|
17
|
+
- Make bigdecimal an optional dependency. [#556](https://github.com/ged/ruby-pg/pull/556)
|
18
|
+
It's a gem in ruby-3.4+, so that users shouldn't be forced to use it.
|
19
|
+
|
20
|
+
|
1
21
|
## v1.5.5 [2024-02-15] Lars Kanis <lars@greiz-reinsdorf.de>
|
2
22
|
|
3
23
|
- Explicitly retype timespec fields to int64_t to fix compatibility with 32bit arches. [#547](https://github.com/ged/ruby-pg/pull/547)
|
@@ -84,7 +104,7 @@ Removed:
|
|
84
104
|
Repository:
|
85
105
|
|
86
106
|
- `rake test` tries to find PostgreSQL server commands by pg_config [#503](https://github.com/ged/ruby-pg/pull/503)
|
87
|
-
So there's no need to set the PATH
|
107
|
+
So there's no need to set the PATH manually any longer.
|
88
108
|
|
89
109
|
|
90
110
|
## v1.4.6 [2023-02-26] Lars Kanis <lars@greiz-reinsdorf.de>
|
@@ -153,7 +173,7 @@ Added:
|
|
153
173
|
Bugfixes:
|
154
174
|
|
155
175
|
- Try IPv6 and IPv4 addresses, if DNS resolves to both. [#452](https://github.com/ged/ruby-pg/pull/452)
|
156
|
-
- Re-add block-call semantics to PG::Connection.new
|
176
|
+
- Re-add block-call semantics to PG::Connection.new accidentally removed in pg-1.3.0. [#454](https://github.com/ged/ruby-pg/pull/454)
|
157
177
|
- Handle client error after all data consumed in #copy_data for output. [#455](https://github.com/ged/ruby-pg/pull/455)
|
158
178
|
- Avoid spurious keyword argument warning on Ruby 2.7. [#456](https://github.com/ged/ruby-pg/pull/456)
|
159
179
|
- Change connection setup to respect connect_timeout parameter. [#459](https://github.com/ged/ruby-pg/pull/459)
|
@@ -192,7 +212,7 @@ Bugfixes:
|
|
192
212
|
|
193
213
|
- Don't leak IO in case of connection errors. [#439](https://github.com/ged/ruby-pg/pull/439)
|
194
214
|
Previously it was kept open until the PG::Connection was garbage collected.
|
195
|
-
- Fix a performance
|
215
|
+
- Fix a performance regression in conn.get_result noticed in single row mode. [#442](https://github.com/ged/ruby-pg/pull/442)
|
196
216
|
- Fix occasional error Errno::EBADF (Bad file descriptor) while connecting. [#444](https://github.com/ged/ruby-pg/pull/444)
|
197
217
|
- Fix compatibility of res.stream_each* methods with Fiber.scheduler. [#446](https://github.com/ged/ruby-pg/pull/446)
|
198
218
|
- Remove FL_TEST and FL_SET, which are MRI-internal. [#437](https://github.com/ged/ruby-pg/pull/437)
|
@@ -278,7 +298,7 @@ Type cast enhancements:
|
|
278
298
|
- Add PG::BasicTypeMapForQueries::BinaryData for encoding of bytea columns. [#348](https://github.com/ged/ruby-pg/pull/348)
|
279
299
|
- Reduce time to build coder maps and permit to reuse them for several type maps per PG::BasicTypeRegistry::CoderMapsBundle.new(conn) . [#376](https://github.com/ged/ruby-pg/pull/376)
|
280
300
|
- Make BasicTypeRegistry a class and use a global default instance of it.
|
281
|
-
Now a local type registry can be
|
301
|
+
Now a local type registry can be instantiated and given to the type map, to avoid changing shared global states.
|
282
302
|
- Allow PG::BasicTypeMapForQueries to take a Proc as callback for undefined types.
|
283
303
|
|
284
304
|
Other Enhancements:
|
data/Rakefile.cross
CHANGED
@@ -31,8 +31,8 @@ class CrossLibrary < OpenStruct
|
|
31
31
|
self.host_platform = toolchain
|
32
32
|
|
33
33
|
# Cross-compilation constants
|
34
|
-
self.openssl_version = ENV['OPENSSL_VERSION'] || '3.
|
35
|
-
self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '16.
|
34
|
+
self.openssl_version = ENV['OPENSSL_VERSION'] || '3.3.1'
|
35
|
+
self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '16.3'
|
36
36
|
|
37
37
|
# Check if symlinks work in the current working directory.
|
38
38
|
# This fails, if rake-compiler-dock is running on a Windows box.
|
@@ -291,7 +291,7 @@ CrossLibraries.each do |xlib|
|
|
291
291
|
RakeCompilerDock.sh <<-EOT, platform: platform
|
292
292
|
(cp build/gem/gem-*.pem ~/.gem/ || true) &&
|
293
293
|
bundle install --local &&
|
294
|
-
rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem
|
294
|
+
rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEOPTS=-j`nproc` RUBY_CC_VERSION=3.3.0:3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
|
295
295
|
EOT
|
296
296
|
end
|
297
297
|
desc "Build the windows binary gems"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
3
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDAyMjgxOTMxNDdaFw0yNTAy
|
4
|
+
MjcxOTMxNDdaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
5
|
+
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
6
|
+
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
7
|
+
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
8
|
+
8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
|
9
|
+
SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
|
10
|
+
JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
|
11
|
+
eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
|
12
|
+
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
13
|
+
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
14
|
+
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
15
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEArBmHSfnUyNWf3R1Fx0mMHloWGdcKn2D2
|
16
|
+
BsqTApXU2nADiyppIqRq4b9e7hw342uzadSLkoQcEFOxThLRhAcijoWfQVBcsbV/
|
17
|
+
ZsCY1qlUTIJuSWxaSyS4efUX+N4eMNyPM9oW/sphlWFo0DgI34Y9WB6HDzH+O71y
|
18
|
+
R7PARke3f4kYnRJf5yRQLPDrH9UYt9KlBQm6l7XMtr5EMnQt0EfcmZEi9H4t/vS2
|
19
|
+
haxvpFMdAKo4H46GBYNO96r6b74t++vgQSBTg/AFVwvRZwNSrPPcBfb4xxeEAhRR
|
20
|
+
x+LU7feIH7lZ//3buiyD03gLAEtHXai0Y+/VfuWIpwYJAl2BO/tU7FS/dtbJq9oc
|
21
|
+
dI36Yyzy+BrCM0WT4oCsagePNb97FaNhl4F6sM5JEPT0ZPxRx0i3G4TNNIYziVos
|
22
|
+
5wFER6XhvvLDFAMh/jMg+s7Wd5SbSHgHNSUaUGVtdWkVPOer6oF0aLdZUR3CETkn
|
23
|
+
5nWXZma/BUd3YgYA/Xumc6QQqIS4p7mr
|
24
|
+
-----END CERTIFICATE-----
|
data/ext/extconf.rb
CHANGED
@@ -9,6 +9,8 @@ if ENV['MAINTAINER_MODE']
|
|
9
9
|
' -ggdb' <<
|
10
10
|
' -DDEBUG' <<
|
11
11
|
' -pedantic'
|
12
|
+
$LDFLAGS <<
|
13
|
+
' -ggdb'
|
12
14
|
end
|
13
15
|
|
14
16
|
if pgdir = with_config( 'pg' )
|
@@ -158,6 +160,7 @@ have_func 'timegm'
|
|
158
160
|
have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
|
159
161
|
have_func 'rb_gc_mark_movable' # since ruby-2.7
|
160
162
|
have_func 'rb_io_wait' # since ruby-3.0
|
163
|
+
have_func 'rb_io_descriptor' # since ruby-3.1
|
161
164
|
|
162
165
|
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
163
166
|
have_header 'unistd.h'
|
data/ext/pg.c
CHANGED
@@ -543,7 +543,7 @@ Init_pg_ext(void)
|
|
543
543
|
/* Result#result_error_field argument constant
|
544
544
|
*
|
545
545
|
* The SQLSTATE code for the error.
|
546
|
-
* The SQLSTATE code
|
546
|
+
* The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error.
|
547
547
|
* For a list of the possible SQLSTATE codes, see Appendix A.
|
548
548
|
* This field is not localizable, and is always present.
|
549
549
|
*/
|
data/ext/pg_connection.c
CHANGED
@@ -33,8 +33,8 @@ static VALUE pgconn_async_flush(VALUE self);
|
|
33
33
|
#ifdef __GNUC__
|
34
34
|
__attribute__((format(printf, 3, 4)))
|
35
35
|
#endif
|
36
|
-
static void
|
37
|
-
pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...)
|
36
|
+
NORETURN( static void
|
37
|
+
pg_raise_conn_error( VALUE klass, VALUE self, const char *format, ...))
|
38
38
|
{
|
39
39
|
VALUE msg, error;
|
40
40
|
va_list ap;
|
@@ -515,9 +515,9 @@ static VALUE
|
|
515
515
|
pgconn_connect_poll(VALUE self)
|
516
516
|
{
|
517
517
|
PostgresPollingStatusType status;
|
518
|
-
status = gvl_PQconnectPoll(pg_get_pgconn(self));
|
519
518
|
|
520
519
|
pgconn_close_socket_io(self);
|
520
|
+
status = gvl_PQconnectPoll(pg_get_pgconn(self));
|
521
521
|
|
522
522
|
return INT2FIX((int)status);
|
523
523
|
}
|
@@ -563,6 +563,27 @@ pgconn_sync_reset( VALUE self )
|
|
563
563
|
return self;
|
564
564
|
}
|
565
565
|
|
566
|
+
static VALUE
|
567
|
+
pgconn_reset_start2( VALUE self, VALUE conninfo )
|
568
|
+
{
|
569
|
+
t_pg_connection *this = pg_get_connection( self );
|
570
|
+
|
571
|
+
/* Close old connection */
|
572
|
+
pgconn_close_socket_io( self );
|
573
|
+
PQfinish( this->pgconn );
|
574
|
+
|
575
|
+
/* Start new connection */
|
576
|
+
this->pgconn = gvl_PQconnectStart( StringValueCStr(conninfo) );
|
577
|
+
|
578
|
+
if( this->pgconn == NULL )
|
579
|
+
rb_raise(rb_ePGerror, "PQconnectStart() unable to allocate PGconn structure");
|
580
|
+
|
581
|
+
if ( PQstatus(this->pgconn) == CONNECTION_BAD )
|
582
|
+
pg_raise_conn_error( rb_eConnectionBad, self, "%s", PQerrorMessage(this->pgconn));
|
583
|
+
|
584
|
+
return Qnil;
|
585
|
+
}
|
586
|
+
|
566
587
|
/*
|
567
588
|
* call-seq:
|
568
589
|
* conn.reset_start() -> nil
|
@@ -594,9 +615,9 @@ static VALUE
|
|
594
615
|
pgconn_reset_poll(VALUE self)
|
595
616
|
{
|
596
617
|
PostgresPollingStatusType status;
|
597
|
-
status = gvl_PQresetPoll(pg_get_pgconn(self));
|
598
618
|
|
599
619
|
pgconn_close_socket_io(self);
|
620
|
+
status = gvl_PQresetPoll(pg_get_pgconn(self));
|
600
621
|
|
601
622
|
return INT2FIX((int)status);
|
602
623
|
}
|
@@ -2245,6 +2266,17 @@ pgconn_notifies(VALUE self)
|
|
2245
2266
|
return hash;
|
2246
2267
|
}
|
2247
2268
|
|
2269
|
+
#ifndef HAVE_RB_IO_DESCRIPTOR
|
2270
|
+
static int
|
2271
|
+
rb_io_descriptor(VALUE io)
|
2272
|
+
{
|
2273
|
+
Check_Type(io, T_FILE);
|
2274
|
+
rb_io_t *fptr = RFILE(io)->fptr;
|
2275
|
+
rb_io_check_closed(fptr);
|
2276
|
+
return fptr->fd;
|
2277
|
+
}
|
2278
|
+
#endif
|
2279
|
+
|
2248
2280
|
#if defined(_WIN32)
|
2249
2281
|
|
2250
2282
|
/* We use a specialized implementation of rb_io_wait() on Windows.
|
@@ -2265,7 +2297,6 @@ int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
|
2265
2297
|
|
2266
2298
|
static VALUE
|
2267
2299
|
pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2268
|
-
rb_io_t *fptr;
|
2269
2300
|
struct timeval ptimeout;
|
2270
2301
|
|
2271
2302
|
struct timeval aborttime={0,0}, currtime, waittime;
|
@@ -2276,7 +2307,6 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
2276
2307
|
long w32_events = 0;
|
2277
2308
|
DWORD wait_ret;
|
2278
2309
|
|
2279
|
-
GetOpenFile((io), fptr);
|
2280
2310
|
if( !NIL_P(timeout) ){
|
2281
2311
|
ptimeout.tv_sec = (time_t)(NUM2DBL(timeout));
|
2282
2312
|
ptimeout.tv_usec = (time_t)((NUM2DBL(timeout) - (double)ptimeout.tv_sec) * 1e6);
|
@@ -2290,7 +2320,7 @@ pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
2290
2320
|
if(rb_events & PG_RUBY_IO_PRIORITY) w32_events |= FD_OOB;
|
2291
2321
|
|
2292
2322
|
for(;;) {
|
2293
|
-
if ( WSAEventSelect(_get_osfhandle(
|
2323
|
+
if ( WSAEventSelect(_get_osfhandle(rb_io_descriptor(io)), hEvent, w32_events) == SOCKET_ERROR ) {
|
2294
2324
|
WSACloseEvent( hEvent );
|
2295
2325
|
rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
|
2296
2326
|
}
|
@@ -2333,7 +2363,7 @@ static VALUE
|
|
2333
2363
|
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2334
2364
|
#if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
|
2335
2365
|
/* We don't support Fiber.scheduler on Windows ruby-3.0 because there is no fast way to check whether a scheduler is active.
|
2336
|
-
*
|
2366
|
+
* Fortunately ruby-3.1 offers a C-API for it.
|
2337
2367
|
*/
|
2338
2368
|
VALUE scheduler = rb_fiber_scheduler_current();
|
2339
2369
|
|
@@ -2363,16 +2393,14 @@ typedef enum {
|
|
2363
2393
|
|
2364
2394
|
static VALUE
|
2365
2395
|
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2366
|
-
rb_io_t *fptr;
|
2367
2396
|
struct timeval waittime;
|
2368
2397
|
int res;
|
2369
2398
|
|
2370
|
-
GetOpenFile((io), fptr);
|
2371
2399
|
if( !NIL_P(timeout) ){
|
2372
2400
|
waittime.tv_sec = (time_t)(NUM2DBL(timeout));
|
2373
2401
|
waittime.tv_usec = (time_t)((NUM2DBL(timeout) - (double)waittime.tv_sec) * 1e6);
|
2374
2402
|
}
|
2375
|
-
res = rb_wait_for_single_fd(
|
2403
|
+
res = rb_wait_for_single_fd(rb_io_descriptor(io), NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
|
2376
2404
|
|
2377
2405
|
return UINT2NUM(res);
|
2378
2406
|
}
|
@@ -3141,7 +3169,7 @@ pgconn_async_get_last_result(VALUE self)
|
|
3141
3169
|
* Returns:
|
3142
3170
|
* * +nil+ when the connection is already idle
|
3143
3171
|
* * +true+ when some results have been discarded
|
3144
|
-
* * +false+ when a failure
|
3172
|
+
* * +false+ when a failure occurred and the connection was closed
|
3145
3173
|
*
|
3146
3174
|
*/
|
3147
3175
|
static VALUE
|
@@ -4468,6 +4496,7 @@ init_pg_connection(void)
|
|
4468
4496
|
rb_define_method(rb_cPGconn, "finished?", pgconn_finished_p, 0);
|
4469
4497
|
rb_define_method(rb_cPGconn, "sync_reset", pgconn_sync_reset, 0);
|
4470
4498
|
rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0);
|
4499
|
+
rb_define_private_method(rb_cPGconn, "reset_start2", pgconn_reset_start2, 1);
|
4471
4500
|
rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0);
|
4472
4501
|
rb_define_alias(rb_cPGconn, "close", "finish");
|
4473
4502
|
|
data/ext/pg_copy_coder.c
CHANGED
@@ -235,7 +235,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
235
235
|
char *ptr1;
|
236
236
|
char *ptr2;
|
237
237
|
int strlen;
|
238
|
-
int
|
238
|
+
int backslashes;
|
239
239
|
VALUE subint;
|
240
240
|
VALUE entry;
|
241
241
|
|
@@ -286,19 +286,19 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
|
|
286
286
|
ptr2 = current_out + strlen;
|
287
287
|
|
288
288
|
/* count required backlashs */
|
289
|
-
for(
|
289
|
+
for(backslashes = 0; ptr1 != ptr2; ptr1++) {
|
290
290
|
/* Escape backslash itself, newline, carriage return, and the current delimiter character. */
|
291
291
|
if(*ptr1 == '\\' || *ptr1 == '\n' || *ptr1 == '\r' || *ptr1 == this->delimiter){
|
292
|
-
|
292
|
+
backslashes++;
|
293
293
|
}
|
294
294
|
}
|
295
295
|
|
296
296
|
ptr1 = current_out + strlen;
|
297
|
-
ptr2 = current_out + strlen +
|
297
|
+
ptr2 = current_out + strlen + backslashes;
|
298
298
|
current_out = ptr2;
|
299
299
|
|
300
300
|
/* Then store the escaped string on the final position, walking
|
301
|
-
* right to left, until all
|
301
|
+
* right to left, until all backslashes are placed. */
|
302
302
|
while( ptr1 != ptr2 ) {
|
303
303
|
*--ptr2 = *--ptr1;
|
304
304
|
if(*ptr1 == '\\' || *ptr1 == '\n' || *ptr1 == '\r' || *ptr1 == this->delimiter){
|
@@ -391,7 +391,7 @@ pg_bin_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediat
|
|
391
391
|
|
392
392
|
switch(TYPE(entry)){
|
393
393
|
case T_NIL:
|
394
|
-
/* 4 bytes for -1
|
394
|
+
/* 4 bytes for -1 indicating a NULL value */
|
395
395
|
PG_RB_STR_ENSURE_CAPA( *intermediate, 4, current_out, end_capa_ptr );
|
396
396
|
write_nbo32(-1, current_out);
|
397
397
|
current_out += 4;
|
data/ext/pg_record_coder.c
CHANGED
@@ -198,7 +198,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
|
|
198
198
|
char *ptr1;
|
199
199
|
char *ptr2;
|
200
200
|
long strlen;
|
201
|
-
int
|
201
|
+
int backslashes;
|
202
202
|
VALUE subint;
|
203
203
|
VALUE entry;
|
204
204
|
|
@@ -249,19 +249,19 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
|
|
249
249
|
ptr2 = current_out + strlen;
|
250
250
|
|
251
251
|
/* count required backlashs */
|
252
|
-
for(
|
252
|
+
for(backslashes = 0; ptr1 != ptr2; ptr1++) {
|
253
253
|
/* Escape backslash itself, newline, carriage return, and the current delimiter character. */
|
254
254
|
if(*ptr1 == '"' || *ptr1 == '\\'){
|
255
|
-
|
255
|
+
backslashes++;
|
256
256
|
}
|
257
257
|
}
|
258
258
|
|
259
259
|
ptr1 = current_out + strlen;
|
260
|
-
ptr2 = current_out + strlen +
|
260
|
+
ptr2 = current_out + strlen + backslashes;
|
261
261
|
current_out = ptr2;
|
262
262
|
|
263
263
|
/* Then store the escaped string on the final position, walking
|
264
|
-
* right to left, until all
|
264
|
+
* right to left, until all backslashes are placed. */
|
265
265
|
while( ptr1 != ptr2 ) {
|
266
266
|
*--ptr2 = *--ptr1;
|
267
267
|
if(*ptr1 == '"' || *ptr1 == '\\'){
|
data/ext/pg_result.c
CHANGED
@@ -664,7 +664,7 @@ pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
|
|
664
664
|
* An example:
|
665
665
|
*
|
666
666
|
* begin
|
667
|
-
* conn.exec( "SELECT * FROM
|
667
|
+
* conn.exec( "SELECT * FROM nonexistent_table" )
|
668
668
|
* rescue PG::Error => err
|
669
669
|
* p [
|
670
670
|
* err.result.error_field( PG::Result::PG_DIAG_SEVERITY ),
|
@@ -684,7 +684,7 @@ pgresult_verbose_error_message(VALUE self, VALUE verbosity, VALUE show_context)
|
|
684
684
|
*
|
685
685
|
* Outputs:
|
686
686
|
*
|
687
|
-
* ["ERROR", "42P01", "relation \"
|
687
|
+
* ["ERROR", "42P01", "relation \"nonexistent_table\" does not exist", nil, nil,
|
688
688
|
* "15", nil, nil, nil, "path/to/parse_relation.c", "857", "parserOpenTable"]
|
689
689
|
*/
|
690
690
|
static VALUE
|
data/ext/pg_text_decoder.c
CHANGED
@@ -174,7 +174,7 @@ pg_text_dec_numeric(t_pg_coder *conv, const char *val, int len, int tuple, int f
|
|
174
174
|
static VALUE
|
175
175
|
init_pg_text_decoder_numeric(VALUE rb_mPG_TextDecoder)
|
176
176
|
{
|
177
|
-
|
177
|
+
rb_funcall(rb_mPG, rb_intern("require_bigdecimal_without_warning"), 0);
|
178
178
|
s_id_BigDecimal = rb_intern("BigDecimal");
|
179
179
|
|
180
180
|
/* dummy = rb_define_class_under( rb_mPG_TextDecoder, "Numeric", rb_cPG_SimpleDecoder ); */
|
data/ext/pg_text_encoder.c
CHANGED
@@ -377,7 +377,7 @@ init_pg_text_encoder_numeric(VALUE rb_mPG_TextDecoder)
|
|
377
377
|
{
|
378
378
|
s_str_F = rb_str_freeze(rb_str_new_cstr("F"));
|
379
379
|
rb_global_variable(&s_str_F);
|
380
|
-
|
380
|
+
rb_funcall(rb_mPG, rb_intern("require_bigdecimal_without_warning"), 0);
|
381
381
|
s_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
|
382
382
|
|
383
383
|
/* dummy = rb_define_class_under( rb_mPG_TextEncoder, "Numeric", rb_cPG_SimpleEncoder ); */
|
@@ -437,7 +437,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
437
437
|
t_pg_composite_coder *this = _this;
|
438
438
|
char *ptr1;
|
439
439
|
char *ptr2;
|
440
|
-
int
|
440
|
+
int backslashes = 0;
|
441
441
|
int needquote;
|
442
442
|
|
443
443
|
/* count data plus backslashes; detect chars needing quotes */
|
@@ -454,7 +454,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
454
454
|
|
455
455
|
if (ch == '"' || ch == '\\'){
|
456
456
|
needquote = 1;
|
457
|
-
|
457
|
+
backslashes++;
|
458
458
|
} else if (ch == '{' || ch == '}' || ch == this->delimiter ||
|
459
459
|
ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f'){
|
460
460
|
needquote = 1;
|
@@ -463,12 +463,12 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
463
463
|
|
464
464
|
if( needquote ){
|
465
465
|
ptr1 = p_in + strlen;
|
466
|
-
ptr2 = p_out + strlen +
|
466
|
+
ptr2 = p_out + strlen + backslashes + 2;
|
467
467
|
/* Write end quote */
|
468
468
|
*--ptr2 = '"';
|
469
469
|
|
470
470
|
/* Then store the escaped string on the final position, walking
|
471
|
-
* right to left, until all
|
471
|
+
* right to left, until all backslashes are placed. */
|
472
472
|
while( ptr1 != p_in ) {
|
473
473
|
*--ptr2 = *--ptr1;
|
474
474
|
if(*ptr2 == '"' || *ptr2 == '\\'){
|
@@ -477,7 +477,7 @@ quote_array_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
477
477
|
}
|
478
478
|
/* Write start quote */
|
479
479
|
*p_out = '"';
|
480
|
-
return strlen +
|
480
|
+
return strlen + backslashes + 2;
|
481
481
|
} else {
|
482
482
|
if( p_in != p_out )
|
483
483
|
memcpy( p_out, p_in, strlen );
|
@@ -692,22 +692,22 @@ static int
|
|
692
692
|
quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
693
693
|
char *ptr1;
|
694
694
|
char *ptr2;
|
695
|
-
int
|
695
|
+
int backslashes = 0;
|
696
696
|
|
697
697
|
/* count required backlashs */
|
698
698
|
for(ptr1 = p_in; ptr1 != p_in + strlen; ptr1++) {
|
699
699
|
if (*ptr1 == '\''){
|
700
|
-
|
700
|
+
backslashes++;
|
701
701
|
}
|
702
702
|
}
|
703
703
|
|
704
704
|
ptr1 = p_in + strlen;
|
705
|
-
ptr2 = p_out + strlen +
|
705
|
+
ptr2 = p_out + strlen + backslashes + 2;
|
706
706
|
/* Write end quote */
|
707
707
|
*--ptr2 = '\'';
|
708
708
|
|
709
709
|
/* Then store the escaped string on the final position, walking
|
710
|
-
* right to left, until all
|
710
|
+
* right to left, until all backslashes are placed. */
|
711
711
|
while( ptr1 != p_in ) {
|
712
712
|
*--ptr2 = *--ptr1;
|
713
713
|
if(*ptr2 == '\''){
|
@@ -716,7 +716,7 @@ quote_literal_buffer( void *_this, char *p_in, int strlen, char *p_out ){
|
|
716
716
|
}
|
717
717
|
/* Write start quote */
|
718
718
|
*p_out = '\'';
|
719
|
-
return strlen +
|
719
|
+
return strlen + backslashes + 2;
|
720
720
|
}
|
721
721
|
|
722
722
|
|
@@ -166,6 +166,12 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
166
166
|
@textarray_encoder
|
167
167
|
end
|
168
168
|
|
169
|
+
begin
|
170
|
+
PG.require_bigdecimal_without_warning
|
171
|
+
has_bigdecimal = true
|
172
|
+
rescue LoadError
|
173
|
+
end
|
174
|
+
|
169
175
|
DEFAULT_TYPE_MAP = PG.make_shareable({
|
170
176
|
TrueClass => [1, 'bool', 'bool'],
|
171
177
|
FalseClass => [1, 'bool', 'bool'],
|
@@ -173,7 +179,6 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
173
179
|
# to unnecessary type conversions on server side.
|
174
180
|
Integer => [0, 'int8'],
|
175
181
|
Float => [0, 'float8'],
|
176
|
-
BigDecimal => [0, 'numeric'],
|
177
182
|
Time => [0, 'timestamptz'],
|
178
183
|
# We use text format and no type OID for IPAddr, because setting the OID can lead
|
179
184
|
# to unnecessary inet/cidr conversions on the server side.
|
@@ -181,7 +186,7 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
181
186
|
Hash => [0, 'json'],
|
182
187
|
Array => :get_array_type,
|
183
188
|
BinaryData => [1, 'bytea'],
|
184
|
-
})
|
189
|
+
}.merge(has_bigdecimal ? {BigDecimal => [0, 'numeric']} : {}))
|
185
190
|
private_constant :DEFAULT_TYPE_MAP
|
186
191
|
|
187
192
|
DEFAULT_ARRAY_TYPE_MAP = PG.make_shareable({
|
@@ -190,9 +195,8 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
|
|
190
195
|
Integer => [0, '_int8'],
|
191
196
|
String => [0, '_text'],
|
192
197
|
Float => [0, '_float8'],
|
193
|
-
BigDecimal => [0, '_numeric'],
|
194
198
|
Time => [0, '_timestamptz'],
|
195
199
|
IPAddr => [0, '_inet'],
|
196
|
-
})
|
200
|
+
}.merge(has_bigdecimal ? {BigDecimal => [0, '_numeric']} : {}))
|
197
201
|
private_constant :DEFAULT_ARRAY_TYPE_MAP
|
198
202
|
end
|
@@ -171,7 +171,14 @@ class PG::BasicTypeRegistry
|
|
171
171
|
include Checker
|
172
172
|
|
173
173
|
def initialize
|
174
|
-
#
|
174
|
+
# @coders_by_name has a content of
|
175
|
+
# Array< Hash< Symbol: Hash< String: Coder > > >
|
176
|
+
#
|
177
|
+
# The layers are:
|
178
|
+
# * index of Array is 0 (text) and 1 (binary)
|
179
|
+
# * Symbol key in the middle Hash is :encoder and :decoder
|
180
|
+
# * String key in the inner Hash corresponds to the `typname` column in the table pg_type
|
181
|
+
# * Coder value in the inner Hash is the associated coder object
|
175
182
|
@coders_by_name = []
|
176
183
|
end
|
177
184
|
|
@@ -225,7 +232,11 @@ class PG::BasicTypeRegistry
|
|
225
232
|
alias_type 0, 'int8', 'int2'
|
226
233
|
alias_type 0, 'oid', 'int2'
|
227
234
|
|
228
|
-
|
235
|
+
begin
|
236
|
+
PG.require_bigdecimal_without_warning
|
237
|
+
register_type 0, 'numeric', PG::TextEncoder::Numeric, PG::TextDecoder::Numeric
|
238
|
+
rescue LoadError
|
239
|
+
end
|
229
240
|
register_type 0, 'text', PG::TextEncoder::String, PG::TextDecoder::String
|
230
241
|
alias_type 0, 'varchar', 'text'
|
231
242
|
alias_type 0, 'char', 'text'
|
data/lib/pg/connection.rb
CHANGED
@@ -166,7 +166,10 @@ class PG::Connection
|
|
166
166
|
# conn.put_copy_data ['more', 'data', 'to', 'copy']
|
167
167
|
# end
|
168
168
|
#
|
169
|
-
|
169
|
+
# All 4 CopyRow classes can take a type map to specify how the columns are mapped to and from the database format.
|
170
|
+
# For details see the particular CopyRow class description.
|
171
|
+
#
|
172
|
+
# PG::BinaryEncoder::CopyRow can be used to send data in binary format to the server.
|
170
173
|
# In this case copy_data generates the header and trailer data automatically:
|
171
174
|
# enco = PG::BinaryEncoder::CopyRow.new
|
172
175
|
# conn.copy_data "COPY my_table FROM STDIN (FORMAT binary)", enco do
|
@@ -306,6 +309,11 @@ class PG::Connection
|
|
306
309
|
rollback = false
|
307
310
|
exec "BEGIN"
|
308
311
|
yield(self)
|
312
|
+
rescue PG::RollbackTransaction
|
313
|
+
rollback = true
|
314
|
+
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
315
|
+
block
|
316
|
+
exec "ROLLBACK"
|
309
317
|
rescue Exception
|
310
318
|
rollback = true
|
311
319
|
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
@@ -493,7 +501,7 @@ class PG::Connection
|
|
493
501
|
# See also #copy_data.
|
494
502
|
#
|
495
503
|
def put_copy_data(buffer, encoder=nil)
|
496
|
-
# sync_put_copy_data does a non-blocking
|
504
|
+
# sync_put_copy_data does a non-blocking attempt to flush data.
|
497
505
|
until res=sync_put_copy_data(buffer, encoder)
|
498
506
|
# It didn't flush immediately and allocation of more buffering memory failed.
|
499
507
|
# Wait for all data sent by doing a blocking flush.
|
@@ -565,7 +573,12 @@ class PG::Connection
|
|
565
573
|
# Resets the backend connection. This method closes the
|
566
574
|
# backend connection and tries to re-connect.
|
567
575
|
def reset
|
568
|
-
|
576
|
+
iopts = conninfo_hash.compact
|
577
|
+
if iopts[:host] && !iopts[:host].empty? && PG.library_version >= 100000
|
578
|
+
iopts = self.class.send(:resolve_hosts, iopts)
|
579
|
+
end
|
580
|
+
conninfo = self.class.parse_connect_args( iopts );
|
581
|
+
reset_start2(conninfo)
|
569
582
|
async_connect_or_reset(:reset_poll)
|
570
583
|
self
|
571
584
|
end
|
@@ -773,6 +786,40 @@ class PG::Connection
|
|
773
786
|
alias setdb new
|
774
787
|
alias setdblogin new
|
775
788
|
|
789
|
+
# Resolve DNS in Ruby to avoid blocking state while connecting.
|
790
|
+
# Multiple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses.
|
791
|
+
# This requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
|
792
|
+
private def resolve_hosts(iopts)
|
793
|
+
ihosts = iopts[:host].split(",", -1)
|
794
|
+
iports = iopts[:port].split(",", -1)
|
795
|
+
iports = [nil] if iports.size == 0
|
796
|
+
iports = iports * ihosts.size if iports.size == 1
|
797
|
+
raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
|
798
|
+
|
799
|
+
dests = ihosts.each_with_index.flat_map do |mhost, idx|
|
800
|
+
unless host_is_named_pipe?(mhost)
|
801
|
+
if Fiber.respond_to?(:scheduler) &&
|
802
|
+
Fiber.scheduler &&
|
803
|
+
RUBY_VERSION < '3.1.'
|
804
|
+
|
805
|
+
# Use a second thread to avoid blocking of the scheduler.
|
806
|
+
# `TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
|
807
|
+
hostaddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
|
808
|
+
else
|
809
|
+
hostaddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
|
810
|
+
end
|
811
|
+
else
|
812
|
+
# No hostname to resolve (UnixSocket)
|
813
|
+
hostaddrs = [nil]
|
814
|
+
end
|
815
|
+
hostaddrs.map { |hostaddr| [hostaddr, mhost, iports[idx]] }
|
816
|
+
end
|
817
|
+
iopts.merge(
|
818
|
+
hostaddr: dests.map{|d| d[0] }.join(","),
|
819
|
+
host: dests.map{|d| d[1] }.join(","),
|
820
|
+
port: dests.map{|d| d[2] }.join(","))
|
821
|
+
end
|
822
|
+
|
776
823
|
private def connect_to_hosts(*args)
|
777
824
|
option_string = parse_connect_args(*args)
|
778
825
|
iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
@@ -782,37 +829,7 @@ class PG::Connection
|
|
782
829
|
# hostaddr is provided -> no need to resolve hostnames
|
783
830
|
|
784
831
|
elsif iopts[:host] && !iopts[:host].empty? && PG.library_version >= 100000
|
785
|
-
|
786
|
-
# Multiple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses.
|
787
|
-
# This requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
|
788
|
-
ihosts = iopts[:host].split(",", -1)
|
789
|
-
iports = iopts[:port].split(",", -1)
|
790
|
-
iports = [nil] if iports.size == 0
|
791
|
-
iports = iports * ihosts.size if iports.size == 1
|
792
|
-
raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
|
793
|
-
|
794
|
-
dests = ihosts.each_with_index.flat_map do |mhost, idx|
|
795
|
-
unless host_is_named_pipe?(mhost)
|
796
|
-
if Fiber.respond_to?(:scheduler) &&
|
797
|
-
Fiber.scheduler &&
|
798
|
-
RUBY_VERSION < '3.1.'
|
799
|
-
|
800
|
-
# Use a second thread to avoid blocking of the scheduler.
|
801
|
-
# `TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
|
802
|
-
hostaddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
|
803
|
-
else
|
804
|
-
hostaddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
|
805
|
-
end
|
806
|
-
else
|
807
|
-
# No hostname to resolve (UnixSocket)
|
808
|
-
hostaddrs = [nil]
|
809
|
-
end
|
810
|
-
hostaddrs.map { |hostaddr| [hostaddr, mhost, iports[idx]] }
|
811
|
-
end
|
812
|
-
iopts.merge!(
|
813
|
-
hostaddr: dests.map{|d| d[0] }.join(","),
|
814
|
-
host: dests.map{|d| d[1] }.join(","),
|
815
|
-
port: dests.map{|d| d[2] }.join(","))
|
832
|
+
iopts = resolve_hosts(iopts)
|
816
833
|
else
|
817
834
|
# No host given
|
818
835
|
end
|
data/lib/pg/exceptions.rb
CHANGED
@@ -21,5 +21,11 @@ module PG
|
|
21
21
|
class NotInBlockingMode < PG::Error
|
22
22
|
end
|
23
23
|
|
24
|
+
# PG::Connection#transaction uses this exception to distinguish a deliberate rollback from other exceptional situations.
|
25
|
+
# Normally, raising an exception will cause the .transaction method to rollback the database transaction and pass on the exception.
|
26
|
+
# But if you raise an PG::RollbackTransaction exception, then the database transaction will be rolled back, without passing on the exception.
|
27
|
+
class RollbackTransaction < StandardError
|
28
|
+
end
|
29
|
+
|
24
30
|
end # module PG
|
25
31
|
|
data/lib/pg/version.rb
CHANGED
data/lib/pg.rb
CHANGED
@@ -126,4 +126,14 @@ module PG
|
|
126
126
|
Warning.extend(TruffleFixWarn)
|
127
127
|
end
|
128
128
|
|
129
|
+
# Ruby-3.4+ prints a warning, if bigdecimal is required but not in the Gemfile.
|
130
|
+
# But it's a false positive, since we enable bigdecimal depending features only if it's available.
|
131
|
+
# And most people don't need these features.
|
132
|
+
def self.require_bigdecimal_without_warning
|
133
|
+
oldverb, $VERBOSE = $VERBOSE, nil
|
134
|
+
require "bigdecimal"
|
135
|
+
ensure
|
136
|
+
$VERBOSE = oldverb
|
137
|
+
end
|
138
|
+
|
129
139
|
end # module PG
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,36 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
8
8
|
- Lars Kanis
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain:
|
12
11
|
- |
|
13
12
|
-----BEGIN CERTIFICATE-----
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
13
|
+
MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
14
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDAyMjgxOTMxNDdaFw0yNTAy
|
15
|
+
MjcxOTMxNDdaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
16
|
+
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
17
|
+
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
18
|
+
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
19
|
+
8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
|
20
|
+
SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
|
21
|
+
JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
|
22
|
+
eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
|
23
|
+
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
24
|
+
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
25
|
+
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
26
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEArBmHSfnUyNWf3R1Fx0mMHloWGdcKn2D2
|
27
|
+
BsqTApXU2nADiyppIqRq4b9e7hw342uzadSLkoQcEFOxThLRhAcijoWfQVBcsbV/
|
28
|
+
ZsCY1qlUTIJuSWxaSyS4efUX+N4eMNyPM9oW/sphlWFo0DgI34Y9WB6HDzH+O71y
|
29
|
+
R7PARke3f4kYnRJf5yRQLPDrH9UYt9KlBQm6l7XMtr5EMnQt0EfcmZEi9H4t/vS2
|
30
|
+
haxvpFMdAKo4H46GBYNO96r6b74t++vgQSBTg/AFVwvRZwNSrPPcBfb4xxeEAhRR
|
31
|
+
x+LU7feIH7lZ//3buiyD03gLAEtHXai0Y+/VfuWIpwYJAl2BO/tU7FS/dtbJq9oc
|
32
|
+
dI36Yyzy+BrCM0WT4oCsagePNb97FaNhl4F6sM5JEPT0ZPxRx0i3G4TNNIYziVos
|
33
|
+
5wFER6XhvvLDFAMh/jMg+s7Wd5SbSHgHNSUaUGVtdWkVPOer6oF0aLdZUR3CETkn
|
34
|
+
5nWXZma/BUd3YgYA/Xumc6QQqIS4p7mr
|
32
35
|
-----END CERTIFICATE-----
|
33
|
-
date: 2024-
|
36
|
+
date: 2024-07-28 00:00:00.000000000 Z
|
34
37
|
dependencies: []
|
35
38
|
description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
|
36
39
|
9.3 and later.
|
@@ -126,6 +129,7 @@ files:
|
|
126
129
|
- certs/kanis@comcard.de.pem
|
127
130
|
- certs/larskanis-2022.pem
|
128
131
|
- certs/larskanis-2023.pem
|
132
|
+
- certs/larskanis-2024.pem
|
129
133
|
- ext/errorcodes.def
|
130
134
|
- ext/errorcodes.rb
|
131
135
|
- ext/errorcodes.txt
|
@@ -222,7 +226,6 @@ metadata:
|
|
222
226
|
source_code_uri: https://github.com/ged/ruby-pg
|
223
227
|
changelog_uri: https://github.com/ged/ruby-pg/blob/master/History.md
|
224
228
|
documentation_uri: http://deveiate.org/code/pg
|
225
|
-
post_install_message:
|
226
229
|
rdoc_options:
|
227
230
|
- "--main"
|
228
231
|
- README.md
|
@@ -242,7 +245,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
242
245
|
version: '0'
|
243
246
|
requirements: []
|
244
247
|
rubygems_version: 3.6.0.dev
|
245
|
-
signing_key:
|
246
248
|
specification_version: 4
|
247
249
|
summary: Pg is the Ruby interface to the PostgreSQL RDBMS
|
248
250
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|