pg 0.21.0-x64-mingw32 → 1.0.0-x64-mingw32

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.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_result.c - PG::Result class extension
3
- * $Id$
3
+ * $Id: pg_result.c,v 7c5d9608349f 2018/01/03 16:11:52 lars $
4
4
  *
5
5
  */
6
6
 
@@ -92,12 +92,8 @@ pg_result_check( VALUE self )
92
92
  case PGRES_TUPLES_OK:
93
93
  case PGRES_COPY_OUT:
94
94
  case PGRES_COPY_IN:
95
- #ifdef HAVE_CONST_PGRES_COPY_BOTH
96
95
  case PGRES_COPY_BOTH:
97
- #endif
98
- #ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
99
96
  case PGRES_SINGLE_TUPLE:
100
- #endif
101
97
  case PGRES_EMPTY_QUERY:
102
98
  case PGRES_COMMAND_OK:
103
99
  return self;
@@ -1056,7 +1052,6 @@ pgresult_type_map_get(VALUE self)
1056
1052
  return this->typemap;
1057
1053
  }
1058
1054
 
1059
- #ifdef HAVE_PQSETSINGLEROWMODE
1060
1055
  /*
1061
1056
  * call-seq:
1062
1057
  * res.stream_each{ |tuple| ... }
@@ -1087,6 +1082,8 @@ pgresult_type_map_get(VALUE self)
1087
1082
  * # do something with the received row of the second query
1088
1083
  * end
1089
1084
  * conn.get_result # => nil (no more results)
1085
+ *
1086
+ * Available since PostgreSQL-9.2
1090
1087
  */
1091
1088
  static VALUE
1092
1089
  pgresult_stream_each(VALUE self)
@@ -1150,6 +1147,8 @@ pgresult_stream_each(VALUE self)
1150
1147
  *
1151
1148
  * This method works equally to #stream_each , but yields an Array of
1152
1149
  * values.
1150
+ *
1151
+ * Available since PostgreSQL-9.2
1153
1152
  */
1154
1153
  static VALUE
1155
1154
  pgresult_stream_each_row(VALUE self)
@@ -1210,7 +1209,6 @@ pgresult_stream_each_row(VALUE self)
1210
1209
  /* never reached */
1211
1210
  return self;
1212
1211
  }
1213
- #endif
1214
1212
 
1215
1213
 
1216
1214
  void
@@ -1267,11 +1265,9 @@ init_pg_result()
1267
1265
  rb_define_method(rb_cPGresult, "type_map=", pgresult_type_map_set, 1);
1268
1266
  rb_define_method(rb_cPGresult, "type_map", pgresult_type_map_get, 0);
1269
1267
 
1270
- #ifdef HAVE_PQSETSINGLEROWMODE
1271
1268
  /****** PG::Result INSTANCE METHODS: streaming ******/
1272
1269
  rb_define_method(rb_cPGresult, "stream_each", pgresult_stream_each, 0);
1273
1270
  rb_define_method(rb_cPGresult, "stream_each_row", pgresult_stream_each_row, 0);
1274
- #endif
1275
1271
  }
1276
1272
 
1277
1273
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_text_decoder.c - PG::TextDecoder module
3
- * $Id$
3
+ * $Id: pg_text_decoder.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_text_encoder.c - PG::TextEncoder module
3
- * $Id$
3
+ * $Id: pg_text_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_type_map.c,v 2af122820861 2017/01/14 19:56:36 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
3
- * $Id$
3
+ * $Id: pg_type_map_all_strings.c,v c53f993a4254 2014/12/12 21:57:29 lars $
4
4
  *
5
5
  * This is the default typemap.
6
6
  *
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_class.c - PG::TypeMapByClass class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_class.c,v eeb8a82c5328 2014/11/10 19:34:02 lars $
4
4
  *
5
5
  * This type map can be used to select value encoders based on the class
6
6
  * of the given value to be send.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_column.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_mri_type.c - PG::TypeMapByMriType class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_mri_type.c,v 1269b8ad77b8 2015/02/06 16:38:23 lars $
4
4
  *
5
5
  * This type map can be used to select value encoders based on the MRI-internal
6
6
  * value type code.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_oid.c - PG::TypeMapByOid class extension
3
- * $Id$
3
+ * $Id: pg_type_map_by_oid.c,v c99d26015e3c 2014/12/12 20:58:25 lars $
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_in_ruby.c - PG::TypeMapInRuby class extension
3
- * $Id$
3
+ * $Id: pg_type_map_in_ruby.c,v 3d89d3aae4fd 2015/01/05 16:19:41 kanis $
4
4
  *
5
5
  */
6
6
 
data/ext/util.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * util.c - Utils for ruby-pg
3
- * $Id$
3
+ * $Id: util.c,v 5fb9170f6a7d 2015/06/29 11:15:12 kanis $
4
4
  *
5
5
  */
6
6
 
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/pg.rb CHANGED
@@ -35,10 +35,10 @@ end
35
35
  module PG
36
36
 
37
37
  # Library version
38
- VERSION = '0.21.0'
38
+ VERSION = '1.0.0'
39
39
 
40
40
  # VCS revision
41
- REVISION = %q$Revision$
41
+ REVISION = %q$Revision: fef434914848 $
42
42
 
43
43
  class NotAllCopyDataRetrieved < PG::Error
44
44
  end
@@ -70,7 +70,3 @@ module PG
70
70
  end # module PG
71
71
 
72
72
 
73
- autoload :PGError, 'pg/deprecated_constants'
74
- autoload :PGconn, 'pg/deprecated_constants'
75
- autoload :PGresult, 'pg/deprecated_constants'
76
-
@@ -47,7 +47,7 @@ class PG::Connection
47
47
 
48
48
  if args.length == 1
49
49
  case args.first
50
- when URI, URI.regexp
50
+ when URI, /\A#{URI.regexp}\z/
51
51
  uri = URI(args.first)
52
52
  options.merge!( Hash[URI.decode_www_form( uri.query )] ) if uri.query
53
53
  when /=/
@@ -85,7 +85,7 @@ class PG::Connection
85
85
 
86
86
 
87
87
  # call-seq:
88
- # conn.copy_data( sql ) {|sql_result| ... } -> PG::Result
88
+ # conn.copy_data( sql [, coder] ) {|sql_result| ... } -> PG::Result
89
89
  #
90
90
  # Execute a copy process for transfering data to or from the server.
91
91
  #
@@ -109,6 +109,11 @@ class PG::Connection
109
109
  # of blocking mode of operation, #copy_data is preferred to raw calls
110
110
  # of #put_copy_data, #get_copy_data and #put_copy_end.
111
111
  #
112
+ # _coder_ can be a PG::Coder derivation
113
+ # (typically PG::TextEncoder::CopyRow or PG::TextDecoder::CopyRow).
114
+ # This enables encoding of data fields given to #put_copy_data
115
+ # or decoding of fields received by #get_copy_data.
116
+ #
112
117
  # Example with CSV input format:
113
118
  # conn.exec "create table my_table (a text,b text,c text,d text)"
114
119
  # conn.copy_data "COPY my_table FROM STDIN CSV" do
@@ -5,7 +5,9 @@ require 'rspec'
5
5
  require 'shellwords'
6
6
  require 'pg'
7
7
 
8
- TEST_DIRECTORY = Pathname.getwd + "tmp_test_specs"
8
+ DEFAULT_TEST_DIR_STR = File.join(Dir.pwd, "tmp_test_specs")
9
+ TEST_DIR_STR = ENV['RUBY_PG_TEST_DIR'] || DEFAULT_TEST_DIR_STR
10
+ TEST_DIRECTORY = Pathname.new(TEST_DIR_STR)
9
11
 
10
12
  module PG::TestingHelpers
11
13
 
@@ -251,7 +253,7 @@ module PG::TestingHelpers
251
253
 
252
254
  def check_for_lingering_connections( conn )
253
255
  conn.exec( "SELECT * FROM pg_stat_activity" ) do |res|
254
- conns = res.find_all {|row| row['pid'].to_i != conn.backend_pid }
256
+ conns = res.find_all {|row| row['pid'].to_i != conn.backend_pid && ["client backend", nil].include?(row["backend_type"]) }
255
257
  unless conns.empty?
256
258
  puts "Lingering connections remain:"
257
259
  conns.each do |row|
@@ -339,14 +341,8 @@ RSpec.configure do |config|
339
341
  config.filter_run_excluding :socket_io unless
340
342
  PG::Connection.instance_methods.map( &:to_sym ).include?( :socket_io )
341
343
 
342
- if PG.library_version < 90200
343
- config.filter_run_excluding( :postgresql_92, :postgresql_93, :postgresql_94, :postgresql_95 )
344
- elsif PG.library_version < 90300
345
- config.filter_run_excluding( :postgresql_93, :postgresql_94, :postgresql_95 )
346
- elsif PG.library_version < 90400
347
- config.filter_run_excluding( :postgresql_94, :postgresql_95 )
348
- elsif PG.library_version < 90500
349
- config.filter_run_excluding( :postgresql_95 )
350
- end
344
+ config.filter_run_excluding( :postgresql_93 ) if PG.library_version < 90300
345
+ config.filter_run_excluding( :postgresql_94 ) if PG.library_version < 90400
346
+ config.filter_run_excluding( :postgresql_95 ) if PG.library_version < 90500
347
+ config.filter_run_excluding( :postgresql_10 ) if PG.library_version < 100000
351
348
  end
352
-
@@ -118,6 +118,19 @@ describe PG::Connection do
118
118
  expect( described_class.parse_connect_args ).to eq( '' )
119
119
  end
120
120
 
121
+ it "connects successfully with connection string" do
122
+ conninfo_with_colon_in_password = "host=localhost user=a port=555 dbname=test password=a:a"
123
+
124
+ string = described_class.parse_connect_args( conninfo_with_colon_in_password )
125
+
126
+ expect( string ).to be_a( String )
127
+ expect( string ).to match( %r{(^|\s)user=a} )
128
+ expect( string ).to match( %r{(^|\s)password=a:a} )
129
+ expect( string ).to match( %r{(^|\s)host=localhost} )
130
+ expect( string ).to match( %r{(^|\s)port=555} )
131
+ expect( string ).to match( %r{(^|\s)dbname=test} )
132
+ end
133
+
121
134
  it "connects successfully with connection string" do
122
135
  tmpconn = described_class.connect( @conninfo )
123
136
  expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
@@ -139,7 +152,7 @@ describe PG::Connection do
139
152
  tmpconn.finish
140
153
  end
141
154
 
142
- it "connects using a hash of optional connection parameters", :postgresql_90 do
155
+ it "connects using a hash of optional connection parameters" do
143
156
  tmpconn = described_class.connect(
144
157
  :host => 'localhost',
145
158
  :port => @port,
@@ -219,7 +232,7 @@ describe PG::Connection do
219
232
  described_class.connect(@conninfo).finish
220
233
  sleep 0.5
221
234
  res = @conn.exec(%[SELECT COUNT(*) AS n FROM pg_stat_activity
222
- WHERE usename IS NOT NULL])
235
+ WHERE usename IS NOT NULL AND application_name != ''])
223
236
  # there's still the global @conn, but should be no more
224
237
  expect( res[0]['n'] ).to eq( '1' )
225
238
  end
@@ -524,7 +537,7 @@ describe PG::Connection do
524
537
  @conn.exec( 'UNLISTEN woo' )
525
538
  end
526
539
 
527
- it "can receive notices while waiting for NOTIFY without exceeding the timeout", :postgresql_90 do
540
+ it "can receive notices while waiting for NOTIFY without exceeding the timeout" do
528
541
  notices = []
529
542
  @conn.set_notice_processor do |msg|
530
543
  notices << [msg, Time.now]
@@ -586,7 +599,7 @@ describe PG::Connection do
586
599
  expect( @conn ).to still_be_usable
587
600
  end
588
601
 
589
- it "can handle server errors in #copy_data for output", :postgresql_90 do
602
+ it "can handle server errors in #copy_data for output" do
590
603
  @conn.exec "ROLLBACK"
591
604
  @conn.transaction do
592
605
  @conn.exec( "CREATE FUNCTION errfunc() RETURNS int AS $$ BEGIN RAISE 'test-error'; END; $$ LANGUAGE plpgsql;" )
@@ -718,11 +731,6 @@ describe PG::Connection do
718
731
  expect( (finish - start) ).to be_within( 0.2 ).of( 0.3 )
719
732
  end
720
733
 
721
-
722
- it "can encrypt a string given a password and username" do
723
- expect( described_class.encrypt_password("postgres", "postgres") ).to match( /\S+/ )
724
- end
725
-
726
734
  it "can return the default connection options" do
727
735
  expect( described_class.conndefaults ).to be_a( Array )
728
736
  expect( described_class.conndefaults ).to all( be_a(Hash) )
@@ -779,18 +787,52 @@ describe PG::Connection do
779
787
  end
780
788
  end
781
789
 
790
+ describe "deprecated password encryption method" do
791
+ it "can encrypt password for a given user" do
792
+ expect( described_class.encrypt_password("postgres", "postgres") ).to match( /\S+/ )
793
+ end
782
794
 
783
- it "raises an appropriate error if either of the required arguments for encrypt_password " +
784
- "is not valid" do
785
- expect {
786
- described_class.encrypt_password( nil, nil )
787
- }.to raise_error( TypeError )
788
- expect {
789
- described_class.encrypt_password( "postgres", nil )
790
- }.to raise_error( TypeError )
791
- expect {
792
- described_class.encrypt_password( nil, "postgres" )
793
- }.to raise_error( TypeError )
795
+ it "raises an appropriate error if either of the required arguments is not valid" do
796
+ expect {
797
+ described_class.encrypt_password( nil, nil )
798
+ }.to raise_error( TypeError )
799
+ expect {
800
+ described_class.encrypt_password( "postgres", nil )
801
+ }.to raise_error( TypeError )
802
+ expect {
803
+ described_class.encrypt_password( nil, "postgres" )
804
+ }.to raise_error( TypeError )
805
+ end
806
+ end
807
+
808
+ describe "password encryption method", :postgresql_10 do
809
+ it "can encrypt without algorithm" do
810
+ expect( @conn.encrypt_password("postgres", "postgres") ).to match( /\S+/ )
811
+ expect( @conn.encrypt_password("postgres", "postgres", nil) ).to match( /\S+/ )
812
+ end
813
+
814
+ it "can encrypt with algorithm" do
815
+ expect( @conn.encrypt_password("postgres", "postgres", "md5") ).to match( /md5\S+/i )
816
+ expect( @conn.encrypt_password("postgres", "postgres", "scram-sha-256") ).to match( /SCRAM-SHA-256\S+/i )
817
+ end
818
+
819
+ it "raises an appropriate error if either of the required arguments is not valid" do
820
+ expect {
821
+ @conn.encrypt_password( nil, nil )
822
+ }.to raise_error( TypeError )
823
+ expect {
824
+ @conn.encrypt_password( "postgres", nil )
825
+ }.to raise_error( TypeError )
826
+ expect {
827
+ @conn.encrypt_password( nil, "postgres" )
828
+ }.to raise_error( TypeError )
829
+ expect {
830
+ @conn.encrypt_password( "postgres", "postgres", :invalid )
831
+ }.to raise_error( TypeError )
832
+ expect {
833
+ @conn.encrypt_password( "postgres", "postgres", "invalid" )
834
+ }.to raise_error( PG::Error, /unrecognized/ )
835
+ end
794
836
  end
795
837
 
796
838
 
@@ -889,155 +931,147 @@ describe PG::Connection do
889
931
  expect{ conn.block }.to raise_error(PG::ConnectionBad, /can't get socket descriptor/)
890
932
  end
891
933
 
892
- context "under PostgreSQL 9", :postgresql_90 do
934
+ it "sets the fallback_application_name on new connections" do
935
+ conn_string = PG::Connection.parse_connect_args( 'dbname=test' )
893
936
 
894
- before( :each ) do
895
- pending "only works with a PostgreSQL >= 9.0 server" if @conn.server_version < 9_00_00
896
- end
937
+ conn_name = conn_string[ /application_name='(.*?)'/, 1 ]
938
+ expect( conn_name ).to include( $0[0..10] )
939
+ expect( conn_name ).to include( $0[-10..-1] )
940
+ expect( conn_name.length ).to be <= 64
941
+ end
897
942
 
898
- it "sets the fallback_application_name on new connections" do
943
+ it "sets a shortened fallback_application_name on new connections" do
944
+ old_0 = $0
945
+ begin
946
+ $0 = "/this/is/a/very/long/path/with/many/directories/to/our/beloved/ruby"
899
947
  conn_string = PG::Connection.parse_connect_args( 'dbname=test' )
900
-
901
948
  conn_name = conn_string[ /application_name='(.*?)'/, 1 ]
902
949
  expect( conn_name ).to include( $0[0..10] )
903
950
  expect( conn_name ).to include( $0[-10..-1] )
904
951
  expect( conn_name.length ).to be <= 64
952
+ ensure
953
+ $0 = old_0
905
954
  end
955
+ end
906
956
 
907
- it "sets a shortened fallback_application_name on new connections" do
908
- old_0 = $0
909
- begin
910
- $0 = "/this/is/a/very/long/path/with/many/directories/to/our/beloved/ruby"
911
- conn_string = PG::Connection.parse_connect_args( 'dbname=test' )
912
- conn_name = conn_string[ /application_name='(.*?)'/, 1 ]
913
- expect( conn_name ).to include( $0[0..10] )
914
- expect( conn_name ).to include( $0[-10..-1] )
915
- expect( conn_name.length ).to be <= 64
916
- ensure
917
- $0 = old_0
918
- end
919
- end
920
-
921
- it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
922
- "any number of arguments" do
923
-
924
- @conn.exec( 'ROLLBACK' )
925
- @conn.exec( 'LISTEN knees' )
957
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
958
+ "any number of arguments" do
926
959
 
927
- conn = described_class.connect( @conninfo )
928
- conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
929
- conn.finish
960
+ @conn.exec( 'ROLLBACK' )
961
+ @conn.exec( 'LISTEN knees' )
930
962
 
931
- event, pid, msg = nil
932
- @conn.wait_for_notify( 10 ) do |*args|
933
- event, pid, msg = *args
934
- end
935
- @conn.exec( 'UNLISTEN knees' )
963
+ conn = described_class.connect( @conninfo )
964
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
965
+ conn.finish
936
966
 
937
- expect( event ).to eq( 'knees' )
938
- expect( pid ).to be_a_kind_of( Integer )
939
- expect( msg ).to eq( 'skirt and boots' )
967
+ event, pid, msg = nil
968
+ @conn.wait_for_notify( 10 ) do |*args|
969
+ event, pid, msg = *args
940
970
  end
971
+ @conn.exec( 'UNLISTEN knees' )
941
972
 
942
- it "accepts nil as the timeout in #wait_for_notify " do
943
- @conn.exec( 'ROLLBACK' )
944
- @conn.exec( 'LISTEN knees' )
973
+ expect( event ).to eq( 'knees' )
974
+ expect( pid ).to be_a_kind_of( Integer )
975
+ expect( msg ).to eq( 'skirt and boots' )
976
+ end
945
977
 
946
- conn = described_class.connect( @conninfo )
947
- conn.exec( %Q{NOTIFY knees} )
948
- conn.finish
978
+ it "accepts nil as the timeout in #wait_for_notify " do
979
+ @conn.exec( 'ROLLBACK' )
980
+ @conn.exec( 'LISTEN knees' )
949
981
 
950
- event, pid = nil
951
- @conn.wait_for_notify( nil ) do |*args|
952
- event, pid = *args
953
- end
954
- @conn.exec( 'UNLISTEN knees' )
982
+ conn = described_class.connect( @conninfo )
983
+ conn.exec( %Q{NOTIFY knees} )
984
+ conn.finish
955
985
 
956
- expect( event ).to eq( 'knees' )
957
- expect( pid ).to be_a_kind_of( Integer )
986
+ event, pid = nil
987
+ @conn.wait_for_notify( nil ) do |*args|
988
+ event, pid = *args
958
989
  end
990
+ @conn.exec( 'UNLISTEN knees' )
959
991
 
960
- it "sends nil as the payload if the notification wasn't given one" do
961
- @conn.exec( 'ROLLBACK' )
962
- @conn.exec( 'LISTEN knees' )
992
+ expect( event ).to eq( 'knees' )
993
+ expect( pid ).to be_a_kind_of( Integer )
994
+ end
963
995
 
964
- conn = described_class.connect( @conninfo )
965
- conn.exec( %Q{NOTIFY knees} )
966
- conn.finish
996
+ it "sends nil as the payload if the notification wasn't given one" do
997
+ @conn.exec( 'ROLLBACK' )
998
+ @conn.exec( 'LISTEN knees' )
967
999
 
968
- payload = :notnil
969
- @conn.wait_for_notify( nil ) do |*args|
970
- payload = args[ 2 ]
971
- end
972
- @conn.exec( 'UNLISTEN knees' )
1000
+ conn = described_class.connect( @conninfo )
1001
+ conn.exec( %Q{NOTIFY knees} )
1002
+ conn.finish
973
1003
 
974
- expect( payload ).to be_nil()
1004
+ payload = :notnil
1005
+ @conn.wait_for_notify( nil ) do |*args|
1006
+ payload = args[ 2 ]
975
1007
  end
1008
+ @conn.exec( 'UNLISTEN knees' )
976
1009
 
977
- it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
978
- "two arguments" do
1010
+ expect( payload ).to be_nil()
1011
+ end
979
1012
 
980
- @conn.exec( 'ROLLBACK' )
981
- @conn.exec( 'LISTEN knees' )
1013
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
1014
+ "two arguments" do
982
1015
 
983
- conn = described_class.connect( @conninfo )
984
- conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
985
- conn.finish
1016
+ @conn.exec( 'ROLLBACK' )
1017
+ @conn.exec( 'LISTEN knees' )
986
1018
 
987
- event, pid, msg = nil
988
- @conn.wait_for_notify( 10 ) do |arg1, arg2|
989
- event, pid, msg = arg1, arg2
990
- end
991
- @conn.exec( 'UNLISTEN knees' )
1019
+ conn = described_class.connect( @conninfo )
1020
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
1021
+ conn.finish
992
1022
 
993
- expect( event ).to eq( 'knees' )
994
- expect( pid ).to be_a_kind_of( Integer )
995
- expect( msg ).to be_nil()
1023
+ event, pid, msg = nil
1024
+ @conn.wait_for_notify( 10 ) do |arg1, arg2|
1025
+ event, pid, msg = arg1, arg2
996
1026
  end
1027
+ @conn.exec( 'UNLISTEN knees' )
997
1028
 
998
- it "calls the block supplied to wait_for_notify with the notify payload if it " +
999
- "doesn't accept arguments" do
1029
+ expect( event ).to eq( 'knees' )
1030
+ expect( pid ).to be_a_kind_of( Integer )
1031
+ expect( msg ).to be_nil()
1032
+ end
1000
1033
 
1001
- @conn.exec( 'ROLLBACK' )
1002
- @conn.exec( 'LISTEN knees' )
1034
+ it "calls the block supplied to wait_for_notify with the notify payload if it " +
1035
+ "doesn't accept arguments" do
1003
1036
 
1004
- conn = described_class.connect( @conninfo )
1005
- conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
1006
- conn.finish
1037
+ @conn.exec( 'ROLLBACK' )
1038
+ @conn.exec( 'LISTEN knees' )
1007
1039
 
1008
- notification_received = false
1009
- @conn.wait_for_notify( 10 ) do
1010
- notification_received = true
1011
- end
1012
- @conn.exec( 'UNLISTEN knees' )
1040
+ conn = described_class.connect( @conninfo )
1041
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
1042
+ conn.finish
1013
1043
 
1014
- expect( notification_received ).to be_truthy()
1044
+ notification_received = false
1045
+ @conn.wait_for_notify( 10 ) do
1046
+ notification_received = true
1015
1047
  end
1048
+ @conn.exec( 'UNLISTEN knees' )
1016
1049
 
1017
- it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
1018
- "three arguments" do
1050
+ expect( notification_received ).to be_truthy()
1051
+ end
1019
1052
 
1020
- @conn.exec( 'ROLLBACK' )
1021
- @conn.exec( 'LISTEN knees' )
1053
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
1054
+ "three arguments" do
1022
1055
 
1023
- conn = described_class.connect( @conninfo )
1024
- conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
1025
- conn.finish
1056
+ @conn.exec( 'ROLLBACK' )
1057
+ @conn.exec( 'LISTEN knees' )
1026
1058
 
1027
- event, pid, msg = nil
1028
- @conn.wait_for_notify( 10 ) do |arg1, arg2, arg3|
1029
- event, pid, msg = arg1, arg2, arg3
1030
- end
1031
- @conn.exec( 'UNLISTEN knees' )
1059
+ conn = described_class.connect( @conninfo )
1060
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
1061
+ conn.finish
1032
1062
 
1033
- expect( event ).to eq( 'knees' )
1034
- expect( pid ).to be_a_kind_of( Integer )
1035
- expect( msg ).to eq( 'skirt and boots' )
1063
+ event, pid, msg = nil
1064
+ @conn.wait_for_notify( 10 ) do |arg1, arg2, arg3|
1065
+ event, pid, msg = arg1, arg2, arg3
1036
1066
  end
1067
+ @conn.exec( 'UNLISTEN knees' )
1037
1068
 
1069
+ expect( event ).to eq( 'knees' )
1070
+ expect( pid ).to be_a_kind_of( Integer )
1071
+ expect( msg ).to eq( 'skirt and boots' )
1038
1072
  end
1039
1073
 
1040
- context "under PostgreSQL 9.1 client library", :postgresql_91, :without_transaction do
1074
+ context "server ping", :without_transaction do
1041
1075
 
1042
1076
  it "pings successfully with connection string" do
1043
1077
  ping = described_class.ping(@conninfo)
@@ -1070,71 +1104,69 @@ describe PG::Connection do
1070
1104
  expect( ping ).to eq( PG::PQPING_NO_ATTEMPT )
1071
1105
  end
1072
1106
 
1073
-
1074
1107
  end
1075
1108
 
1076
- context "under PostgreSQL 9.2 client library", :postgresql_92 do
1077
- describe "set_single_row_mode" do
1109
+ describe "set_single_row_mode" do
1078
1110
 
1079
- it "raises an error when called at the wrong time" do
1080
- expect {
1081
- @conn.set_single_row_mode
1082
- }.to raise_error(PG::Error)
1111
+ it "raises an error when called at the wrong time" do
1112
+ expect {
1113
+ @conn.set_single_row_mode
1114
+ }.to raise_error(PG::Error)
1115
+ end
1116
+
1117
+ it "should work in single row mode" do
1118
+ @conn.send_query( "SELECT generate_series(1,10)" )
1119
+ @conn.set_single_row_mode
1120
+
1121
+ results = []
1122
+ loop do
1123
+ @conn.block
1124
+ res = @conn.get_result or break
1125
+ results << res
1083
1126
  end
1127
+ expect( results.length ).to eq( 11 )
1128
+ results[0..-2].each do |res|
1129
+ expect( res.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
1130
+ values = res.field_values('generate_series')
1131
+ expect( values.length ).to eq( 1 )
1132
+ expect( values.first.to_i ).to be > 0
1133
+ end
1134
+ expect( results.last.result_status ).to eq( PG::PGRES_TUPLES_OK )
1135
+ expect( results.last.ntuples ).to eq( 0 )
1136
+ end
1084
1137
 
1085
- it "should work in single row mode" do
1086
- @conn.send_query( "SELECT generate_series(1,10)" )
1087
- @conn.set_single_row_mode
1138
+ it "should receive rows before entire query is finished" do
1139
+ @conn.send_query( "SELECT generate_series(0,999), NULL UNION ALL SELECT 1000, pg_sleep(1);" )
1140
+ @conn.set_single_row_mode
1088
1141
 
1089
- results = []
1090
- loop do
1091
- @conn.block
1092
- res = @conn.get_result or break
1093
- results << res
1094
- end
1095
- expect( results.length ).to eq( 11 )
1096
- results[0..-2].each do |res|
1097
- expect( res.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
1098
- values = res.field_values('generate_series')
1099
- expect( values.length ).to eq( 1 )
1100
- expect( values.first.to_i ).to be > 0
1101
- end
1102
- expect( results.last.result_status ).to eq( PG::PGRES_TUPLES_OK )
1103
- expect( results.last.ntuples ).to eq( 0 )
1142
+ start_time = Time.now
1143
+ first_row_time = nil
1144
+ loop do
1145
+ res = @conn.get_result or break
1146
+ res.check
1147
+ first_row_time = Time.now unless first_row_time
1104
1148
  end
1149
+ expect( (Time.now - start_time) ).to be >= 0.9
1150
+ expect( (first_row_time - start_time) ).to be < 0.9
1151
+ end
1105
1152
 
1106
- it "should receive rows before entire query is finished" do
1107
- @conn.send_query( "SELECT generate_series(0,999), NULL UNION ALL SELECT 1000, pg_sleep(1);" )
1108
- @conn.set_single_row_mode
1153
+ it "should receive rows before entire query fails" do
1154
+ @conn.exec( "CREATE FUNCTION errfunc() RETURNS int AS $$ BEGIN RAISE 'test-error'; END; $$ LANGUAGE plpgsql;" )
1155
+ @conn.send_query( "SELECT generate_series(0,999), NULL UNION ALL SELECT 1000, errfunc();" )
1156
+ @conn.set_single_row_mode
1109
1157
 
1110
- start_time = Time.now
1111
- first_row_time = nil
1158
+ first_result = nil
1159
+ expect do
1112
1160
  loop do
1113
1161
  res = @conn.get_result or break
1114
1162
  res.check
1115
- first_row_time = Time.now unless first_row_time
1163
+ first_result ||= res
1116
1164
  end
1117
- expect( (Time.now - start_time) ).to be >= 0.9
1118
- expect( (first_row_time - start_time) ).to be < 0.9
1119
- end
1120
-
1121
- it "should receive rows before entire query fails" do
1122
- @conn.exec( "CREATE FUNCTION errfunc() RETURNS int AS $$ BEGIN RAISE 'test-error'; END; $$ LANGUAGE plpgsql;" )
1123
- @conn.send_query( "SELECT generate_series(0,999), NULL UNION ALL SELECT 1000, errfunc();" )
1124
- @conn.set_single_row_mode
1125
-
1126
- first_result = nil
1127
- expect do
1128
- loop do
1129
- res = @conn.get_result or break
1130
- res.check
1131
- first_result ||= res
1132
- end
1133
- end.to raise_error(PG::Error)
1134
- expect( first_result.kind_of?(PG::Result) ).to be_truthy
1135
- expect( first_result.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
1136
- end
1165
+ end.to raise_error(PG::Error)
1166
+ expect( first_result.kind_of?(PG::Result) ).to be_truthy
1167
+ expect( first_result.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
1137
1168
  end
1169
+
1138
1170
  end
1139
1171
 
1140
1172
  context "multinationalization support", :ruby_19 do
@@ -1201,7 +1233,7 @@ describe PG::Connection do
1201
1233
  expect( escaped ).to eq( "Möhre to".encode(Encoding::EUC_JP) )
1202
1234
  end
1203
1235
 
1204
- it "uses the client encoding for escaped literal", :postgresql_90 do
1236
+ it "uses the client encoding for escaped literal" do
1205
1237
  original = "Möhre to\0 escape".encode( "utf-16be" )
1206
1238
  @conn.set_client_encoding( "euc_jp" )
1207
1239
  escaped = @conn.escape_literal( original )
@@ -1209,7 +1241,7 @@ describe PG::Connection do
1209
1241
  expect( escaped ).to eq( "'Möhre to'".encode(Encoding::EUC_JP) )
1210
1242
  end
1211
1243
 
1212
- it "uses the client encoding for escaped identifier", :postgresql_90 do
1244
+ it "uses the client encoding for escaped identifier" do
1213
1245
  original = "Möhre to\0 escape".encode( "utf-16le" )
1214
1246
  @conn.set_client_encoding( "euc_jp" )
1215
1247
  escaped = @conn.escape_identifier( original )
@@ -1240,6 +1272,12 @@ describe PG::Connection do
1240
1272
  expect( escaped.encoding ).to eq( Encoding::ISO8859_1 )
1241
1273
  expect( escaped.encode ).to eq( "\"Möhre to\"".encode(Encoding::ISO8859_1) )
1242
1274
  end
1275
+
1276
+ it "raises appropriate error if set_client_encoding is called with invalid arguments" do
1277
+ expect { @conn.set_client_encoding( "invalid" ) }.to raise_error(PG::Error, /invalid value/)
1278
+ expect { @conn.set_client_encoding( :invalid ) }.to raise_error(TypeError)
1279
+ expect { @conn.set_client_encoding( nil ) }.to raise_error(TypeError)
1280
+ end
1243
1281
  end
1244
1282
 
1245
1283
  describe "respect and convert character encoding of input strings" do
@@ -1408,7 +1446,7 @@ describe PG::Connection do
1408
1446
  conn.finish if conn
1409
1447
  end
1410
1448
 
1411
- it "handles clearing result in or after set_notice_receiver", :postgresql_90 do
1449
+ it "handles clearing result in or after set_notice_receiver" do
1412
1450
  r = nil
1413
1451
  @conn.set_notice_receiver do |result|
1414
1452
  r = result
@@ -1423,7 +1461,7 @@ describe PG::Connection do
1423
1461
  @conn.set_notice_receiver
1424
1462
  end
1425
1463
 
1426
- it "receives properly encoded messages in the notice callbacks", :postgresql_90 do
1464
+ it "receives properly encoded messages in the notice callbacks" do
1427
1465
  [:receiver, :processor].each do |kind|
1428
1466
  notices = []
1429
1467
  @conn.internal_encoding = 'utf-8'
@@ -1451,7 +1489,7 @@ describe PG::Connection do
1451
1489
  end
1452
1490
  end
1453
1491
 
1454
- it "receives properly encoded text from wait_for_notify", :postgresql_90 do
1492
+ it "receives properly encoded text from wait_for_notify" do
1455
1493
  @conn.internal_encoding = 'utf-8'
1456
1494
  @conn.exec( 'ROLLBACK' )
1457
1495
  @conn.exec( 'LISTEN "Möhre"' )
@@ -1468,7 +1506,7 @@ describe PG::Connection do
1468
1506
  expect( msg.encoding ).to eq( Encoding::UTF_8 )
1469
1507
  end
1470
1508
 
1471
- it "returns properly encoded text from notifies", :postgresql_90 do
1509
+ it "returns properly encoded text from notifies" do
1472
1510
  @conn.internal_encoding = 'utf-8'
1473
1511
  @conn.exec( 'ROLLBACK' )
1474
1512
  @conn.exec( 'LISTEN "Möhre"' )
@@ -1524,9 +1562,14 @@ describe PG::Connection do
1524
1562
  end
1525
1563
 
1526
1564
  it "shouldn't type map params unless requested" do
1527
- expect{
1528
- @conn.exec_params( "SELECT $1", [5] )
1529
- }.to raise_error(PG::IndeterminateDatatype)
1565
+ if @conn.server_version < 100000
1566
+ expect{
1567
+ @conn.exec_params( "SELECT $1", [5] )
1568
+ }.to raise_error(PG::IndeterminateDatatype)
1569
+ else
1570
+ # PostgreSQL-10 maps to TEXT type (OID 25)
1571
+ expect( @conn.exec_params( "SELECT $1", [5] ).ftype(0)).to eq(25)
1572
+ end
1530
1573
  end
1531
1574
 
1532
1575
  it "should raise an error on invalid encoder to put_copy_data" do