pg 1.4.2-x86-mingw32 → 1.4.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee7a63a506afa6472f3664914858259c59caf05c9eaac6e1adf00acf453dff26
4
- data.tar.gz: 8dfdb41d719ea6d34693ad251e2a0fd00ebd0b613ad04ef67e9d41fcf896c424
3
+ metadata.gz: 8b2e47b6c6ca0f642e05e92341ccf67b4eead97b65b5e550d335d9a4035c7577
4
+ data.tar.gz: 1ceaf2c8584ae31fb57a24bb10d1b160c46735213113a22825dd485a15a8842e
5
5
  SHA512:
6
- metadata.gz: 96c838a5b5eaa22cf18e7f4a7d35b8572b64548b0961073b0df1f8d343292dff89671e98a01ed1aba82d98c49771d04596e029b85f767266dcbc19488e393d1b
7
- data.tar.gz: b3fdb5f2724b35481d944db3bf87eff999daeaf33eaa86d81e66ee91b3c73825b330dc7e3586bd96a2f1c355a2394397650542adaead22a01a2cbf4157132f05
6
+ metadata.gz: d61700de7b8288912b7b518b883204f89bacebd1e2a7426d5dea69aacf0fde3c3df5aaf7c7fa36fefdc82a93bf4ed4e21aad9c81643787a792d1e89ef1de4a3f
7
+ data.tar.gz: 265c7e118944b456c6f106d8a45707f72ce2b16af2a379b465e55d10783cab75201d5b5ab86376d6ef59142432ac4863492ba2e39a69601ff42476d4e86c6ac4
checksums.yaml.gz.sig CHANGED
Binary file
@@ -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/2.5/pg_ext.so CHANGED
Binary file
data/lib/2.6/pg_ext.so CHANGED
Binary file
data/lib/2.7/pg_ext.so CHANGED
Binary file
data/lib/3.0/pg_ext.so CHANGED
Binary file
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: x86-mingw32
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