pg 1.4.2-x64-mingw-ucrt → 1.4.4-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e314b891dc2ddfcb46fd85b01aa5867af39fba5fea4d349921e487b1b5190319
4
- data.tar.gz: 96820e836cdccdb3d961a1a9ab16fd254ce977e95bcdc78d73649ad94f26e5c2
3
+ metadata.gz: 93015da5c2a1828248ea58ea84210d0e0cc3b637cabbe05a7df149df39abfb51
4
+ data.tar.gz: 9411741276f87b9aff595b1d2f20ce624c9e9a0a6c0c17b9815994aa4ee70caa
5
5
  SHA512:
6
- metadata.gz: bd853ba3e8b1012fa1a37746d87763e795f53eed74b85341b5050308d4c69ff0129bfe13fd5e05f9548e0fdbe932c904b0a30c0646a8b036ea29e87222b0fcb5
7
- data.tar.gz: 87b218527cfb921065de9561fe42dea9f082c1c924658ced529d222cc51aba439ce186c2fb6901aab13241647ecfcbe1ec2c3f30ed0b8160f2dea7e8fc3e8a17
6
+ metadata.gz: 1f81e2b66ac210a1aafaa2d853be224ce9f98c490a2922fb05657fc7061774b55cfd8a752d144dfb550c5abd7aecd8f415e4f77954949ab97e6ef3bb8d15b94f
7
+ data.tar.gz: 56c08d9b66245d68f5d19f696734f363b292e81edd6a265b1f6f8c07756afd04996ea38d6aad26afe05bf0d638b5cc97447e8355c9af9723637ada79ab37e97f
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1 @@
1
- ��ɻ�7[v{ZW&rH|�|����0����(y��DYwe���Ĕ>�������]��q����^���mf��(������9%2<~�� D�m���bmP~D��01�0�Ij�ׂwx6v���̀���ص�0�Iv��ZK�b�n���s�ldTӟ>�+fo<
2
- 6m;n��X��Z��J$ULN0��@0x���� k
1
+ 'a�`kCsuf�Go��Pp��K\L)E2t�:�tV+�~A��0$YF��+��Z�ъ� T8���UBF���:gG�C
@@ -45,7 +45,7 @@ jobs:
45
45
  include:
46
46
  - ruby: "3.1"
47
47
  platform: "x64-mingw-ucrt"
48
- PGVERSION: 14.2-1-windows-x64
48
+ PGVERSION: 15.0-rc1-windows-x64
49
49
  - ruby: "2.5"
50
50
  platform: "x64-mingw32"
51
51
  PGVERSION: 10.20-1-windows
@@ -83,4 +83,4 @@ jobs:
83
83
  - run: bundle install
84
84
  - run: gem install --local pg-*${{ matrix.platform }}.gem --verbose
85
85
  - name: Run specs
86
- run: ruby -rpg -S rspec spec/**/*_spec.rb
86
+ run: ruby -rpg -S rspec -fd spec/**/*_spec.rb
@@ -31,7 +31,7 @@ jobs:
31
31
  include:
32
32
  - os: windows
33
33
  ruby: "head"
34
- PGVERSION: 14.2-1-windows-x64
34
+ PGVERSION: 15.0-rc1-windows-x64
35
35
  PGVER: "14"
36
36
  - os: windows
37
37
  ruby: "2.5"
@@ -54,13 +54,14 @@ jobs:
54
54
  PGVER: "14"
55
55
  - os: macos
56
56
  ruby: "head"
57
- PGVERSION: 14.2-1-osx
58
- PGVER: "14"
57
+ PGVERSION: 13.8-1-osx
58
+ PGVER: "13"
59
59
 
60
60
  runs-on: ${{ matrix.os }}-latest
61
61
  env:
62
62
  PGVERSION: ${{ matrix.PGVERSION }}
63
63
  PGVER: ${{ matrix.PGVER }}
64
+ MAKE: make -j2 V=1
64
65
 
65
66
  steps:
66
67
  - uses: actions/checkout@v2
@@ -107,8 +108,9 @@ jobs:
107
108
  if: matrix.os == 'macos'
108
109
  run: |
109
110
  wget https://get.enterprisedb.com/postgresql/postgresql-$PGVERSION-binaries.zip && \
110
- unzip postgresql-$PGVERSION-binaries.zip && \
111
- echo `pwd`/pgsql/bin >> $GITHUB_PATH
111
+ sudo mkdir -p /Library/PostgreSQL && \
112
+ sudo unzip postgresql-$PGVERSION-binaries.zip -d /Library/PostgreSQL/$PGVER && \
113
+ echo /Library/PostgreSQL/$PGVER/bin >> $GITHUB_PATH
112
114
 
113
115
  - run: gem update --system
114
116
  - run: bundle install
data/History.rdoc CHANGED
@@ -1,3 +1,19 @@
1
+ == v1.4.4 [2022-10-11] Lars Kanis <lars@greiz-reinsdorf.de>
2
+
3
+ - Revert to let libpq do the host iteration while connecting. #485
4
+ Ensure that parameter `connect_timeout` is still respected.
5
+ - Handle multiple hosts in the connection string, where only one host has writable session. #476
6
+ - Add some useful information to PG::Connection#inspect. #487
7
+ - Support new pgresult_stream_any API in sequel_pg-1.17.0. #481
8
+ - Update Windows fat binary gem to PostgreSQL-14.5.
9
+
10
+
11
+ == v1.4.3 [2022-08-09] Lars Kanis <lars@greiz-reinsdorf.de>
12
+
13
+ - Avoid memory bloat possible in put_copy_data in pg-1.4.0 to 1.4.2. #473
14
+ - Use Encoding::BINARY for JOHAB, removing some useless code. #472
15
+
16
+
1
17
  == v1.4.2 [2022-07-27] Lars Kanis <lars@greiz-reinsdorf.de>
2
18
 
3
19
  Bugfixes:
data/README.rdoc CHANGED
@@ -171,12 +171,31 @@ The following type maps are prefilled with type mappings from the PG::BasicTypeR
171
171
  To report bugs, suggest features, or check out the source with Git,
172
172
  {check out the project page}[https://github.com/ged/ruby-pg].
173
173
 
174
- After checking out the source, run:
174
+ After checking out the source, install all dependencies:
175
175
 
176
- $ rake newb
176
+ $ bundle install
177
177
 
178
- This task will install any missing dependencies, run the tests/specs, and
179
- generate the API documentation.
178
+ Cleanup extension files, packaging files, test databases:
179
+
180
+ $ rake clean
181
+
182
+ Compile extension:
183
+
184
+ $ rake compile
185
+
186
+ Run tests/specs with PostgreSQL tools like `initdb` in the path:
187
+
188
+ $ PATH=$PATH:/usr/lib/postgresql/14/bin rake test
189
+
190
+ Or run a specific test with the line number:
191
+
192
+ $ PATH=$PATH:/usr/lib/postgresql/14/bin rspec -Ilib -fd spec/pg/connection_spec.rb:455
193
+
194
+ Generate the API documentation:
195
+
196
+ $ rake docs
197
+
198
+ Make sure, that all bugs and new features are verified by tests.
180
199
 
181
200
  The current maintainers are Michael Granger <ged@FaerieMUD.org> and
182
201
  Lars Kanis <lars@greiz-reinsdorf.de>.
@@ -184,7 +203,7 @@ Lars Kanis <lars@greiz-reinsdorf.de>.
184
203
 
185
204
  == Copying
186
205
 
187
- Copyright (c) 1997-2019 by the authors.
206
+ Copyright (c) 1997-2022 by the authors.
188
207
 
189
208
  * Jeff Davis <ruby-pg@j-davis.com>
190
209
  * Guy Decoux (ts) <decoux@moulon.inra.fr>
data/Rakefile CHANGED
@@ -16,14 +16,14 @@ LIBDIR = BASEDIR + 'lib'
16
16
  EXTDIR = BASEDIR + 'ext'
17
17
  PKGDIR = BASEDIR + 'pkg'
18
18
  TMPDIR = BASEDIR + 'tmp'
19
- TESTDIR = BASEDIR + "tmp_test_specs"
19
+ TESTDIR = BASEDIR + "tmp_test_*"
20
20
 
21
21
  DLEXT = RbConfig::CONFIG['DLEXT']
22
22
  EXT = LIBDIR + "pg_ext.#{DLEXT}"
23
23
 
24
24
  GEMSPEC = 'pg.gemspec'
25
25
 
26
- CLOBBER.include( TESTDIR.to_s )
26
+ CLEAN.include( TESTDIR.to_s )
27
27
  CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
28
28
  CLEAN.include "lib/*/libpq.dll"
29
29
  CLEAN.include "lib/pg_ext.*"
data/Rakefile.cross CHANGED
@@ -32,7 +32,7 @@ class CrossLibrary < OpenStruct
32
32
 
33
33
  # Cross-compilation constants
34
34
  self.openssl_version = ENV['OPENSSL_VERSION'] || '1.1.1q'
35
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '14.4'
35
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '14.5'
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.
data/ext/pg.c CHANGED
@@ -47,7 +47,6 @@
47
47
  */
48
48
 
49
49
  #include "pg.h"
50
- #include "pg_config.h"
51
50
 
52
51
  int pg_skip_deprecation_warning;
53
52
  VALUE rb_mPG;
@@ -127,26 +126,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
127
126
  static struct st_table *enc_pg2ruby;
128
127
 
129
128
 
130
- /*
131
- * Look up the JOHAB encoding, creating it as a dummy encoding if it's not
132
- * already defined.
133
- */
134
- static rb_encoding *
135
- pg_find_or_create_johab(void)
136
- {
137
- static const char * const aliases[] = { "JOHAB", "Windows-1361", "CP1361" };
138
- int enc_index;
139
- size_t i;
140
-
141
- for (i = 0; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
142
- enc_index = rb_enc_find_index(aliases[i]);
143
- if (enc_index > 0) return rb_enc_from_index(enc_index);
144
- }
145
-
146
- enc_index = rb_define_dummy_encoding(aliases[0]);
147
- return rb_enc_from_index(enc_index);
148
- }
149
-
150
129
  /*
151
130
  * Return the given PostgreSQL encoding ID as an rb_encoding.
152
131
  *
@@ -187,10 +166,6 @@ pg_get_pg_encname_as_rb_encoding( const char *pg_encname )
187
166
  return rb_enc_find( pg_enc_pg2ruby_mapping[i][1] );
188
167
  }
189
168
 
190
- /* JOHAB isn't a builtin encoding, so make up a dummy encoding if it's seen */
191
- if ( strncmp(pg_encname, "JOHAB", 5) == 0 )
192
- return pg_find_or_create_johab();
193
-
194
169
  /* Fallthrough to ASCII-8BIT */
195
170
  return rb_ascii8bit_encoding();
196
171
  }
@@ -377,7 +352,7 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
377
352
  **************************************************************************/
378
353
 
379
354
  void
380
- Init_pg_ext()
355
+ Init_pg_ext(void)
381
356
  {
382
357
  if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
383
358
  /* Set all bits to disable all deprecation warnings. */
data/ext/pg.h CHANGED
@@ -57,6 +57,7 @@
57
57
  #endif
58
58
 
59
59
  /* PostgreSQL headers */
60
+ #include "pg_config.h"
60
61
  #include "libpq-fe.h"
61
62
  #include "libpq/libpq-fs.h" /* large-object interface */
62
63
  #include "pg_config_manual.h"
@@ -205,7 +205,7 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
205
205
  */
206
206
 
207
207
  void
208
- init_pg_binary_decoder()
208
+ init_pg_binary_decoder(void)
209
209
  {
210
210
  /* This module encapsulates all decoder classes with binary input format */
211
211
  rb_mPG_BinaryDecoder = rb_define_module_under( rb_mPG, "BinaryDecoder" );
@@ -139,7 +139,7 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
139
139
  }
140
140
 
141
141
  void
142
- init_pg_binary_encoder()
142
+ init_pg_binary_encoder(void)
143
143
  {
144
144
  /* This module encapsulates all encoder classes with binary output format */
145
145
  rb_mPG_BinaryEncoder = rb_define_module_under( rb_mPG, "BinaryEncoder" );
data/ext/pg_coder.c CHANGED
@@ -537,7 +537,7 @@ pg_coder_dec_func(t_pg_coder *this, int binary)
537
537
 
538
538
 
539
539
  void
540
- init_pg_coder()
540
+ init_pg_coder(void)
541
541
  {
542
542
  s_id_encode = rb_intern("encode");
543
543
  s_id_decode = rb_intern("decode");
data/ext/pg_connection.c CHANGED
@@ -266,6 +266,7 @@ pgconn_s_allocate( VALUE klass )
266
266
  this->encoder_for_put_copy_data = Qnil;
267
267
  this->decoder_for_get_copy_data = Qnil;
268
268
  this->trace_stream = Qnil;
269
+ rb_ivar_set(self, rb_intern("@calls_to_put_copy_data"), INT2FIX(0));
269
270
 
270
271
  return self;
271
272
  }
@@ -1526,8 +1527,7 @@ pgconn_sync_describe_prepared(VALUE self, VALUE stmt_name)
1526
1527
  * It's not recommended to use explicit sync or async variants but #describe_portal instead, unless you have a good reason to do so.
1527
1528
  */
1528
1529
  static VALUE
1529
- pgconn_sync_describe_portal(self, stmt_name)
1530
- VALUE self, stmt_name;
1530
+ pgconn_sync_describe_portal(VALUE self, VALUE stmt_name)
1531
1531
  {
1532
1532
  PGresult *result;
1533
1533
  VALUE rb_pgresult;
@@ -4325,7 +4325,7 @@ pgconn_field_name_type_get(VALUE self)
4325
4325
  * Document-class: PG::Connection
4326
4326
  */
4327
4327
  void
4328
- init_pg_connection()
4328
+ init_pg_connection(void)
4329
4329
  {
4330
4330
  s_id_encode = rb_intern("encode");
4331
4331
  s_id_autoclose_set = rb_intern("autoclose=");
data/ext/pg_copy_coder.c CHANGED
@@ -592,7 +592,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
592
592
 
593
593
 
594
594
  void
595
- init_pg_copycoder()
595
+ init_pg_copycoder(void)
596
596
  {
597
597
  /* Document-class: PG::CopyCoder < PG::Coder
598
598
  *
data/ext/pg_errors.c CHANGED
@@ -70,7 +70,7 @@ lookup_error_class(const char *sqlstate)
70
70
  }
71
71
 
72
72
  void
73
- init_pg_errors()
73
+ init_pg_errors(void)
74
74
  {
75
75
  rb_hErrors = rb_hash_new();
76
76
  rb_define_const( rb_mPG, "ERROR_CLASSES", rb_hErrors );
@@ -494,7 +494,7 @@ pg_text_dec_record(t_pg_coder *conv, char *input_line, int len, int _tuple, int
494
494
 
495
495
 
496
496
  void
497
- init_pg_recordcoder()
497
+ init_pg_recordcoder(void)
498
498
  {
499
499
  /* Document-class: PG::RecordCoder < PG::Coder
500
500
  *
data/ext/pg_result.c CHANGED
@@ -1382,21 +1382,20 @@ pgresult_type_map_get(VALUE self)
1382
1382
  }
1383
1383
 
1384
1384
 
1385
- static void
1385
+ static int
1386
1386
  yield_hash(VALUE self, int ntuples, int nfields, void *data)
1387
1387
  {
1388
1388
  int tuple_num;
1389
- t_pg_result *this = pgresult_get_this(self);
1390
1389
  UNUSED(nfields);
1391
1390
 
1392
1391
  for(tuple_num = 0; tuple_num < ntuples; tuple_num++) {
1393
1392
  rb_yield(pgresult_aref(self, INT2NUM(tuple_num)));
1394
1393
  }
1395
1394
 
1396
- pgresult_clear( this );
1395
+ return 1; /* clear the result */
1397
1396
  }
1398
1397
 
1399
- static void
1398
+ static int
1400
1399
  yield_array(VALUE self, int ntuples, int nfields, void *data)
1401
1400
  {
1402
1401
  int row;
@@ -1413,10 +1412,10 @@ yield_array(VALUE self, int ntuples, int nfields, void *data)
1413
1412
  rb_yield( rb_ary_new4( nfields, row_values ));
1414
1413
  }
1415
1414
 
1416
- pgresult_clear( this );
1415
+ return 1; /* clear the result */
1417
1416
  }
1418
1417
 
1419
- static void
1418
+ static int
1420
1419
  yield_tuple(VALUE self, int ntuples, int nfields, void *data)
1421
1420
  {
1422
1421
  int tuple_num;
@@ -1434,11 +1433,12 @@ yield_tuple(VALUE self, int ntuples, int nfields, void *data)
1434
1433
  VALUE tuple = pgresult_tuple(copy, INT2FIX(tuple_num));
1435
1434
  rb_yield( tuple );
1436
1435
  }
1436
+ return 0; /* don't clear the result */
1437
1437
  }
1438
1438
 
1439
1439
  /* Non-static, and data pointer for use by sequel_pg */
1440
1440
  VALUE
1441
- pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int, void*), void* data)
1441
+ pgresult_stream_any(VALUE self, int (*yielder)(VALUE, int, int, void*), void* data)
1442
1442
  {
1443
1443
  t_pg_result *this;
1444
1444
  int nfields;
@@ -1467,7 +1467,9 @@ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int, void*), void* d
1467
1467
  pg_result_check( self );
1468
1468
  }
1469
1469
 
1470
- yielder( self, ntuples, nfields, data );
1470
+ if( yielder( self, ntuples, nfields, data ) ){
1471
+ pgresult_clear( this );
1472
+ }
1471
1473
 
1472
1474
  if( gvl_PQisBusy(pgconn) ){
1473
1475
  /* wait for input (without blocking) before reading each result */
@@ -1617,7 +1619,7 @@ pgresult_field_name_type_get(VALUE self)
1617
1619
  }
1618
1620
 
1619
1621
  void
1620
- init_pg_result()
1622
+ init_pg_result(void)
1621
1623
  {
1622
1624
  sym_string = ID2SYM(rb_intern("string"));
1623
1625
  sym_symbol = ID2SYM(rb_intern("symbol"));
@@ -923,7 +923,7 @@ pg_text_dec_inet(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
923
923
  }
924
924
 
925
925
  void
926
- init_pg_text_decoder()
926
+ init_pg_text_decoder(void)
927
927
  {
928
928
  rb_require("ipaddr");
929
929
  s_IPAddr = rb_funcall(rb_cObject, rb_intern("const_get"), 1, rb_str_new2("IPAddr"));
@@ -775,7 +775,7 @@ pg_text_enc_to_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedi
775
775
 
776
776
 
777
777
  void
778
- init_pg_text_encoder()
778
+ init_pg_text_encoder(void)
779
779
  {
780
780
  s_id_encode = rb_intern("encode");
781
781
  s_id_to_i = rb_intern("to_i");
data/ext/pg_tuple.c CHANGED
@@ -545,7 +545,7 @@ pg_tuple_load(VALUE self, VALUE a)
545
545
  }
546
546
 
547
547
  void
548
- init_pg_tuple()
548
+ init_pg_tuple(void)
549
549
  {
550
550
  rb_cPG_Tuple = rb_define_class_under( rb_mPG, "Tuple", rb_cObject );
551
551
  rb_define_alloc_func( rb_cPG_Tuple, pg_tuple_s_allocate );
data/ext/pg_type_map.c CHANGED
@@ -176,7 +176,7 @@ pg_typemap_with_default_type_map(VALUE self, VALUE typemap)
176
176
  }
177
177
 
178
178
  void
179
- init_pg_type_map()
179
+ init_pg_type_map(void)
180
180
  {
181
181
  s_id_fit_to_query = rb_intern("fit_to_query");
182
182
  s_id_fit_to_result = rb_intern("fit_to_result");
@@ -105,7 +105,7 @@ pg_tmas_s_allocate( VALUE klass )
105
105
 
106
106
 
107
107
  void
108
- init_pg_type_map_all_strings()
108
+ init_pg_type_map_all_strings(void)
109
109
  {
110
110
  /*
111
111
  * Document-class: PG::TypeMapAllStrings < PG::TypeMap
@@ -247,7 +247,7 @@ pg_tmbk_coders( VALUE self )
247
247
  }
248
248
 
249
249
  void
250
- init_pg_type_map_by_class()
250
+ init_pg_type_map_by_class(void)
251
251
  {
252
252
  /*
253
253
  * Document-class: PG::TypeMapByClass < PG::TypeMap
@@ -243,7 +243,7 @@ pg_tmbc_s_allocate( VALUE klass )
243
243
  }
244
244
 
245
245
  VALUE
246
- pg_tmbc_allocate()
246
+ pg_tmbc_allocate(void)
247
247
  {
248
248
  return pg_tmbc_s_allocate(rb_cTypeMapByColumn);
249
249
  }
@@ -320,7 +320,7 @@ pg_tmbc_coders(VALUE self)
320
320
  }
321
321
 
322
322
  void
323
- init_pg_type_map_by_column()
323
+ init_pg_type_map_by_column(void)
324
324
  {
325
325
  s_id_decode = rb_intern("decode");
326
326
  s_id_encode = rb_intern("encode");
@@ -286,7 +286,7 @@ pg_tmbmt_coders( VALUE self )
286
286
  }
287
287
 
288
288
  void
289
- init_pg_type_map_by_mri_type()
289
+ init_pg_type_map_by_mri_type(void)
290
290
  {
291
291
  /*
292
292
  * Document-class: PG::TypeMapByMriType < PG::TypeMap
@@ -356,7 +356,7 @@ pg_tmbo_build_column_map( VALUE self, VALUE result )
356
356
 
357
357
 
358
358
  void
359
- init_pg_type_map_by_oid()
359
+ init_pg_type_map_by_oid(void)
360
360
  {
361
361
  s_id_decode = rb_intern("decode");
362
362
 
@@ -299,7 +299,7 @@ pg_tmir_s_allocate( VALUE klass )
299
299
 
300
300
 
301
301
  void
302
- init_pg_type_map_in_ruby()
302
+ init_pg_type_map_in_ruby(void)
303
303
  {
304
304
  s_id_fit_to_result = rb_intern("fit_to_result");
305
305
  s_id_fit_to_query = rb_intern("fit_to_query");
data/lib/3.1/pg_ext.so CHANGED
Binary file
data/lib/pg/connection.rb CHANGED
@@ -93,6 +93,27 @@ class PG::Connection
93
93
  return connect_hash_to_string(iopts)
94
94
  end
95
95
 
96
+ # Return a String representation of the object suitable for debugging.
97
+ def inspect
98
+ str = self.to_s
99
+ str[-1,0] = if finished?
100
+ " finished"
101
+ else
102
+ stats = []
103
+ stats << " status=#{ PG.constants.grep(/CONNECTION_/).find{|c| PG.const_get(c) == status} }" if status != CONNECTION_OK
104
+ stats << " transaction_status=#{ PG.constants.grep(/PQTRANS_/).find{|c| PG.const_get(c) == transaction_status} }" if transaction_status != PG::PQTRANS_IDLE
105
+ stats << " nonblocking=#{ isnonblocking }" if isnonblocking
106
+ stats << " pipeline_status=#{ PG.constants.grep(/PQ_PIPELINE_/).find{|c| PG.const_get(c) == pipeline_status} }" if respond_to?(:pipeline_status) && pipeline_status != PG::PQ_PIPELINE_OFF
107
+ stats << " client_encoding=#{ get_client_encoding }" if get_client_encoding != "UTF8"
108
+ stats << " type_map_for_results=#{ type_map_for_results.to_s }" unless type_map_for_results.is_a?(PG::TypeMapAllStrings)
109
+ stats << " type_map_for_queries=#{ type_map_for_queries.to_s }" unless type_map_for_queries.is_a?(PG::TypeMapAllStrings)
110
+ stats << " encoder_for_put_copy_data=#{ encoder_for_put_copy_data.to_s }" if encoder_for_put_copy_data
111
+ stats << " decoder_for_get_copy_data=#{ decoder_for_get_copy_data.to_s }" if decoder_for_get_copy_data
112
+ " host=#{host} port=#{port} user=#{user}#{stats.join}"
113
+ end
114
+ return str
115
+ end
116
+
96
117
  # call-seq:
97
118
  # conn.copy_data( sql [, coder] ) {|sql_result| ... } -> PG::Result
98
119
  #
@@ -408,7 +429,17 @@ class PG::Connection
408
429
  # See also #copy_data.
409
430
  #
410
431
  def put_copy_data(buffer, encoder=nil)
432
+ # sync_put_copy_data does a non-blocking attept to flush data.
411
433
  until res=sync_put_copy_data(buffer, encoder)
434
+ # It didn't flush immediately and allocation of more buffering memory failed.
435
+ # Wait for all data sent by doing a blocking flush.
436
+ res = flush
437
+ end
438
+
439
+ # And do a blocking flush every 100 calls.
440
+ # This is to avoid memory bloat, when sending the data is slower than calls to put_copy_data happen.
441
+ if (@calls_to_put_copy_data += 1) > 100
442
+ @calls_to_put_copy_data = 0
412
443
  res = flush
413
444
  end
414
445
  res
@@ -431,6 +462,7 @@ class PG::Connection
431
462
  until sync_put_copy_end(*args)
432
463
  flush
433
464
  end
465
+ @calls_to_put_copy_data = 0
434
466
  flush
435
467
  end
436
468
  alias async_put_copy_end put_copy_end
@@ -544,14 +576,17 @@ class PG::Connection
544
576
  if (timeo = conninfo_hash[:connect_timeout].to_i) && timeo > 0
545
577
  # Lowest timeout is 2 seconds - like in libpq
546
578
  timeo = [timeo, 2].max
547
- stop_time = timeo + Process.clock_gettime(Process::CLOCK_MONOTONIC)
579
+ host_count = conninfo_hash[:host].to_s.count(",") + 1
580
+ stop_time = timeo * host_count + Process.clock_gettime(Process::CLOCK_MONOTONIC)
548
581
  end
549
582
 
550
583
  poll_status = PG::PGRES_POLLING_WRITING
551
584
  until poll_status == PG::PGRES_POLLING_OK ||
552
585
  poll_status == PG::PGRES_POLLING_FAILED
553
586
 
554
- timeout = stop_time&.-(Process.clock_gettime(Process::CLOCK_MONOTONIC))
587
+ # Set single timeout to parameter "connect_timeout" but
588
+ # don't exceed total connection time of number-of-hosts * connect_timeout.
589
+ timeout = [timeo, stop_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)].min if stop_time
555
590
  event = if !timeout || timeout >= 0
556
591
  # If the socket needs to read, wait 'til it becomes readable to poll again
557
592
  case poll_status
@@ -589,7 +624,6 @@ class PG::Connection
589
624
 
590
625
  # Check to see if it's finished or failed yet
591
626
  poll_status = send( poll_meth )
592
- @last_status = status unless [PG::CONNECTION_BAD, PG::CONNECTION_OK].include?(status)
593
627
  end
594
628
 
595
629
  unless status == PG::CONNECTION_OK
@@ -680,84 +714,49 @@ class PG::Connection
680
714
  iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
681
715
  iopts = PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
682
716
 
683
- errors = []
684
717
  if iopts[:hostaddr]
685
718
  # hostaddr is provided -> no need to resolve hostnames
686
- ihostaddrs = iopts[:hostaddr].split(",", -1)
687
-
688
- ihosts = iopts[:host].split(",", -1) if iopts[:host]
689
- raise PG::ConnectionBad, "could not match #{ihosts.size} host names to #{ihostaddrs.size} hostaddr values" if ihosts && ihosts.size != ihostaddrs.size
690
719
 
691
- iports = iopts[:port].split(",", -1)
692
- iports = iports * ihostaddrs.size if iports.size == 1
693
- raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihostaddrs.size} hosts" if iports.size != ihostaddrs.size
694
-
695
- # Try to connect to each hostaddr with separate timeout
696
- ihostaddrs.each_with_index do |ihostaddr, idx|
697
- oopts = iopts.merge(hostaddr: ihostaddr, port: iports[idx])
698
- oopts[:host] = ihosts[idx] if ihosts
699
- c = connect_internal(oopts, errors)
700
- return c if c
701
- end
702
- elsif iopts[:host] && !iopts[:host].empty?
703
- # Resolve DNS in Ruby to avoid blocking state while connecting, when it ...
720
+ elsif iopts[:host] && !iopts[:host].empty? && PG.library_version >= 100000
721
+ # Resolve DNS in Ruby to avoid blocking state while connecting.
722
+ # Multiple comma-separated values are generated, if the hostname resolves to both IPv4 and IPv6 addresses.
723
+ # This requires PostgreSQL-10+, so no DNS resolving is done on earlier versions.
704
724
  ihosts = iopts[:host].split(",", -1)
705
-
706
725
  iports = iopts[:port].split(",", -1)
707
726
  iports = iports * ihosts.size if iports.size == 1
708
727
  raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
709
728
 
710
- ihosts.each_with_index do |mhost, idx|
729
+ dests = ihosts.each_with_index.flat_map do |mhost, idx|
711
730
  unless host_is_named_pipe?(mhost)
712
- addrs = if Fiber.respond_to?(:scheduler) &&
731
+ if Fiber.respond_to?(:scheduler) &&
713
732
  Fiber.scheduler &&
714
733
  RUBY_VERSION < '3.1.'
715
734
 
716
735
  # Use a second thread to avoid blocking of the scheduler.
717
736
  # `TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
718
- Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
737
+ hostaddrs = Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
719
738
  else
720
- Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
721
- end
722
-
723
- # Try to connect to each host with separate timeout
724
- addrs.each do |addr|
725
- oopts = iopts.merge(hostaddr: addr, host: mhost, port: iports[idx])
726
- c = connect_internal(oopts, errors)
727
- return c if c
739
+ hostaddrs = Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
728
740
  end
729
741
  else
730
742
  # No hostname to resolve (UnixSocket)
731
- oopts = iopts.merge(host: mhost, port: iports[idx])
732
- c = connect_internal(oopts, errors)
733
- return c if c
743
+ hostaddrs = [nil]
734
744
  end
745
+ hostaddrs.map { |hostaddr| [hostaddr, mhost, iports[idx]] }
735
746
  end
747
+ iopts.merge!(
748
+ hostaddr: dests.map{|d| d[0] }.join(","),
749
+ host: dests.map{|d| d[1] }.join(","),
750
+ port: dests.map{|d| d[2] }.join(","))
736
751
  else
737
752
  # No host given
738
- return connect_internal(iopts)
739
753
  end
740
- raise PG::ConnectionBad, errors.join("\n")
741
- end
754
+ conn = self.connect_start(iopts) or
755
+ raise(PG::Error, "Unable to create a new connection")
742
756
 
743
- private def connect_internal(opts, errors=nil)
744
- begin
745
- conn = self.connect_start(opts) or
746
- raise(PG::Error, "Unable to create a new connection")
757
+ raise PG::ConnectionBad, conn.error_message if conn.status == PG::CONNECTION_BAD
747
758
 
748
- raise PG::ConnectionBad.new(conn.error_message, connection: self) if conn.status == PG::CONNECTION_BAD
749
-
750
- conn.send(:async_connect_or_reset, :connect_poll)
751
- rescue PG::ConnectionBad => err
752
- if errors && !(conn && [PG::CONNECTION_AWAITING_RESPONSE].include?(conn.instance_variable_get(:@last_status)))
753
- # Seems to be no authentication error -> try next host
754
- errors << err
755
- return nil
756
- else
757
- # Probably an authentication error
758
- raise
759
- end
760
- end
759
+ conn.send(:async_connect_or_reset, :connect_poll)
761
760
  conn
762
761
  end
763
762
 
data/lib/pg/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module PG
2
2
  # Library version
3
- VERSION = '1.4.2'
3
+ VERSION = '1.4.4'
4
4
  end
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.4.2
4
+ version: 1.4.4
5
5
  platform: x64-mingw-ucrt
6
6
  authors:
7
7
  - Michael Granger
@@ -11,32 +11,26 @@ bindir: bin
11
11
  cert_chain:
12
12
  - |
13
13
  -----BEGIN CERTIFICATE-----
14
- MIIETTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
15
- L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yMjAyMTQxMzMwNTZaFw0yMzAy
16
- MTQxMzMwNTZaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
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
- 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjgYEwfzAJ
26
- BgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUOIdbSMr3VFrTCO9/cTM0
27
- 0exHzBcwIgYDVR0RBBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwIgYDVR0S
28
- BBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwDQYJKoZIhvcNAQELBQADggGB
29
- AFWP7F/y3Oq3NgrqUOnjKOeDaBa7AqNhHS+PZg+C90lnJzMgOs4KKgZYxqSQVSab
30
- SCEmzIO/StkXY4NpJ4fYLrHemf/fJy1wPyu+fNdp5SEEUwEo+2toRFlzTe4u4LdS
31
- QC636nPPTMt8H3xz2wf/lUIUeo2Qc95Qt2BQM465ibbG9kmA3c7Sopx6yOabYOAl
32
- KPRbOSEPiWYcF9Suuz8Gdf8jxEtPlnZiwRvnYJ+IHMq3XQCJWPpMzdDMbtlgHbXE
33
- vq1zOTLMSYAS0UB3uionR4yo1hLz60odwkCm7qf0o2Ci/5OjtB0a89VuyqRU2vUJ
34
- QH95WBjDJ6lCCW7J0mrMPnJQSUFTmufsU6jOChvPaCeAzW1YwrsP/YKnvwueG7ip
35
- VOdW6RitjtFxhS7evRL0201+KUvLz12zZWWjOcujlQs64QprxOtiv/MiisKb1Ng+
36
- oL1mUdzB8KrZL4/WbG5YNX6UTtJbIOu9qEFbBAy4/jtIkJX+dlNoFwd4GXQW1YNO
37
- nA==
14
+ MIIDLjCCAhagAwIBAgIBCjANBgkqhkiG9w0BAQsFADA9MQ4wDAYDVQQDDAVrYW5p
15
+ czEXMBUGCgmSJomT8ixkARkWB2NvbWNhcmQxEjAQBgoJkiaJk/IsZAEZFgJkZTAe
16
+ Fw0yMjA0MTExMTMwNTNaFw0yMzA0MTExMTMwNTNaMD0xDjAMBgNVBAMMBWthbmlz
17
+ MRcwFQYKCZImiZPyLGQBGRYHY29tY2FyZDESMBAGCgmSJomT8ixkARkWAmRlMIIB
18
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApop+rNmg35bzRugZ21VMGqI6
19
+ HGzPLO4VHYncWn/xmgPU/ZMcZdfj6MzIaZJ/czXyt4eHpBk1r8QOV3gBXnRXEjVW
20
+ 9xi+EdVOkTV2/AVFKThcbTAQGiF/bT1n2M+B1GTybRzMg6hyhOJeGPqIhLfJEpxn
21
+ lJi4+ENAVT4MpqHEAGB8yFoPC0GqiOHQsdHxQV3P3c2OZqG+yJey74QtwA2tLcLn
22
+ Q53c63+VLGsOjODl1yPn/2ejyq8qWu6ahfTxiIlSar2UbwtaQGBDFdb2CXgEufXT
23
+ L7oaPxlmj+Q2oLOfOnInd2Oxop59HoJCQPsg8f921J43NCQGA8VHK6paxIRDLQID
24
+ AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUvgTdT7fe
25
+ x17ugO3IOsjEJwW7KP4wDQYJKoZIhvcNAQELBQADggEBAILiaB/unSVBfX5n7uL8
26
+ veGGCOHuGYhCGqspb6mYiCx0dmV3RPRiEfGDLfzcXbHNx/3AjygcxH4Slr+pmaxr
27
+ 04Xli3WurocnjoANSWqCwpHH3OhSVxFgBNrCa3OMWcIr0xKH+I7PXA80SXe0pzfg
28
+ ePjpzTY71j+rcyRJqWiU5/zwdUaCCelBJscxh/0IaNcz67ocCEMRj0n4m5HFEmZL
29
+ 9zKkMZFoOjxRQjcL84QU7ZXnnFR5HG8nLw+NqWjo49W6MBQ9HGFda2tk3OpBhyWS
30
+ sc3NyOkGUGdfiee5VRG31Sh3LLON3YGED+zZAS+ZF6598y4vhv8MBLa1Oy357byC
31
+ tTg=
38
32
  -----END CERTIFICATE-----
39
- date: 2022-07-27 00:00:00.000000000 Z
33
+ date: 2022-10-11 00:00:00.000000000 Z
40
34
  dependencies: []
41
35
  description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
42
36
  9.3 and later.
metadata.gz.sig CHANGED
Binary file