pg 1.5.5-x64-mingw-ucrt → 1.5.7-x64-mingw-ucrt
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 +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/3.1/pg_ext.so +0 -0
- data/lib/3.2/pg_ext.so +0 -0
- data/lib/3.3/pg_ext.so +0 -0
- 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/lib/x64-mingw-ucrt/libpq.dll +0 -0
- data.tar.gz.sig +0 -0
- metadata +25 -20
- 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: 9e7ec0395615a0debac4f139fdeb76aadca9ad918f72c89df8631114680ccb9f
|
4
|
+
data.tar.gz: ca2579ddcb81da81d8f8fb0d559794d698b9b9df078ec6737751a1a240073c29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2334c4700390384a8ec7654a204d5df32278a65bf89be66e2a43bce6b629406b42a92d14b99e56f501619589e336dc9e02ac386eb0fac25ded33752148513ae
|
7
|
+
data.tar.gz: 19e2f21a74c06a6bc3f0211c109dfe66317ac6b4917b241e2974355066d00386043747a9a4edc6a51789c8117c84c63fad6c041eab26ae5b619d892697e8dcb3
|
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
|
|
data/lib/3.1/pg_ext.so
CHANGED
Binary file
|
data/lib/3.2/pg_ext.so
CHANGED
Binary file
|
data/lib/3.3/pg_ext.so
CHANGED
Binary file
|
@@ -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
|
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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: x64-mingw-ucrt
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -11,26 +11,30 @@ bindir: bin
|
|
11
11
|
cert_chain:
|
12
12
|
- |
|
13
13
|
-----BEGIN CERTIFICATE-----
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
14
|
+
MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
15
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDAyMjgxOTMxNDdaFw0yNTAy
|
16
|
+
MjcxOTMxNDdaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
17
|
+
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
18
|
+
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
19
|
+
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
20
|
+
8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
|
21
|
+
SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
|
22
|
+
JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
|
23
|
+
eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
|
24
|
+
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
25
|
+
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
26
|
+
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
27
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEArBmHSfnUyNWf3R1Fx0mMHloWGdcKn2D2
|
28
|
+
BsqTApXU2nADiyppIqRq4b9e7hw342uzadSLkoQcEFOxThLRhAcijoWfQVBcsbV/
|
29
|
+
ZsCY1qlUTIJuSWxaSyS4efUX+N4eMNyPM9oW/sphlWFo0DgI34Y9WB6HDzH+O71y
|
30
|
+
R7PARke3f4kYnRJf5yRQLPDrH9UYt9KlBQm6l7XMtr5EMnQt0EfcmZEi9H4t/vS2
|
31
|
+
haxvpFMdAKo4H46GBYNO96r6b74t++vgQSBTg/AFVwvRZwNSrPPcBfb4xxeEAhRR
|
32
|
+
x+LU7feIH7lZ//3buiyD03gLAEtHXai0Y+/VfuWIpwYJAl2BO/tU7FS/dtbJq9oc
|
33
|
+
dI36Yyzy+BrCM0WT4oCsagePNb97FaNhl4F6sM5JEPT0ZPxRx0i3G4TNNIYziVos
|
34
|
+
5wFER6XhvvLDFAMh/jMg+s7Wd5SbSHgHNSUaUGVtdWkVPOer6oF0aLdZUR3CETkn
|
35
|
+
5nWXZma/BUd3YgYA/Xumc6QQqIS4p7mr
|
32
36
|
-----END CERTIFICATE-----
|
33
|
-
date: 2024-
|
37
|
+
date: 2024-07-28 00:00:00.000000000 Z
|
34
38
|
dependencies: []
|
35
39
|
description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
|
36
40
|
9.3 and later.
|
@@ -125,6 +129,7 @@ files:
|
|
125
129
|
- certs/kanis@comcard.de.pem
|
126
130
|
- certs/larskanis-2022.pem
|
127
131
|
- certs/larskanis-2023.pem
|
132
|
+
- certs/larskanis-2024.pem
|
128
133
|
- ext/errorcodes.def
|
129
134
|
- ext/errorcodes.rb
|
130
135
|
- ext/errorcodes.txt
|
metadata.gz.sig
CHANGED
Binary file
|