pg 1.3.0.rc1-x86-mingw32 → 1.3.0.rc2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pg/connection.rb CHANGED
@@ -364,14 +364,44 @@ class PG::Connection
364
364
  end
365
365
  end
366
366
 
367
- alias sync_get_result get_result
368
- def async_get_result(*args)
367
+ # call-seq:
368
+ # conn.get_result() -> PG::Result
369
+ # conn.get_result() {|pg_result| block }
370
+ #
371
+ # Blocks waiting for the next result from a call to
372
+ # #send_query (or another asynchronous command), and returns
373
+ # it. Returns +nil+ if no more results are available.
374
+ #
375
+ # Note: call this function repeatedly until it returns +nil+, or else
376
+ # you will not be able to issue further commands.
377
+ #
378
+ # If the optional code block is given, it will be passed <i>result</i> as an argument,
379
+ # and the PG::Result object will automatically be cleared when the block terminates.
380
+ # In this instance, <code>conn.exec</code> returns the value of the block.
381
+ def get_result(*args)
369
382
  block
370
383
  sync_get_result
371
384
  end
385
+ alias async_get_result get_result
372
386
 
373
- alias sync_get_copy_data get_copy_data
374
- def async_get_copy_data(async=false, decoder=nil)
387
+ # call-seq:
388
+ # conn.get_copy_data( [ nonblock = false [, decoder = nil ]] ) -> Object
389
+ #
390
+ # Return one row of data, +nil+
391
+ # if the copy is done, or +false+ if the call would
392
+ # block (only possible if _nonblock_ is true).
393
+ #
394
+ # If _decoder_ is not set or +nil+, data is returned as binary string.
395
+ #
396
+ # If _decoder_ is set to a PG::Coder derivation, the return type depends on this decoder.
397
+ # PG::TextDecoder::CopyRow decodes the received data fields from one row of PostgreSQL's
398
+ # COPY text format to an Array of Strings.
399
+ # Optionally the decoder can type cast the single fields to various Ruby types in one step,
400
+ # if PG::TextDecoder::CopyRow#type_map is set accordingly.
401
+ #
402
+ # See also #copy_data.
403
+ #
404
+ def get_copy_data(async=false, decoder=nil)
375
405
  if async
376
406
  return sync_get_copy_data(async, decoder)
377
407
  else
@@ -382,56 +412,143 @@ class PG::Connection
382
412
  return res
383
413
  end
384
414
  end
415
+ alias async_get_copy_data get_copy_data
385
416
 
386
- # In async_api=false mode all send calls run directly on libpq.
387
- # Blocking vs. nonblocking state can be changed in libpq.
388
- alias sync_setnonblocking setnonblocking
389
417
 
390
418
  # In async_api=true mode (default) all send calls run nonblocking.
391
419
  # The difference is that setnonblocking(true) disables automatic handling of would-block cases.
392
- def async_setnonblocking(enabled)
420
+ # In async_api=false mode all send calls run directly on libpq.
421
+ # Blocking vs. nonblocking state can be changed in libpq.
422
+
423
+ # call-seq:
424
+ # conn.setnonblocking(Boolean) -> nil
425
+ #
426
+ # Sets the nonblocking status of the connection.
427
+ # In the blocking state, calls to #send_query
428
+ # will block until the message is sent to the server,
429
+ # but will not wait for the query results.
430
+ # In the nonblocking state, calls to #send_query
431
+ # will return an error if the socket is not ready for
432
+ # writing.
433
+ # Note: This function does not affect #exec, because
434
+ # that function doesn't return until the server has
435
+ # processed the query and returned the results.
436
+ #
437
+ # Returns +nil+.
438
+ def setnonblocking(enabled)
393
439
  singleton_class.async_send_api = !enabled
394
440
  self.flush_data = !enabled
395
441
  sync_setnonblocking(true)
396
442
  end
443
+ alias async_setnonblocking setnonblocking
397
444
 
398
445
  # sync/async isnonblocking methods are switched by async_setnonblocking()
399
- alias sync_isnonblocking isnonblocking
400
- def async_isnonblocking
446
+
447
+ # call-seq:
448
+ # conn.isnonblocking() -> Boolean
449
+ #
450
+ # Returns the blocking status of the database connection.
451
+ # Returns +true+ if the connection is set to nonblocking mode and +false+ if blocking.
452
+ def isnonblocking
401
453
  false
402
454
  end
455
+ alias async_isnonblocking isnonblocking
456
+ alias nonblocking? isnonblocking
403
457
 
404
- alias sync_put_copy_data put_copy_data
405
- def async_put_copy_data(buffer, encoder=nil)
458
+ # call-seq:
459
+ # conn.put_copy_data( buffer [, encoder] ) -> Boolean
460
+ #
461
+ # Transmits _buffer_ as copy data to the server.
462
+ # Returns true if the data was sent, false if it was
463
+ # not sent (false is only possible if the connection
464
+ # is in nonblocking mode, and this command would block).
465
+ #
466
+ # _encoder_ can be a PG::Coder derivation (typically PG::TextEncoder::CopyRow).
467
+ # This encodes the data fields given as _buffer_ from an Array of Strings to
468
+ # PostgreSQL's COPY text format inclusive proper escaping. Optionally
469
+ # the encoder can type cast the fields from various Ruby types in one step,
470
+ # if PG::TextEncoder::CopyRow#type_map is set accordingly.
471
+ #
472
+ # Raises an exception if an error occurs.
473
+ #
474
+ # See also #copy_data.
475
+ #
476
+ def put_copy_data(buffer, encoder=nil)
406
477
  until sync_put_copy_data(buffer, encoder)
407
478
  flush
408
479
  end
409
480
  flush
410
481
  end
411
- alias sync_put_copy_end put_copy_end
412
- def async_put_copy_end(*args)
482
+ alias async_put_copy_data put_copy_data
483
+
484
+ # call-seq:
485
+ # conn.put_copy_end( [ error_message ] ) -> Boolean
486
+ #
487
+ # Sends end-of-data indication to the server.
488
+ #
489
+ # _error_message_ is an optional parameter, and if set,
490
+ # forces the COPY command to fail with the string
491
+ # _error_message_.
492
+ #
493
+ # Returns true if the end-of-data was sent, #false* if it was
494
+ # not sent (*false* is only possible if the connection
495
+ # is in nonblocking mode, and this command would block).
496
+ def put_copy_end(*args)
413
497
  until sync_put_copy_end(*args)
414
498
  flush
415
499
  end
416
500
  flush
417
501
  end
502
+ alias async_put_copy_end put_copy_end
418
503
 
419
- if method_defined? :encrypt_password
420
- alias sync_encrypt_password encrypt_password
421
- def async_encrypt_password( password, username, algorithm=nil )
504
+ if method_defined? :sync_encrypt_password
505
+ # call-seq:
506
+ # conn.encrypt_password( password, username, algorithm=nil ) -> String
507
+ #
508
+ # This function is intended to be used by client applications that wish to send commands like <tt>ALTER USER joe PASSWORD 'pwd'</tt>.
509
+ # It is good practice not to send the original cleartext password in such a command, because it might be exposed in command logs, activity displays, and so on.
510
+ # Instead, use this function to convert the password to encrypted form before it is sent.
511
+ #
512
+ # The +password+ and +username+ arguments are the cleartext password, and the SQL name of the user it is for.
513
+ # +algorithm+ specifies the encryption algorithm to use to encrypt the password.
514
+ # Currently supported algorithms are +md5+ and +scram-sha-256+ (+on+ and +off+ are also accepted as aliases for +md5+, for compatibility with older server versions).
515
+ # Note that support for +scram-sha-256+ was introduced in PostgreSQL version 10, and will not work correctly with older server versions.
516
+ # If algorithm is omitted or +nil+, this function will query the server for the current value of the +password_encryption+ setting.
517
+ # That can block, and will fail if the current transaction is aborted, or if the connection is busy executing another query.
518
+ # If you wish to use the default algorithm for the server but want to avoid blocking, query +password_encryption+ yourself before calling #encrypt_password, and pass that value as the algorithm.
519
+ #
520
+ # Return value is the encrypted password.
521
+ # The caller can assume the string doesn't contain any special characters that would require escaping.
522
+ #
523
+ # Available since PostgreSQL-10.
524
+ # See also corresponding {libpq function}[https://www.postgresql.org/docs/current/libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN].
525
+ def encrypt_password( password, username, algorithm=nil )
422
526
  algorithm ||= exec("SHOW password_encryption").getvalue(0,0)
423
527
  sync_encrypt_password(password, username, algorithm)
424
528
  end
529
+ alias async_encrypt_password encrypt_password
425
530
  end
426
531
 
427
- alias sync_reset reset
428
- def async_reset
532
+ # call-seq:
533
+ # conn.reset()
534
+ #
535
+ # Resets the backend connection. This method closes the
536
+ # backend connection and tries to re-connect.
537
+ def reset
429
538
  reset_start
430
539
  async_connect_or_reset(:reset_poll)
431
540
  end
541
+ alias async_reset reset
432
542
 
433
- alias sync_cancel cancel
434
- def async_cancel
543
+ # call-seq:
544
+ # conn.cancel() -> String
545
+ #
546
+ # Requests cancellation of the command currently being
547
+ # processed.
548
+ #
549
+ # Returns +nil+ on success, or a string containing the
550
+ # error message if a failure occurs.
551
+ def cancel
435
552
  be_pid = backend_pid
436
553
  be_key = backend_key
437
554
  cancel_request = [0x10, 1234, 5678, be_pid, be_key].pack("NnnNN")
@@ -484,6 +601,7 @@ class PG::Connection
484
601
  rescue SystemCallError => err
485
602
  err.to_s
486
603
  end
604
+ alias async_cancel cancel
487
605
 
488
606
  private def async_connect_or_reset(poll_meth)
489
607
  # Now grab a reference to the underlying socket so we know when the connection is established
@@ -520,9 +638,58 @@ class PG::Connection
520
638
  end
521
639
 
522
640
  class << self
523
- alias sync_connect new
524
-
525
- def async_connect(*args, **kwargs)
641
+ # call-seq:
642
+ # PG::Connection.new -> conn
643
+ # PG::Connection.new(connection_hash) -> conn
644
+ # PG::Connection.new(connection_string) -> conn
645
+ # PG::Connection.new(host, port, options, tty, dbname, user, password) -> conn
646
+ #
647
+ # Create a connection to the specified server.
648
+ #
649
+ # +connection_hash+ must be a ruby Hash with connection parameters.
650
+ # See the {list of valid parameters}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS] in the PostgreSQL documentation.
651
+ #
652
+ # There are two accepted formats for +connection_string+: plain <code>keyword = value</code> strings and URIs.
653
+ # See the documentation of {connection strings}[https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING].
654
+ #
655
+ # The positional parameter form has the same functionality except that the missing parameters will always take on default values. The parameters are:
656
+ # [+host+]
657
+ # server hostname
658
+ # [+port+]
659
+ # server port number
660
+ # [+options+]
661
+ # backend options
662
+ # [+tty+]
663
+ # (ignored in all versions of PostgreSQL)
664
+ # [+dbname+]
665
+ # connecting database name
666
+ # [+user+]
667
+ # login user name
668
+ # [+password+]
669
+ # login password
670
+ #
671
+ # Examples:
672
+ #
673
+ # # Connect using all defaults
674
+ # PG::Connection.new
675
+ #
676
+ # # As a Hash
677
+ # PG::Connection.new( dbname: 'test', port: 5432 )
678
+ #
679
+ # # As a String
680
+ # PG::Connection.new( "dbname=test port=5432" )
681
+ #
682
+ # # As an Array
683
+ # PG::Connection.new( nil, 5432, nil, nil, 'test', nil, nil )
684
+ #
685
+ # # As an URI
686
+ # PG::Connection.new( "postgresql://user:pass@pgsql.example.com:5432/testdb?sslmode=require" )
687
+ #
688
+ # If the Ruby default internal encoding is set (i.e., <code>Encoding.default_internal != nil</code>), the
689
+ # connection will have its +client_encoding+ set accordingly.
690
+ #
691
+ # Raises a PG::Error if the connection fails.
692
+ def new(*args, **kwargs)
526
693
  conn = PG::Connection.connect_start(*args, **kwargs ) or
527
694
  raise(PG::Error, "Unable to create a new connection")
528
695
 
@@ -530,9 +697,31 @@ class PG::Connection
530
697
 
531
698
  conn.send(:async_connect_or_reset, :connect_poll)
532
699
  end
700
+ alias async_connect new
701
+ alias connect new
702
+ alias open new
703
+ alias setdb new
704
+ alias setdblogin new
533
705
 
534
- alias sync_ping ping
535
- def async_ping(*args)
706
+ # call-seq:
707
+ # PG::Connection.ping(connection_hash) -> Integer
708
+ # PG::Connection.ping(connection_string) -> Integer
709
+ # PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
710
+ #
711
+ # Check server status.
712
+ #
713
+ # See PG::Connection.new for a description of the parameters.
714
+ #
715
+ # Returns one of:
716
+ # [+PQPING_OK+]
717
+ # server is accepting connections
718
+ # [+PQPING_REJECT+]
719
+ # server is alive but rejecting connections
720
+ # [+PQPING_NO_RESPONSE+]
721
+ # could not establish connection
722
+ # [+PQPING_NO_ATTEMPT+]
723
+ # connection not attempted (bad params)
724
+ def ping(*args)
536
725
  if Fiber.respond_to?(:scheduler) && Fiber.scheduler
537
726
  # Run PQping in a second thread to avoid blocking of the scheduler.
538
727
  # Unfortunately there's no nonblocking way to run ping.
@@ -541,9 +730,14 @@ class PG::Connection
541
730
  sync_ping(*args)
542
731
  end
543
732
  end
733
+ alias async_ping ping
544
734
 
545
735
  REDIRECT_CLASS_METHODS = {
546
736
  :new => [:async_connect, :sync_connect],
737
+ :connect => [:async_connect, :sync_connect],
738
+ :open => [:async_connect, :sync_connect],
739
+ :setdb => [:async_connect, :sync_connect],
740
+ :setdblogin => [:async_connect, :sync_connect],
547
741
  :ping => [:async_ping, :sync_ping],
548
742
  }
549
743
 
@@ -586,6 +780,22 @@ class PG::Connection
586
780
  end
587
781
  end
588
782
 
783
+ # Switch between sync and async libpq API.
784
+ #
785
+ # PG::Connection.async_api = true
786
+ # this is the default.
787
+ # It sets an alias from #exec to #async_exec, #reset to #async_reset and so on.
788
+ #
789
+ # PG::Connection.async_api = false
790
+ # sets an alias from #exec to #sync_exec, #reset to #sync_reset and so on.
791
+ #
792
+ # pg-1.1.0+ defaults to libpq's async API for query related blocking methods.
793
+ # pg-1.3.0+ defaults to libpq's async API for all possibly blocking methods.
794
+ #
795
+ # _PLEASE_ _NOTE_: This method is not part of the public API and is for debug and development use only.
796
+ # Do not use this method in production code.
797
+ # Any issues with the default setting of <tt>async_api=true</tt> should be reported to the maintainers instead.
798
+ #
589
799
  def async_api=(enable)
590
800
  self.async_send_api = enable
591
801
  REDIRECT_METHODS.each do |ali, (async, sync)|
@@ -599,6 +809,5 @@ class PG::Connection
599
809
  end
600
810
  end
601
811
 
602
- # pg-1.1.0+ defaults to libpq's async API for query related blocking methods
603
812
  self.async_api = true
604
813
  end # class PG::Connection
data/lib/pg/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module PG
2
2
  # Library version
3
- VERSION = '1.3.0.rc1'
3
+ VERSION = '1.3.0.rc2'
4
4
  end
Binary file
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,34 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.rc1
4
+ version: 1.3.0.rc2
5
5
  platform: x86-mingw32
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
- 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
- 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
- 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
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+5uh+zqCXKho0zXIaLmJD6YDpa
18
- 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
- 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
- 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
- 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
- 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
- AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFOTn5ek+QtcI
24
- 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
- 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
- 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
- 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
- 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
- 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
37
+ gw==
30
38
  -----END CERTIFICATE-----
31
- date: 2021-12-27 00:00:00.000000000 Z
39
+ date: 2022-01-08 00:00:00.000000000 Z
32
40
  dependencies: []
33
41
  description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
34
42
  9.3 and later.
@@ -100,6 +108,7 @@ files:
100
108
  - lib/2.6/pg_ext.so
101
109
  - lib/2.7/pg_ext.so
102
110
  - lib/3.0/pg_ext.so
111
+ - lib/3.1/pg_ext.so
103
112
  - lib/pg.rb
104
113
  - lib/pg/basic_type_map_based_on_result.rb
105
114
  - lib/pg/basic_type_map_for_queries.rb
@@ -156,7 +165,7 @@ metadata:
156
165
  source_code_uri: https://github.com/ged/ruby-pg
157
166
  changelog_uri: https://github.com/ged/ruby-pg/blob/master/History.rdoc
158
167
  documentation_uri: http://deveiate.org/code/pg
159
- post_install_message:
168
+ post_install_message:
160
169
  rdoc_options:
161
170
  - "--main"
162
171
  - README.rdoc
@@ -169,15 +178,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
178
  version: '2.5'
170
179
  - - "<"
171
180
  - !ruby/object:Gem::Version
172
- version: 3.1.dev
181
+ version: 3.2.dev
173
182
  required_rubygems_version: !ruby/object:Gem::Requirement
174
183
  requirements:
175
184
  - - ">"
176
185
  - !ruby/object:Gem::Version
177
186
  version: 1.3.1
178
187
  requirements: []
179
- rubygems_version: 3.2.3
180
- signing_key:
188
+ rubygems_version: 3.3.4
189
+ signing_key:
181
190
  specification_version: 4
182
191
  summary: Pg is the Ruby interface to the PostgreSQL RDBMS
183
192
  test_files: []
metadata.gz.sig CHANGED
Binary file