pg 1.3.0.rc2 → 1.3.1
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/.github/workflows/binary-gems.yml +1 -0
- data/.github/workflows/source-gem.yml +1 -1
- data/History.rdoc +21 -3
- data/certs/ged.pem +12 -12
- data/ext/extconf.rb +1 -0
- data/ext/pg_connection.c +122 -15
- data/ext/pg_record_coder.c +1 -1
- data/lib/pg/connection.rb +11 -3
- data/lib/pg/version.rb +1 -1
- data/lib/pg.rb +9 -7
- data.tar.gz.sig +0 -0
- metadata +29 -31
- 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: 066fc0a1f6e951b395f258798f382417c51be61dba5c3999ef6712bb793dc138
|
4
|
+
data.tar.gz: a8944c0abae70b7996067dec9a613f750d8cffbbd69e75ab8c35759a36cada53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c689ccbb0410d6b704144e18d8fb5cf747599f8ad0d84be1d265374f568a9a44b77be6542a36f6c7acdb8dbf862c352e0b0de3d576be82e6d1599801fb7546f0
|
7
|
+
data.tar.gz: e0be5c3b24a89b294f1c7762d027f424670b191437db0f35ee74994389e15a5059899740c137918c25eb50906ee1a8979a9c5fcd67a72ff3b69519d1b096229f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -79,6 +79,7 @@ jobs:
|
|
79
79
|
echo "PGUSER=$env:USERNAME" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
80
80
|
echo "PGPASSWORD=" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
81
81
|
|
82
|
+
- run: gem update --system
|
82
83
|
- run: bundle install
|
83
84
|
- run: gem install --local pg-*${{ matrix.platform }}.gem --verbose
|
84
85
|
- name: Run specs
|
@@ -110,10 +110,10 @@ jobs:
|
|
110
110
|
unzip postgresql-$PGVERSION-binaries.zip && \
|
111
111
|
echo `pwd`/pgsql/bin >> $GITHUB_PATH
|
112
112
|
|
113
|
+
- run: gem update --system
|
113
114
|
- run: bundle install
|
114
115
|
|
115
116
|
- run: gem install --local *.gem --verbose
|
116
|
-
continue-on-error: ${{ matrix.ruby == 'truffleruby-head' }}
|
117
117
|
|
118
118
|
- name: Run specs
|
119
119
|
continue-on-error: ${{ matrix.ruby == 'truffleruby-head' }}
|
data/History.rdoc
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
-
== v1.3.
|
1
|
+
== v1.3.1 [YYYY-MM-DD] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Bugfixes:
|
4
|
+
|
5
|
+
- Fix wrong handling of socket writability on Windows introduced in #417.
|
6
|
+
This caused starvation in conn.put_copy_data.
|
7
|
+
- Fix error in PG.version_string(true). #419
|
8
|
+
- Fix a regression in pg 1.3.0 where Ruby 2.x busy-looping any fractional seconds for every wait. #420
|
9
|
+
|
10
|
+
Enhancements:
|
11
|
+
|
12
|
+
- Raise an error when conn.copy_data is used in nonblocking mode.
|
13
|
+
|
14
|
+
|
15
|
+
== v1.3.0 [2022-01-20] Michael Granger <ged@FaerieMUD.org>
|
2
16
|
|
3
17
|
Install Enhancements:
|
4
18
|
- Print some install help if libpq wasn't found. #396
|
@@ -27,6 +41,8 @@ API Enhancements:
|
|
27
41
|
- Make discard_results scheduler friendly
|
28
42
|
- Do all socket waiting through the conn.socket_io object.
|
29
43
|
- Avoid PG.connect blocking while address resolution by automatically providing the +hostaddr+ parameter.
|
44
|
+
- On Windows Fiber.scheduler support requires Ruby-3.1+.
|
45
|
+
It is also only partly usable since may ruby IO methods are not yet scheduler aware on Windows.
|
30
46
|
- Add support for pipeline mode of PostgreSQL-14. #401
|
31
47
|
- Allow specification of multiple hosts in PostgreSQL URI. #387
|
32
48
|
- Add new method conn.backend_key - used to implement our own cancel method.
|
@@ -46,8 +62,9 @@ Other Enhancements:
|
|
46
62
|
- Add PG::CONNECTION_* constants for conn.status of newer PostgreSQL versions.
|
47
63
|
- Add better support for logical replication. #339
|
48
64
|
- Change conn.socket_io to read+write mode and to a BasicSocket object instead of IO.
|
49
|
-
- Use rb_io_wait() and the conn.socket_io object if available
|
50
|
-
Fall back to rb_wait_for_single_fd() on ruby < 3.0
|
65
|
+
- Use rb_io_wait() and the conn.socket_io object if available for better compatibility to Fiber.scheduler .
|
66
|
+
Fall back to rb_wait_for_single_fd() on ruby < 3.0.
|
67
|
+
- On Windows use a specialized wait function as a workaround for very poor performance of rb_io_wait(). #416
|
51
68
|
|
52
69
|
Bugfixes:
|
53
70
|
- Release GVL while calling PQping which is a blocking method, but it didn't release GVL so far.
|
@@ -62,6 +79,7 @@ Deprecated:
|
|
62
79
|
Removed:
|
63
80
|
- Remove support of ruby-2.2, 2.3 and 2.4. Minimum is ruby-2.5 now.
|
64
81
|
- Remove support for PostgreSQL-9.2. Minimum is PostgreSQL-9.3 now.
|
82
|
+
- Remove constant PG::REVISION, which was broken since pg-1.1.4.
|
65
83
|
|
66
84
|
Repository:
|
67
85
|
- Replace Hoe by Bundler for gem packaging
|
data/certs/ged.pem
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
MIID+
|
3
|
-
|
4
|
-
|
2
|
+
MIID+DCCAmCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
|
3
|
+
REM9RmFlcmllTVVEL0RDPW9yZzAeFw0yMjAxMDcyMzU4MTRaFw0yMzAxMDcyMzU4
|
4
|
+
MTRaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
|
5
5
|
hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
|
6
6
|
L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
|
7
7
|
M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
|
@@ -12,13 +12,13 @@ dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
|
|
12
12
|
ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
|
13
13
|
N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
|
14
14
|
VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DANBgkqhkiG
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
9w0BAQsFAAOCAYEASrm1AbEoxACZ9WXJH3R5axV3U0CA4xaETlL2YT+2nOfVBMQ9
|
16
|
+
0ZlkPx6j4ghKJgAIi1TMfDM2JyPJsppQh8tiNccDjWc62UZRY/dq26cMqf/lcI+a
|
17
|
+
6YBuEYvzZfearwVs8tHnXtwYV3WSCoCOQaB+nq2lA1O+nkKNl41WOsVbNama5jx3
|
18
|
+
8cQtVSEEmZy6jIDJ8c5TmBJ7BQUDEUEWA/A3V42Xyctoj7DvUXWE0lP+X6ypAVSr
|
19
|
+
lFh3TS64D7NTvxkmg7natUoCvobl6kGl4yMaqE4YRTlfuzhpf91TSOntClqrAOsS
|
20
|
+
K1s56WndQj3IoBocdY9mQhDZLtLHofSkymoP8btBlj5SsN24TiF0VMSZlctSCYZg
|
21
|
+
GKyHim/MMlIfGOWsgfioq5jzwmql7W4CDubbb8Lkg70v+hN2E/MnNVAcNE3gyaGc
|
22
|
+
P5YP5BAbNW+gvd3QHRiWTTuhgHrdDnGdXg93N2M5KHn1ug8BtPLQwlcFwEpKnlLn
|
23
|
+
btEP+7EplFuoiMfd
|
24
24
|
-----END CERTIFICATE-----
|
data/ext/extconf.rb
CHANGED
@@ -155,6 +155,7 @@ have_func 'rb_io_wait' # since ruby-3.0
|
|
155
155
|
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
156
156
|
have_header 'unistd.h'
|
157
157
|
have_header 'inttypes.h'
|
158
|
+
have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
|
158
159
|
|
159
160
|
checking_for "C99 variable length arrays" do
|
160
161
|
$defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
|
data/ext/pg_connection.c
CHANGED
@@ -968,8 +968,8 @@ static VALUE pgconn_sync_exec_params( int, VALUE *, VALUE );
|
|
968
968
|
* However #async_exec has two advantages:
|
969
969
|
*
|
970
970
|
* 1. #async_exec can be aborted by signals (like Ctrl-C), while #exec blocks signal processing until the query is answered.
|
971
|
-
* 2. Ruby VM gets notified about IO blocked operations.
|
972
|
-
*
|
971
|
+
* 2. Ruby VM gets notified about IO blocked operations and can pass them through <tt>Fiber.scheduler</tt>.
|
972
|
+
* So only <tt>async_*</tt> methods are compatible to event based schedulers like the async gem.
|
973
973
|
*/
|
974
974
|
static VALUE
|
975
975
|
pgconn_sync_exec(int argc, VALUE *argv, VALUE self)
|
@@ -2207,18 +2207,124 @@ pgconn_notifies(VALUE self)
|
|
2207
2207
|
return hash;
|
2208
2208
|
}
|
2209
2209
|
|
2210
|
+
#if defined(_WIN32)
|
2211
|
+
|
2212
|
+
/* We use a specialized implementation of rb_io_wait() on Windows.
|
2213
|
+
* This is because rb_io_wait() and rb_wait_for_single_fd() are very slow on Windows.
|
2214
|
+
*/
|
2215
|
+
|
2216
|
+
#if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
|
2217
|
+
#include <ruby/fiber/scheduler.h>
|
2218
|
+
#endif
|
2219
|
+
|
2220
|
+
typedef enum {
|
2221
|
+
PG_RUBY_IO_READABLE = RB_WAITFD_IN,
|
2222
|
+
PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
|
2223
|
+
PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
|
2224
|
+
} pg_rb_io_event_t;
|
2225
|
+
|
2226
|
+
int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
|
2227
|
+
|
2228
|
+
static VALUE
|
2229
|
+
pg_rb_thread_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2230
|
+
rb_io_t *fptr;
|
2231
|
+
struct timeval ptimeout;
|
2232
|
+
|
2233
|
+
struct timeval aborttime={0,0}, currtime, waittime;
|
2234
|
+
DWORD timeout_milisec = INFINITE;
|
2235
|
+
HANDLE hEvent = WSACreateEvent();
|
2236
|
+
|
2237
|
+
long rb_events = NUM2UINT(events);
|
2238
|
+
long w32_events = 0;
|
2239
|
+
DWORD wait_ret;
|
2240
|
+
|
2241
|
+
GetOpenFile((io), fptr);
|
2242
|
+
if( !NIL_P(timeout) ){
|
2243
|
+
ptimeout.tv_sec = (time_t)(NUM2DBL(timeout));
|
2244
|
+
ptimeout.tv_usec = (time_t)((NUM2DBL(timeout) - (double)ptimeout.tv_sec) * 1e6);
|
2245
|
+
|
2246
|
+
gettimeofday(&currtime, NULL);
|
2247
|
+
timeradd(&currtime, &ptimeout, &aborttime);
|
2248
|
+
}
|
2249
|
+
|
2250
|
+
if(rb_events & PG_RUBY_IO_READABLE) w32_events |= FD_READ | FD_ACCEPT | FD_CLOSE;
|
2251
|
+
if(rb_events & PG_RUBY_IO_WRITABLE) w32_events |= FD_WRITE | FD_CONNECT;
|
2252
|
+
if(rb_events & PG_RUBY_IO_PRIORITY) w32_events |= FD_OOB;
|
2253
|
+
|
2254
|
+
for(;;) {
|
2255
|
+
if ( WSAEventSelect(_get_osfhandle(fptr->fd), hEvent, w32_events) == SOCKET_ERROR ) {
|
2256
|
+
WSACloseEvent( hEvent );
|
2257
|
+
rb_raise( rb_eConnectionBad, "WSAEventSelect socket error: %d", WSAGetLastError() );
|
2258
|
+
}
|
2259
|
+
|
2260
|
+
if ( !NIL_P(timeout) ) {
|
2261
|
+
gettimeofday(&currtime, NULL);
|
2262
|
+
timersub(&aborttime, &currtime, &waittime);
|
2263
|
+
timeout_milisec = (DWORD)( waittime.tv_sec * 1e3 + waittime.tv_usec / 1e3 );
|
2264
|
+
}
|
2265
|
+
|
2266
|
+
if( NIL_P(timeout) || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
|
2267
|
+
/* Wait for the socket to become readable before checking again */
|
2268
|
+
wait_ret = rb_w32_wait_events( &hEvent, 1, timeout_milisec );
|
2269
|
+
} else {
|
2270
|
+
wait_ret = WAIT_TIMEOUT;
|
2271
|
+
}
|
2272
|
+
|
2273
|
+
if ( wait_ret == WAIT_TIMEOUT ) {
|
2274
|
+
WSACloseEvent( hEvent );
|
2275
|
+
return UINT2NUM(0);
|
2276
|
+
} else if ( wait_ret == WAIT_OBJECT_0 ) {
|
2277
|
+
WSACloseEvent( hEvent );
|
2278
|
+
/* The event we were waiting for. */
|
2279
|
+
return UINT2NUM(rb_events);
|
2280
|
+
} else if ( wait_ret == WAIT_OBJECT_0 + 1) {
|
2281
|
+
/* This indicates interruption from timer thread, GC, exception
|
2282
|
+
* from other threads etc... */
|
2283
|
+
rb_thread_check_ints();
|
2284
|
+
} else if ( wait_ret == WAIT_FAILED ) {
|
2285
|
+
WSACloseEvent( hEvent );
|
2286
|
+
rb_raise( rb_eConnectionBad, "Wait on socket error (WaitForMultipleObjects): %lu", GetLastError() );
|
2287
|
+
} else {
|
2288
|
+
WSACloseEvent( hEvent );
|
2289
|
+
rb_raise( rb_eConnectionBad, "Wait on socket abandoned (WaitForMultipleObjects)" );
|
2290
|
+
}
|
2291
|
+
}
|
2292
|
+
}
|
2293
|
+
|
2294
|
+
static VALUE
|
2295
|
+
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2296
|
+
#if defined(HAVE_RUBY_FIBER_SCHEDULER_H)
|
2297
|
+
/* We don't support Fiber.scheduler on Windows ruby-3.0 because there is no fast way to check whether a scheduler is active.
|
2298
|
+
* Fortunatelly ruby-3.1 offers a C-API for it.
|
2299
|
+
*/
|
2300
|
+
VALUE scheduler = rb_fiber_scheduler_current();
|
2301
|
+
|
2302
|
+
if (!NIL_P(scheduler)) {
|
2303
|
+
return rb_io_wait(io, events, timeout);
|
2304
|
+
}
|
2305
|
+
#endif
|
2306
|
+
return pg_rb_thread_io_wait(io, events, timeout);
|
2307
|
+
}
|
2308
|
+
|
2309
|
+
#elif defined(HAVE_RB_IO_WAIT)
|
2310
|
+
|
2311
|
+
/* Use our own function and constants names, to avoid conflicts with truffleruby-head on its road to ruby-3.0 compatibility. */
|
2312
|
+
#define pg_rb_io_wait rb_io_wait
|
2313
|
+
#define PG_RUBY_IO_READABLE RUBY_IO_READABLE
|
2314
|
+
#define PG_RUBY_IO_WRITABLE RUBY_IO_WRITABLE
|
2315
|
+
#define PG_RUBY_IO_PRIORITY RUBY_IO_PRIORITY
|
2210
2316
|
|
2211
|
-
#
|
2317
|
+
#else
|
2212
2318
|
/* For compat with ruby < 3.0 */
|
2213
2319
|
|
2214
2320
|
typedef enum {
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
}
|
2321
|
+
PG_RUBY_IO_READABLE = RB_WAITFD_IN,
|
2322
|
+
PG_RUBY_IO_WRITABLE = RB_WAITFD_OUT,
|
2323
|
+
PG_RUBY_IO_PRIORITY = RB_WAITFD_PRI,
|
2324
|
+
} pg_rb_io_event_t;
|
2219
2325
|
|
2220
2326
|
static VALUE
|
2221
|
-
|
2327
|
+
pg_rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
2222
2328
|
rb_io_t *fptr;
|
2223
2329
|
struct timeval waittime;
|
2224
2330
|
int res;
|
@@ -2226,7 +2332,7 @@ rb_io_wait(VALUE io, VALUE events, VALUE timeout) {
|
|
2226
2332
|
GetOpenFile((io), fptr);
|
2227
2333
|
if( !NIL_P(timeout) ){
|
2228
2334
|
waittime.tv_sec = (time_t)(NUM2DBL(timeout));
|
2229
|
-
waittime.tv_usec = (time_t)(NUM2DBL(timeout) - (double)waittime.tv_sec);
|
2335
|
+
waittime.tv_usec = (time_t)((NUM2DBL(timeout) - (double)waittime.tv_sec) * 1e6);
|
2230
2336
|
}
|
2231
2337
|
res = rb_wait_for_single_fd(fptr->fd, NUM2UINT(events), NIL_P(timeout) ? NULL : &waittime);
|
2232
2338
|
|
@@ -2267,7 +2373,7 @@ wait_socket_readable( VALUE self, struct timeval *ptimeout, void *(*is_readable)
|
|
2267
2373
|
/* Is the given timeout valid? */
|
2268
2374
|
if( !ptimeout || (waittime.tv_sec >= 0 && waittime.tv_usec >= 0) ){
|
2269
2375
|
/* Wait for the socket to become readable before checking again */
|
2270
|
-
ret =
|
2376
|
+
ret = pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), wait_timeout);
|
2271
2377
|
} else {
|
2272
2378
|
ret = Qfalse;
|
2273
2379
|
}
|
@@ -2304,9 +2410,9 @@ pgconn_async_flush(VALUE self)
|
|
2304
2410
|
/* wait for the socket to become read- or write-ready */
|
2305
2411
|
int events;
|
2306
2412
|
VALUE socket_io = pgconn_socket_io(self);
|
2307
|
-
events = RB_NUM2INT(
|
2413
|
+
events = RB_NUM2INT(pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE | PG_RUBY_IO_WRITABLE), Qnil));
|
2308
2414
|
|
2309
|
-
if (events &
|
2415
|
+
if (events & PG_RUBY_IO_READABLE)
|
2310
2416
|
pgconn_consume_input(self);
|
2311
2417
|
}
|
2312
2418
|
return Qtrue;
|
@@ -3013,10 +3119,10 @@ pgconn_discard_results(VALUE self)
|
|
3013
3119
|
int status;
|
3014
3120
|
|
3015
3121
|
/* pgconn_block() raises an exception in case of errors.
|
3016
|
-
* To avoid this call
|
3122
|
+
* To avoid this call pg_rb_io_wait() and PQconsumeInput() without rb_raise().
|
3017
3123
|
*/
|
3018
3124
|
while( gvl_PQisBusy(conn) ){
|
3019
|
-
|
3125
|
+
pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
|
3020
3126
|
if ( PQconsumeInput(conn) == 0 ) {
|
3021
3127
|
pgconn_close_socket_io(self);
|
3022
3128
|
return Qfalse;
|
@@ -3037,7 +3143,7 @@ pgconn_discard_results(VALUE self)
|
|
3037
3143
|
int st = gvl_PQgetCopyData(conn, &buffer, 1);
|
3038
3144
|
if( st == 0 ) {
|
3039
3145
|
/* would block -> wait for readable data */
|
3040
|
-
|
3146
|
+
pg_rb_io_wait(socket_io, RB_INT2NUM(PG_RUBY_IO_READABLE), Qnil);
|
3041
3147
|
if ( PQconsumeInput(conn) == 0 ) {
|
3042
3148
|
pgconn_close_socket_io(self);
|
3043
3149
|
return Qfalse;
|
@@ -3076,6 +3182,7 @@ pgconn_discard_results(VALUE self)
|
|
3076
3182
|
* #exec is an alias for #async_exec which is almost identical to #sync_exec .
|
3077
3183
|
* #sync_exec is implemented on the simpler synchronous command processing API of libpq, whereas
|
3078
3184
|
* #async_exec is implemented on the asynchronous API and on ruby's IO mechanisms.
|
3185
|
+
* Only #async_exec is compatible to <tt>Fiber.scheduler</tt> based asynchronous IO processing introduced in ruby-3.0.
|
3079
3186
|
* Both methods ensure that other threads can process while waiting for the server to
|
3080
3187
|
* complete the request, but #sync_exec blocks all signals to be processed until the query is finished.
|
3081
3188
|
* This is most notably visible by a delayed reaction to Control+C.
|
data/ext/pg_record_coder.c
CHANGED
@@ -134,7 +134,7 @@ pg_recordcoder_type_map_get(VALUE self)
|
|
134
134
|
* tm = PG::TypeMapByColumn.new([PG::TextEncoder::Float.new]*2)
|
135
135
|
* # Use this type map to encode the record:
|
136
136
|
* PG::TextEncoder::Record.new(type_map: tm).encode([1,2])
|
137
|
-
* # => "(\"1.
|
137
|
+
* # => "(\"1.0\",\"2.0\")"
|
138
138
|
*
|
139
139
|
* Records can also be encoded and decoded directly to and from the database.
|
140
140
|
* This avoids intermediate string allocations and is very fast.
|
data/lib/pg/connection.rb
CHANGED
@@ -7,7 +7,7 @@ require 'io/wait'
|
|
7
7
|
require 'socket'
|
8
8
|
|
9
9
|
# The PostgreSQL connection class. The interface for this class is based on
|
10
|
-
# {libpq}[http://www.postgresql.org/docs/
|
10
|
+
# {libpq}[http://www.postgresql.org/docs/current/libpq.html], the C
|
11
11
|
# application programmer's interface to PostgreSQL. Some familiarity with libpq
|
12
12
|
# is recommended, but not necessary.
|
13
13
|
#
|
@@ -21,6 +21,13 @@ require 'socket'
|
|
21
21
|
#
|
22
22
|
# See the PG::Result class for information on working with the results of a query.
|
23
23
|
#
|
24
|
+
# Many methods of this class have three variants kind of:
|
25
|
+
# 1. #exec - the base method which is an alias to #async_exec .
|
26
|
+
# This is the method that should be used in general.
|
27
|
+
# 2. #async_exec - the async aware version of the method, implemented by libpq's async API.
|
28
|
+
# 3. #sync_exec - the method version that is implemented by blocking function(s) of libpq.
|
29
|
+
#
|
30
|
+
# Sync and async version of the method can be switched by Connection.async_api= , however it is not recommended to change the default.
|
24
31
|
class PG::Connection
|
25
32
|
|
26
33
|
# The order the options are passed to the ::connect method.
|
@@ -234,6 +241,7 @@ class PG::Connection
|
|
234
241
|
# ["more", "data", "to", "copy"]
|
235
242
|
|
236
243
|
def copy_data( sql, coder=nil )
|
244
|
+
raise PG::NotInBlockingMode, "copy_data can not be used in nonblocking mode" if nonblocking?
|
237
245
|
res = exec( sql )
|
238
246
|
|
239
247
|
case res.result_status
|
@@ -378,7 +386,7 @@ class PG::Connection
|
|
378
386
|
# If the optional code block is given, it will be passed <i>result</i> as an argument,
|
379
387
|
# and the PG::Result object will automatically be cleared when the block terminates.
|
380
388
|
# In this instance, <code>conn.exec</code> returns the value of the block.
|
381
|
-
def get_result
|
389
|
+
def get_result
|
382
390
|
block
|
383
391
|
sync_get_result
|
384
392
|
end
|
@@ -690,7 +698,7 @@ class PG::Connection
|
|
690
698
|
#
|
691
699
|
# Raises a PG::Error if the connection fails.
|
692
700
|
def new(*args, **kwargs)
|
693
|
-
conn =
|
701
|
+
conn = self.connect_start(*args, **kwargs ) or
|
694
702
|
raise(PG::Error, "Unable to create a new connection")
|
695
703
|
|
696
704
|
raise(PG::ConnectionBad, conn.error_message) if conn.status == PG::CONNECTION_BAD
|
data/lib/pg/version.rb
CHANGED
data/lib/pg.rb
CHANGED
@@ -53,18 +53,20 @@ module PG
|
|
53
53
|
|
54
54
|
class NotAllCopyDataRetrieved < PG::Error
|
55
55
|
end
|
56
|
+
class NotInBlockingMode < PG::Error
|
57
|
+
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
return
|
59
|
+
# Get the PG library version.
|
60
|
+
#
|
61
|
+
# +include_buildnum+ is no longer used and any value passed will be ignored.
|
62
|
+
def self::version_string( include_buildnum=nil )
|
63
|
+
return "%s %s" % [ self.name, VERSION ]
|
62
64
|
end
|
63
65
|
|
64
66
|
|
65
67
|
### Convenience alias for PG::Connection.new.
|
66
|
-
def self::connect( *args )
|
67
|
-
return PG::Connection.new( *args )
|
68
|
+
def self::connect( *args, **kwargs )
|
69
|
+
return PG::Connection.new( *args, **kwargs )
|
68
70
|
end
|
69
71
|
|
70
72
|
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,42 +1,40 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
8
8
|
- Lars Kanis
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
d5T9wAD7jW/0seVujw+76/YOJWO3Dft+FQmMBbdd8s3J47HbN9R2mDt6fl6he+X/
|
37
|
-
gw==
|
14
|
+
MIID+DCCAmCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
|
15
|
+
REM9RmFlcmllTVVEL0RDPW9yZzAeFw0yMjAxMDcyMzU4MTRaFw0yMzAxMDcyMzU4
|
16
|
+
MTRaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
|
17
|
+
hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
|
18
|
+
L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
|
19
|
+
M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
|
20
|
+
5PU2AEbf04GGSrmqADGWXeaslaoRdb1fu/0M5qfPTRn5V39sWD9umuDAF9qqil/x
|
21
|
+
Sl6phTvgBrG8GExHbNZpLARd3xrBYLEFsX7RvBn2UPfgsrtvpdXjsHGfpT3IPN+B
|
22
|
+
vQ66lts4alKC69TE5cuKasWBm+16A4aEe3XdZBRNmtOu/g81gvwA7fkJHKllJuaI
|
23
|
+
dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
|
24
|
+
ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
|
25
|
+
N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
|
26
|
+
VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DANBgkqhkiG
|
27
|
+
9w0BAQsFAAOCAYEASrm1AbEoxACZ9WXJH3R5axV3U0CA4xaETlL2YT+2nOfVBMQ9
|
28
|
+
0ZlkPx6j4ghKJgAIi1TMfDM2JyPJsppQh8tiNccDjWc62UZRY/dq26cMqf/lcI+a
|
29
|
+
6YBuEYvzZfearwVs8tHnXtwYV3WSCoCOQaB+nq2lA1O+nkKNl41WOsVbNama5jx3
|
30
|
+
8cQtVSEEmZy6jIDJ8c5TmBJ7BQUDEUEWA/A3V42Xyctoj7DvUXWE0lP+X6ypAVSr
|
31
|
+
lFh3TS64D7NTvxkmg7natUoCvobl6kGl4yMaqE4YRTlfuzhpf91TSOntClqrAOsS
|
32
|
+
K1s56WndQj3IoBocdY9mQhDZLtLHofSkymoP8btBlj5SsN24TiF0VMSZlctSCYZg
|
33
|
+
GKyHim/MMlIfGOWsgfioq5jzwmql7W4CDubbb8Lkg70v+hN2E/MnNVAcNE3gyaGc
|
34
|
+
P5YP5BAbNW+gvd3QHRiWTTuhgHrdDnGdXg93N2M5KHn1ug8BtPLQwlcFwEpKnlLn
|
35
|
+
btEP+7EplFuoiMfd
|
38
36
|
-----END CERTIFICATE-----
|
39
|
-
date: 2022-01
|
37
|
+
date: 2022-02-01 00:00:00.000000000 Z
|
40
38
|
dependencies: []
|
41
39
|
description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
|
42
40
|
9.3 and later.
|
@@ -160,7 +158,7 @@ metadata:
|
|
160
158
|
source_code_uri: https://github.com/ged/ruby-pg
|
161
159
|
changelog_uri: https://github.com/ged/ruby-pg/blob/master/History.rdoc
|
162
160
|
documentation_uri: http://deveiate.org/code/pg
|
163
|
-
post_install_message:
|
161
|
+
post_install_message:
|
164
162
|
rdoc_options:
|
165
163
|
- "--main"
|
166
164
|
- README.rdoc
|
@@ -173,12 +171,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
171
|
version: '2.5'
|
174
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
173
|
requirements:
|
176
|
-
- - "
|
174
|
+
- - ">="
|
177
175
|
- !ruby/object:Gem::Version
|
178
|
-
version:
|
176
|
+
version: '0'
|
179
177
|
requirements: []
|
180
178
|
rubygems_version: 3.2.22
|
181
|
-
signing_key:
|
179
|
+
signing_key:
|
182
180
|
specification_version: 4
|
183
181
|
summary: Pg is the Ruby interface to the PostgreSQL RDBMS
|
184
182
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|