pg 0.18.4 → 0.19.0.pre20160409114042

Sign up to get free protection for your applications and to get access to all the features.
@@ -198,6 +198,14 @@
198
198
  VALUE klass = define_error_class( "InvalidRowCountInResultOffsetClause", "22" );
199
199
  register_error_class( "2201X", klass );
200
200
  }
201
+ {
202
+ VALUE klass = define_error_class( "InvalidTablesampleArgument", "22" );
203
+ register_error_class( "2202H", klass );
204
+ }
205
+ {
206
+ VALUE klass = define_error_class( "InvalidTablesampleRepeat", "22" );
207
+ register_error_class( "2202G", klass );
208
+ }
201
209
  {
202
210
  VALUE klass = define_error_class( "InvalidTimeZoneDisplacementValue", "22" );
203
211
  register_error_class( "22009", klass );
@@ -466,6 +474,10 @@
466
474
  VALUE klass = define_error_class( "ERIESrfProtocolViolated", "39" );
467
475
  register_error_class( "39P02", klass );
468
476
  }
477
+ {
478
+ VALUE klass = define_error_class( "ERIEEventTriggerProtocolViolated", "39" );
479
+ register_error_class( "39P03", klass );
480
+ }
469
481
  {
470
482
  VALUE klass = define_error_class( "SavepointException", NULL );
471
483
  register_error_class( "3B000", klass );
@@ -916,6 +928,10 @@
916
928
  VALUE klass = define_error_class( "TooManyRows", "P0" );
917
929
  register_error_class( "P0003", klass );
918
930
  }
931
+ {
932
+ VALUE klass = define_error_class( "AssertFailure", "P0" );
933
+ register_error_class( "P0004", klass );
934
+ }
919
935
  {
920
936
  VALUE klass = define_error_class( "InternalError", NULL );
921
937
  register_error_class( "XX000", klass );
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2013, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2016, PostgreSQL Global Development Group
6
6
  #
7
7
  # This list serves as the basis for generating source files containing error
8
8
  # codes. It is kept in a common format to make sure all these source files have
@@ -177,6 +177,8 @@ Section: Class 22 - Data Exception
177
177
  2201B E ERRCODE_INVALID_REGULAR_EXPRESSION invalid_regular_expression
178
178
  2201W E ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE invalid_row_count_in_limit_clause
179
179
  2201X E ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE invalid_row_count_in_result_offset_clause
180
+ 2202H E ERRCODE_INVALID_TABLESAMPLE_ARGUMENT invalid_tablesample_argument
181
+ 2202G E ERRCODE_INVALID_TABLESAMPLE_REPEAT invalid_tablesample_repeat
180
182
  22009 E ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE invalid_time_zone_displacement_value
181
183
  2200C E ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER invalid_use_of_escape_character
182
184
  2200G E ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH most_specific_type_mismatch
@@ -278,6 +280,7 @@ Section: Class 39 - External Routine Invocation Exception
278
280
  39004 E ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED null_value_not_allowed
279
281
  39P01 E ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED trigger_protocol_violated
280
282
  39P02 E ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED srf_protocol_violated
283
+ 39P03 E ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED event_trigger_protocol_violated
281
284
 
282
285
  Section: Class 3B - Savepoint Exception
283
286
 
@@ -454,6 +457,7 @@ P0000 E ERRCODE_PLPGSQL_ERROR plp
454
457
  P0001 E ERRCODE_RAISE_EXCEPTION raise_exception
455
458
  P0002 E ERRCODE_NO_DATA_FOUND no_data_found
456
459
  P0003 E ERRCODE_TOO_MANY_ROWS too_many_rows
460
+ P0004 E ERRCODE_ASSERT_FAILURE assert_failure
457
461
 
458
462
  Section: Class XX - Internal Error
459
463
 
@@ -24,7 +24,11 @@ if enable_config("windows-cross")
24
24
  else
25
25
  # Native build
26
26
 
27
- if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
27
+ pgconfig = with_config('pg-config') ||
28
+ with_config('pg_config') ||
29
+ find_executable('pg_config')
30
+
31
+ if pgconfig && pgconfig != 'ignore'
28
32
  $stderr.puts "Using config values from %s" % [ pgconfig ]
29
33
  incdir = `"#{pgconfig}" --includedir`.chomp
30
34
  libdir = `"#{pgconfig}" --libdir`.chomp
@@ -73,6 +77,7 @@ have_func 'PQlibVersion'
73
77
  have_func 'PQping'
74
78
  have_func 'PQsetSingleRowMode'
75
79
  have_func 'PQconninfo'
80
+ have_func 'PQsslAttribute'
76
81
 
77
82
  have_func 'rb_encdb_alias'
78
83
  have_func 'rb_enc_alias'
data/ext/pg.h CHANGED
@@ -9,6 +9,9 @@
9
9
  #include <stdio.h>
10
10
  #include <stdlib.h>
11
11
  #include <sys/types.h>
12
+ #if !defined(_WIN32)
13
+ # include <sys/time.h>
14
+ #endif
12
15
  #if defined(HAVE_UNISTD_H) && !defined(_WIN32)
13
16
  # include <unistd.h>
14
17
  #endif /* HAVE_UNISTD_H */
@@ -205,7 +208,7 @@ typedef struct {
205
208
  } t_pg_result;
206
209
 
207
210
 
208
- typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *);
211
+ typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
209
212
  typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
210
213
  typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
211
214
  typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
@@ -321,8 +324,8 @@ void init_pg_binary_decoder _(( void ));
321
324
  VALUE lookup_error_class _(( const char * ));
322
325
  VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
323
326
  VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
324
- int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *));
325
- int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *));
327
+ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
328
+ int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
326
329
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
327
330
  t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
328
331
  void pg_define_coder _(( const char *, void *, VALUE, VALUE ));
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_encoder.c,v 72168db5fb7b 2015/11/04 16:13:42 lars $
3
+ * $Id: pg_binary_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
4
4
  *
5
5
  */
6
6
 
@@ -22,7 +22,7 @@ VALUE rb_mPG_BinaryEncoder;
22
22
  *
23
23
  */
24
24
  static int
25
- pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
25
+ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
26
26
  {
27
27
  char mybool;
28
28
  switch(value){
@@ -44,7 +44,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
44
44
  *
45
45
  */
46
46
  static int
47
- pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
47
+ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
48
48
  {
49
49
  if(out){
50
50
  write_nbo16(NUM2INT(*intermediate), out);
@@ -63,7 +63,7 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
63
63
  *
64
64
  */
65
65
  static int
66
- pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
66
+ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
67
67
  {
68
68
  if(out){
69
69
  write_nbo32(NUM2LONG(*intermediate), out);
@@ -82,7 +82,7 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
82
82
  *
83
83
  */
84
84
  static int
85
- pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
85
+ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
86
86
  {
87
87
  if(out){
88
88
  write_nbo64(NUM2LL(*intermediate), out);
@@ -100,7 +100,7 @@ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
100
100
  *
101
101
  */
102
102
  static int
103
- pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
103
+ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
104
104
  {
105
105
  int strlen;
106
106
  VALUE subint;
@@ -109,13 +109,13 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
109
109
 
110
110
  if(out){
111
111
  /* Second encoder pass, if required */
112
- strlen = enc_func(this->elem, value, out, intermediate);
112
+ strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
113
113
  strlen = base64_decode( out, out, strlen );
114
114
 
115
115
  return strlen;
116
116
  } else {
117
117
  /* First encoder pass */
118
- strlen = enc_func(this->elem, value, NULL, &subint);
118
+ strlen = enc_func(this->elem, value, NULL, &subint, enc_idx);
119
119
 
120
120
  if( strlen == -1 ){
121
121
  /* Encoded string is returned in subint */
@@ -114,13 +114,24 @@ pg_composite_decoder_allocate( VALUE klass )
114
114
  *
115
115
  */
116
116
  static VALUE
117
- pg_coder_encode(VALUE self, VALUE value)
117
+ pg_coder_encode(int argc, VALUE *argv, VALUE self)
118
118
  {
119
119
  VALUE res;
120
120
  VALUE intermediate;
121
+ VALUE value;
121
122
  int len, len2;
123
+ int enc_idx;
122
124
  t_pg_coder *this = DATA_PTR(self);
123
125
 
126
+ if(argc < 1 || argc > 2){
127
+ rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
128
+ }else if(argc == 1){
129
+ enc_idx = rb_ascii8bit_encindex();
130
+ }else{
131
+ enc_idx = rb_to_encoding_index(argv[1]);
132
+ }
133
+ value = argv[0];
134
+
124
135
  if( NIL_P(value) )
125
136
  return Qnil;
126
137
 
@@ -128,7 +139,7 @@ pg_coder_encode(VALUE self, VALUE value)
128
139
  rb_raise(rb_eRuntimeError, "no encoder function defined");
129
140
  }
130
141
 
131
- len = this->enc_func( this, value, NULL, &intermediate );
142
+ len = this->enc_func( this, value, NULL, &intermediate, enc_idx );
132
143
 
133
144
  if( len == -1 ){
134
145
  /* The intermediate value is a String that can be used directly. */
@@ -137,7 +148,8 @@ pg_coder_encode(VALUE self, VALUE value)
137
148
  }
138
149
 
139
150
  res = rb_str_new(NULL, len);
140
- len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate);
151
+ PG_ENCODING_SET_NOCHECK(res, enc_idx);
152
+ len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
141
153
  if( len < len2 ){
142
154
  rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
143
155
  rb_obj_classname( self ), len, len2 );
@@ -165,8 +177,8 @@ static VALUE
165
177
  pg_coder_decode(int argc, VALUE *argv, VALUE self)
166
178
  {
167
179
  char *val;
168
- VALUE tuple = -1;
169
- VALUE field = -1;
180
+ int tuple = -1;
181
+ int field = -1;
170
182
  VALUE res;
171
183
  t_pg_coder *this = DATA_PTR(self);
172
184
 
@@ -359,10 +371,19 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
359
371
 
360
372
 
361
373
  static int
362
- pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
374
+ pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
363
375
  {
364
- *intermediate = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
365
- StringValue( *intermediate );
376
+ int arity = rb_obj_method_arity(conv->coder_obj, s_id_encode);
377
+ if( arity == 1 ){
378
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
379
+ StringValue( out_str );
380
+ *intermediate = rb_str_export_to_enc(out_str, rb_enc_from_index(enc_idx));
381
+ }else{
382
+ VALUE enc = rb_enc_from_encoding(rb_enc_from_index(enc_idx));
383
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 2, value, enc );
384
+ StringValue( out_str );
385
+ *intermediate = out_str;
386
+ }
366
387
  return -1;
367
388
  }
368
389
 
@@ -442,7 +463,7 @@ init_pg_coder()
442
463
  * This accessor is only used in PG::Coder#inspect .
443
464
  */
444
465
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
445
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, 1 );
466
+ rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
446
467
  rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
447
468
 
448
469
  /* Document-class: PG::SimpleCoder < PG::Coder */
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_connection.c - PG::Connection class extension
3
- * $Id: pg_connection.c,v eb4d3c003bd6 2015/05/25 20:04:04 ged $
3
+ * $Id: pg_connection.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
4
4
  *
5
5
  */
6
6
 
@@ -52,7 +52,7 @@ pg_get_connection( VALUE self )
52
52
  * Fetch the PG::Connection object data pointer and check it's
53
53
  * PGconn data pointer for sanity.
54
54
  */
55
- t_pg_connection *
55
+ static t_pg_connection *
56
56
  pg_get_connection_safe( VALUE self )
57
57
  {
58
58
  t_pg_connection *this;
@@ -88,7 +88,7 @@ pg_get_pgconn( VALUE self )
88
88
  /*
89
89
  * Close the associated socket IO object if there is one.
90
90
  */
91
- void
91
+ static void
92
92
  pgconn_close_socket_io( VALUE self )
93
93
  {
94
94
  t_pg_connection *this = pg_get_connection( self );
@@ -141,6 +141,16 @@ pgconn_make_conninfo_array( const PQconninfoOption *options )
141
141
  return ary;
142
142
  }
143
143
 
144
+ static const char *pg_cstr_enc(VALUE str, int enc_idx){
145
+ const char *ptr = StringValueCStr(str);
146
+ if( ENCODING_GET(str) == enc_idx ){
147
+ return ptr;
148
+ } else {
149
+ str = rb_str_export_to_enc(str, rb_enc_from_index(enc_idx));
150
+ return StringValueCStr(str);
151
+ }
152
+ }
153
+
144
154
 
145
155
  /*
146
156
  * GC Mark function
@@ -373,7 +383,7 @@ pgconn_s_ping( int argc, VALUE *argv, VALUE klass )
373
383
 
374
384
 
375
385
  /*
376
- * Document-method: conndefaults
386
+ * Document-method: PG::Connection.conndefaults
377
387
  *
378
388
  * call-seq:
379
389
  * PG::Connection.conndefaults() -> Array
@@ -947,9 +957,9 @@ pgconn_exec(int argc, VALUE *argv, VALUE self)
947
957
 
948
958
  /* If called with no parameters, use PQexec */
949
959
  if ( argc == 1 ) {
950
- Check_Type(argv[0], T_STRING);
960
+ VALUE query_str = argv[0];
951
961
 
952
- result = gvl_PQexec(conn, StringValueCStr(argv[0]));
962
+ result = gvl_PQexec(conn, pg_cstr_enc(query_str, ENCODING_GET(self)));
953
963
  rb_pgresult = pg_new_result(result, self);
954
964
  pg_result_check(rb_pgresult);
955
965
  if (rb_block_given_p()) {
@@ -978,6 +988,10 @@ struct query_params_data {
978
988
  * Filled by caller
979
989
  */
980
990
 
991
+ /* The character encoding index of the connection. Any strings
992
+ * given as query parameters are converted to this encoding.
993
+ */
994
+ int enc_idx;
981
995
  /* Is the query function to execute one with types array? */
982
996
  int with_types;
983
997
  /* Array of query params from user space */
@@ -1138,7 +1152,7 @@ alloc_query_params(struct query_params_data *paramsData)
1138
1152
  VALUE intermediate;
1139
1153
 
1140
1154
  /* 1st pass for retiving the required memory space */
1141
- int len = enc_func(conv, param_value, NULL, &intermediate);
1155
+ int len = enc_func(conv, param_value, NULL, &intermediate, paramsData->enc_idx);
1142
1156
 
1143
1157
  if( len == -1 ){
1144
1158
  /* The intermediate value is a String that can be used directly. */
@@ -1162,7 +1176,7 @@ alloc_query_params(struct query_params_data *paramsData)
1162
1176
  }
1163
1177
 
1164
1178
  /* 2nd pass for writing the data to prepared buffer */
1165
- len = enc_func(conv, param_value, typecast_buf, &intermediate);
1179
+ len = enc_func(conv, param_value, typecast_buf, &intermediate, paramsData->enc_idx);
1166
1180
  paramsData->values[i] = typecast_buf;
1167
1181
  if( paramsData->formats[i] == 0 ){
1168
1182
  /* text format strings must be zero terminated and lengths are ignored */
@@ -1258,7 +1272,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1258
1272
  VALUE command, in_res_fmt;
1259
1273
  int nParams;
1260
1274
  int resultFormat;
1261
- struct query_params_data paramsData;
1275
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1262
1276
 
1263
1277
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1264
1278
  paramsData.with_types = 1;
@@ -1275,7 +1289,7 @@ pgconn_exec_params( int argc, VALUE *argv, VALUE self )
1275
1289
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1276
1290
  nParams = alloc_query_params( &paramsData );
1277
1291
 
1278
- result = gvl_PQexecParams(conn, StringValueCStr(command), nParams, paramsData.types,
1292
+ result = gvl_PQexecParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1279
1293
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1280
1294
 
1281
1295
  free_query_params( &paramsData );
@@ -1321,10 +1335,13 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1321
1335
  int i = 0;
1322
1336
  int nParams = 0;
1323
1337
  Oid *paramTypes = NULL;
1338
+ const char *name_cstr;
1339
+ const char *command_cstr;
1340
+ int enc_idx = ENCODING_GET(self);
1324
1341
 
1325
1342
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1326
- Check_Type(name, T_STRING);
1327
- Check_Type(command, T_STRING);
1343
+ name_cstr = pg_cstr_enc(name, enc_idx);
1344
+ command_cstr = pg_cstr_enc(command, enc_idx);
1328
1345
 
1329
1346
  if(! NIL_P(in_paramtypes)) {
1330
1347
  Check_Type(in_paramtypes, T_ARRAY);
@@ -1338,8 +1355,7 @@ pgconn_prepare(int argc, VALUE *argv, VALUE self)
1338
1355
  paramTypes[i] = NUM2UINT(param);
1339
1356
  }
1340
1357
  }
1341
- result = gvl_PQprepare(conn, StringValueCStr(name), StringValueCStr(command),
1342
- nParams, paramTypes);
1358
+ result = gvl_PQprepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1343
1359
 
1344
1360
  xfree(paramTypes);
1345
1361
 
@@ -1392,11 +1408,10 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1392
1408
  VALUE name, in_res_fmt;
1393
1409
  int nParams;
1394
1410
  int resultFormat;
1395
- struct query_params_data paramsData;
1411
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1396
1412
 
1397
1413
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1398
1414
  paramsData.with_types = 0;
1399
- Check_Type(name, T_STRING);
1400
1415
 
1401
1416
  if(NIL_P(paramsData.params)) {
1402
1417
  paramsData.params = rb_ary_new2(0);
@@ -1406,7 +1421,7 @@ pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1406
1421
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1407
1422
  nParams = alloc_query_params( &paramsData );
1408
1423
 
1409
- result = gvl_PQexecPrepared(conn, StringValueCStr(name), nParams,
1424
+ result = gvl_PQexecPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1410
1425
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1411
1426
  resultFormat);
1412
1427
 
@@ -1434,13 +1449,12 @@ pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1434
1449
  PGresult *result;
1435
1450
  VALUE rb_pgresult;
1436
1451
  PGconn *conn = pg_get_pgconn(self);
1437
- char *stmt;
1438
- if(stmt_name == Qnil) {
1452
+ const char *stmt;
1453
+ if(NIL_P(stmt_name)) {
1439
1454
  stmt = NULL;
1440
1455
  }
1441
1456
  else {
1442
- Check_Type(stmt_name, T_STRING);
1443
- stmt = StringValueCStr(stmt_name);
1457
+ stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1444
1458
  }
1445
1459
  result = gvl_PQdescribePrepared(conn, stmt);
1446
1460
  rb_pgresult = pg_new_result(result, self);
@@ -1462,13 +1476,12 @@ pgconn_describe_portal(self, stmt_name)
1462
1476
  PGresult *result;
1463
1477
  VALUE rb_pgresult;
1464
1478
  PGconn *conn = pg_get_pgconn(self);
1465
- char *stmt;
1466
- if(stmt_name == Qnil) {
1479
+ const char *stmt;
1480
+ if(NIL_P(stmt_name)) {
1467
1481
  stmt = NULL;
1468
1482
  }
1469
1483
  else {
1470
- Check_Type(stmt_name, T_STRING);
1471
- stmt = StringValueCStr(stmt_name);
1484
+ stmt = pg_cstr_enc(stmt_name, ENCODING_GET(self));
1472
1485
  }
1473
1486
  result = gvl_PQdescribePortal(conn, stmt);
1474
1487
  rb_pgresult = pg_new_result(result, self);
@@ -1510,10 +1523,6 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1510
1523
  * call-seq:
1511
1524
  * conn.escape_string( str ) -> String
1512
1525
  *
1513
- * Connection instance method for versions of 8.1 and higher of libpq
1514
- * uses PQescapeStringConn, which is safer. Avoid calling as a class method,
1515
- * the class method uses the deprecated PQescapeString() API function.
1516
- *
1517
1526
  * Returns a SQL-safe version of the String _str_.
1518
1527
  * This is the preferred way to make strings safe for inclusion in
1519
1528
  * SQL queries.
@@ -1522,32 +1531,41 @@ pgconn_make_empty_pgresult(VALUE self, VALUE status)
1522
1531
  * inside of SQL commands.
1523
1532
  *
1524
1533
  * Encoding of escaped string will be equal to client encoding of connection.
1534
+ *
1535
+ * NOTE: This class version of this method can only be used safely in client
1536
+ * programs that use a single PostgreSQL connection at a time (in this case it can
1537
+ * find out what it needs to know "behind the scenes"). It might give the wrong
1538
+ * results if used in programs that use multiple database connections; use the
1539
+ * same method on the connection object in such cases.
1525
1540
  */
1526
1541
  static VALUE
1527
1542
  pgconn_s_escape(VALUE self, VALUE string)
1528
1543
  {
1529
- char *escaped;
1530
1544
  size_t size;
1531
1545
  int error;
1532
1546
  VALUE result;
1547
+ int enc_idx;
1548
+ int singleton = !rb_obj_is_kind_of(self, rb_cPGconn);
1533
1549
 
1534
1550
  Check_Type(string, T_STRING);
1551
+ enc_idx = ENCODING_GET( singleton ? string : self );
1552
+ if( ENCODING_GET(string) != enc_idx ){
1553
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1554
+ }
1535
1555
 
1536
- escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1);
1537
- if( rb_obj_is_kind_of(self, rb_cPGconn) ) {
1538
- size = PQescapeStringConn(pg_get_pgconn(self), escaped,
1556
+ result = rb_str_new(NULL, RSTRING_LEN(string) * 2 + 1);
1557
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1558
+ if( !singleton ) {
1559
+ size = PQescapeStringConn(pg_get_pgconn(self), RSTRING_PTR(result),
1539
1560
  RSTRING_PTR(string), RSTRING_LEN(string), &error);
1540
1561
  if(error) {
1541
- xfree(escaped);
1542
1562
  rb_raise(rb_ePGerror, "%s", PQerrorMessage(pg_get_pgconn(self)));
1543
1563
  }
1544
1564
  } else {
1545
- size = PQescapeString(escaped, RSTRING_PTR(string), RSTRING_LENINT(string));
1565
+ size = PQescapeString(RSTRING_PTR(result), RSTRING_PTR(string), RSTRING_LEN(string));
1546
1566
  }
1547
- result = rb_str_new(escaped, size);
1548
- xfree(escaped);
1567
+ rb_str_set_len(result, size);
1549
1568
  OBJ_INFECT(result, string);
1550
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET( rb_obj_is_kind_of(self, rb_cPGconn) ? self : string ));
1551
1569
 
1552
1570
  return result;
1553
1571
  }
@@ -1556,13 +1574,6 @@ pgconn_s_escape(VALUE self, VALUE string)
1556
1574
  * call-seq:
1557
1575
  * conn.escape_bytea( string ) -> String
1558
1576
  *
1559
- * Connection instance method for versions of 8.1 and higher of libpq
1560
- * uses PQescapeByteaConn, which is safer. Avoid calling as a class method,
1561
- * the class method uses the deprecated PQescapeBytea() API function.
1562
- *
1563
- * Use the instance method version of this function, it is safer than the
1564
- * class method.
1565
- *
1566
1577
  * Escapes binary data for use within an SQL command with the type +bytea+.
1567
1578
  *
1568
1579
  * Certain byte values must be escaped (but all byte values may be escaped)
@@ -1575,6 +1586,12 @@ pgconn_s_escape(VALUE self, VALUE string)
1575
1586
  *
1576
1587
  * Consider using exec_params, which avoids the need for passing values inside of
1577
1588
  * SQL commands.
1589
+ *
1590
+ * NOTE: This class version of this method can only be used safely in client
1591
+ * programs that use a single PostgreSQL connection at a time (in this case it can
1592
+ * find out what it needs to know "behind the scenes"). It might give the wrong
1593
+ * results if used in programs that use multiple database connections; use the
1594
+ * same method on the connection object in such cases.
1578
1595
  */
1579
1596
  static VALUE
1580
1597
  pgconn_s_escape_bytea(VALUE self, VALUE str)
@@ -1643,8 +1660,12 @@ pgconn_escape_literal(VALUE self, VALUE string)
1643
1660
  char *escaped = NULL;
1644
1661
  VALUE error;
1645
1662
  VALUE result = Qnil;
1663
+ int enc_idx = ENCODING_GET(self);
1646
1664
 
1647
1665
  Check_Type(string, T_STRING);
1666
+ if( ENCODING_GET(string) != enc_idx ){
1667
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1668
+ }
1648
1669
 
1649
1670
  escaped = PQescapeLiteral(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1650
1671
  if (escaped == NULL)
@@ -1657,7 +1678,7 @@ pgconn_escape_literal(VALUE self, VALUE string)
1657
1678
  result = rb_str_new2(escaped);
1658
1679
  PQfreemem(escaped);
1659
1680
  OBJ_INFECT(result, string);
1660
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET(self));
1681
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1661
1682
 
1662
1683
  return result;
1663
1684
  }
@@ -1670,8 +1691,9 @@ pgconn_escape_literal(VALUE self, VALUE string)
1670
1691
  *
1671
1692
  * Escape an arbitrary String +str+ as an identifier.
1672
1693
  *
1673
- * This method does the same as #quote_ident, but uses libpq to
1674
- * process the string.
1694
+ * This method does the same as #quote_ident with a String argument,
1695
+ * but it doesn't support an Array argument and it makes use of libpq
1696
+ * to process the string.
1675
1697
  */
1676
1698
  static VALUE
1677
1699
  pgconn_escape_identifier(VALUE self, VALUE string)
@@ -1680,8 +1702,12 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1680
1702
  char *escaped = NULL;
1681
1703
  VALUE error;
1682
1704
  VALUE result = Qnil;
1705
+ int enc_idx = ENCODING_GET(self);
1683
1706
 
1684
1707
  Check_Type(string, T_STRING);
1708
+ if( ENCODING_GET(string) != enc_idx ){
1709
+ string = rb_str_export_to_enc(string, rb_enc_from_index(enc_idx));
1710
+ }
1685
1711
 
1686
1712
  escaped = PQescapeIdentifier(conn, RSTRING_PTR(string), RSTRING_LEN(string));
1687
1713
  if (escaped == NULL)
@@ -1694,7 +1720,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
1694
1720
  result = rb_str_new2(escaped);
1695
1721
  PQfreemem(escaped);
1696
1722
  OBJ_INFECT(result, string);
1697
- PG_ENCODING_SET_NOCHECK(result, ENCODING_GET(self));
1723
+ PG_ENCODING_SET_NOCHECK(result, enc_idx);
1698
1724
 
1699
1725
  return result;
1700
1726
  }
@@ -1802,15 +1828,14 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1802
1828
  VALUE error;
1803
1829
  int nParams;
1804
1830
  int resultFormat;
1805
- struct query_params_data paramsData;
1831
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1806
1832
 
1807
1833
  rb_scan_args(argc, argv, "13", &command, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1808
1834
  paramsData.with_types = 1;
1809
- Check_Type(command, T_STRING);
1810
1835
 
1811
1836
  /* If called with no parameters, use PQsendQuery */
1812
1837
  if(NIL_P(paramsData.params)) {
1813
- if(gvl_PQsendQuery(conn,StringValueCStr(command)) == 0) {
1838
+ if(gvl_PQsendQuery(conn, pg_cstr_enc(command, paramsData.enc_idx)) == 0) {
1814
1839
  error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1815
1840
  rb_iv_set(error, "@connection", self);
1816
1841
  rb_exc_raise(error);
@@ -1826,7 +1851,7 @@ pgconn_send_query(int argc, VALUE *argv, VALUE self)
1826
1851
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1827
1852
  nParams = alloc_query_params( &paramsData );
1828
1853
 
1829
- result = gvl_PQsendQueryParams(conn, StringValueCStr(command), nParams, paramsData.types,
1854
+ result = gvl_PQsendQueryParams(conn, pg_cstr_enc(command, paramsData.enc_idx), nParams, paramsData.types,
1830
1855
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats, resultFormat);
1831
1856
 
1832
1857
  free_query_params( &paramsData );
@@ -1870,10 +1895,13 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1870
1895
  int i = 0;
1871
1896
  int nParams = 0;
1872
1897
  Oid *paramTypes = NULL;
1898
+ const char *name_cstr;
1899
+ const char *command_cstr;
1900
+ int enc_idx = ENCODING_GET(self);
1873
1901
 
1874
1902
  rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1875
- Check_Type(name, T_STRING);
1876
- Check_Type(command, T_STRING);
1903
+ name_cstr = pg_cstr_enc(name, enc_idx);
1904
+ command_cstr = pg_cstr_enc(command, enc_idx);
1877
1905
 
1878
1906
  if(! NIL_P(in_paramtypes)) {
1879
1907
  Check_Type(in_paramtypes, T_ARRAY);
@@ -1887,8 +1915,7 @@ pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1887
1915
  paramTypes[i] = NUM2UINT(param);
1888
1916
  }
1889
1917
  }
1890
- result = gvl_PQsendPrepare(conn, StringValueCStr(name), StringValueCStr(command),
1891
- nParams, paramTypes);
1918
+ result = gvl_PQsendPrepare(conn, name_cstr, command_cstr, nParams, paramTypes);
1892
1919
 
1893
1920
  xfree(paramTypes);
1894
1921
 
@@ -1941,11 +1968,10 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1941
1968
  VALUE error;
1942
1969
  int nParams;
1943
1970
  int resultFormat;
1944
- struct query_params_data paramsData;
1971
+ struct query_params_data paramsData = { ENCODING_GET(self) };
1945
1972
 
1946
1973
  rb_scan_args(argc, argv, "13", &name, &paramsData.params, &in_res_fmt, &paramsData.typemap);
1947
1974
  paramsData.with_types = 0;
1948
- Check_Type(name, T_STRING);
1949
1975
 
1950
1976
  if(NIL_P(paramsData.params)) {
1951
1977
  paramsData.params = rb_ary_new2(0);
@@ -1956,7 +1982,7 @@ pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1956
1982
  resultFormat = NIL_P(in_res_fmt) ? 0 : NUM2INT(in_res_fmt);
1957
1983
  nParams = alloc_query_params( &paramsData );
1958
1984
 
1959
- result = gvl_PQsendQueryPrepared(conn, StringValueCStr(name), nParams,
1985
+ result = gvl_PQsendQueryPrepared(conn, pg_cstr_enc(name, paramsData.enc_idx), nParams,
1960
1986
  (const char * const *)paramsData.values, paramsData.lengths, paramsData.formats,
1961
1987
  resultFormat);
1962
1988
 
@@ -1983,7 +2009,7 @@ pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
1983
2009
  VALUE error;
1984
2010
  PGconn *conn = pg_get_pgconn(self);
1985
2011
  /* returns 0 on failure */
1986
- if(gvl_PQsendDescribePrepared(conn,StringValueCStr(stmt_name)) == 0) {
2012
+ if(gvl_PQsendDescribePrepared(conn, pg_cstr_enc(stmt_name, ENCODING_GET(self))) == 0) {
1987
2013
  error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
1988
2014
  rb_iv_set(error, "@connection", self);
1989
2015
  rb_exc_raise(error);
@@ -2005,7 +2031,7 @@ pgconn_send_describe_portal(VALUE self, VALUE portal)
2005
2031
  VALUE error;
2006
2032
  PGconn *conn = pg_get_pgconn(self);
2007
2033
  /* returns 0 on failure */
2008
- if(gvl_PQsendDescribePortal(conn,StringValueCStr(portal)) == 0) {
2034
+ if(gvl_PQsendDescribePortal(conn, pg_cstr_enc(portal, ENCODING_GET(self))) == 0) {
2009
2035
  error = rb_exc_new2(rb_eUnableToSend, PQerrorMessage(conn));
2010
2036
  rb_iv_set(error, "@connection", self);
2011
2037
  rb_exc_raise(error);
@@ -2565,16 +2591,17 @@ pgconn_put_copy_data(int argc, VALUE *argv, VALUE self)
2565
2591
 
2566
2592
  if( p_coder ){
2567
2593
  t_pg_coder_enc_func enc_func;
2594
+ int enc_idx = ENCODING_GET(self);
2568
2595
 
2569
2596
  enc_func = pg_coder_enc_func( p_coder );
2570
- len = enc_func( p_coder, value, NULL, &intermediate );
2597
+ len = enc_func( p_coder, value, NULL, &intermediate, enc_idx);
2571
2598
 
2572
2599
  if( len == -1 ){
2573
2600
  /* The intermediate value is a String that can be used directly. */
2574
2601
  buffer = intermediate;
2575
2602
  } else {
2576
2603
  buffer = rb_str_new(NULL, len);
2577
- len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate);
2604
+ len = enc_func( p_coder, value, RSTRING_PTR(buffer), &intermediate, enc_idx);
2578
2605
  rb_str_set_len( buffer, len );
2579
2606
  }
2580
2607
  }
@@ -2613,13 +2640,13 @@ pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2613
2640
  VALUE str;
2614
2641
  VALUE error;
2615
2642
  int ret;
2616
- char *error_message = NULL;
2643
+ const char *error_message = NULL;
2617
2644
  PGconn *conn = pg_get_pgconn(self);
2618
2645
 
2619
2646
  if (rb_scan_args(argc, argv, "01", &str) == 0)
2620
2647
  error_message = NULL;
2621
2648
  else
2622
- error_message = StringValueCStr(str);
2649
+ error_message = pg_cstr_enc(str, ENCODING_GET(self));
2623
2650
 
2624
2651
  ret = gvl_PQputCopyEnd(conn, error_message);
2625
2652
  if(ret == -1) {
@@ -2996,10 +3023,10 @@ pgconn_transaction(VALUE self)
2996
3023
 
2997
3024
  /*
2998
3025
  * call-seq:
2999
- * PG::Connection.quote_ident( str ) -> String
3000
- * PG::Connection.quote_ident( array ) -> String
3001
3026
  * conn.quote_ident( str ) -> String
3002
3027
  * conn.quote_ident( array ) -> String
3028
+ * PG::Connection.quote_ident( str ) -> String
3029
+ * PG::Connection.quote_ident( array ) -> String
3003
3030
  *
3004
3031
  * Returns a string that is safe for inclusion in a SQL query as an
3005
3032
  * identifier. Note: this is not a quote function for values, but for
@@ -3009,7 +3036,7 @@ pgconn_transaction(VALUE self)
3009
3036
  * The identifier <tt>FOO</tt> is folded to lower case, so it actually
3010
3037
  * means <tt>foo</tt>. If you really want to access the case-sensitive
3011
3038
  * field name <tt>FOO</tt>, use this function like
3012
- * <tt>PG::Connection.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
3039
+ * <tt>conn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
3013
3040
  * (with double-quotes). PostgreSQL will see the double-quotes, and
3014
3041
  * it will not fold to lower case.
3015
3042
  *
@@ -3023,15 +3050,27 @@ pgconn_transaction(VALUE self)
3023
3050
  *
3024
3051
  * This method is functional identical to the encoder PG::TextEncoder::Identifier .
3025
3052
  *
3053
+ * If the instance method form is used and the input string character encoding
3054
+ * is different to the connection encoding, then the string is converted to this
3055
+ * encoding, so that the returned string is always encoded as PG::Connection#internal_encoding .
3056
+ *
3057
+ * In the singleton form (PG::Connection.quote_ident) the character encoding
3058
+ * of the result string is set to the character encoding of the input string.
3026
3059
  */
3027
3060
  static VALUE
3028
- pgconn_s_quote_ident(VALUE self, VALUE in_str)
3061
+ pgconn_s_quote_ident(VALUE self, VALUE str_or_array)
3029
3062
  {
3030
3063
  VALUE ret;
3031
- pg_text_enc_identifier(NULL, in_str, NULL, &ret);
3064
+ int enc_idx;
3065
+
3066
+ if( rb_obj_is_kind_of(self, rb_cPGconn) ){
3067
+ enc_idx = ENCODING_GET( self );
3068
+ }else{
3069
+ enc_idx = RB_TYPE_P(str_or_array, T_STRING) ? ENCODING_GET( str_or_array ) : rb_ascii8bit_encindex();
3070
+ }
3071
+ pg_text_enc_identifier(NULL, str_or_array, NULL, &ret, enc_idx);
3032
3072
 
3033
- OBJ_INFECT(ret, in_str);
3034
- PG_ENCODING_SET_NOCHECK(ret, ENCODING_GET( rb_obj_is_kind_of(self, rb_cPGconn) ? self : in_str ));
3073
+ OBJ_INFECT(ret, str_or_array);
3035
3074
 
3036
3075
  return ret;
3037
3076
  }
@@ -3157,6 +3196,84 @@ pgconn_async_exec(int argc, VALUE *argv, VALUE self)
3157
3196
  return rb_pgresult;
3158
3197
  }
3159
3198
 
3199
+
3200
+ #ifdef HAVE_PQSSLATTRIBUTE
3201
+ /* Since PostgreSQL-9.5: */
3202
+
3203
+ /*
3204
+ * call-seq:
3205
+ * conn.ssl_in_use? -> Boolean
3206
+ *
3207
+ * Returns +true+ if the connection uses SSL, +false+ if not.
3208
+ *
3209
+ */
3210
+ static VALUE
3211
+ pgconn_ssl_in_use(VALUE self)
3212
+ {
3213
+ return PQsslInUse(pg_get_pgconn(self)) ? Qtrue : Qfalse;
3214
+ }
3215
+
3216
+
3217
+ /*
3218
+ * call-seq:
3219
+ * conn.ssl_attribute(attribute_name) -> String
3220
+ *
3221
+ * Returns SSL-related information about the connection.
3222
+ *
3223
+ * The list of available attributes varies depending on the SSL library being used,
3224
+ * and the type of connection. If an attribute is not available, returns nil.
3225
+ *
3226
+ * The following attributes are commonly available:
3227
+ *
3228
+ * [+library+]
3229
+ * Name of the SSL implementation in use. (Currently, only "OpenSSL" is implemented)
3230
+ * [+protocol+]
3231
+ * SSL/TLS version in use. Common values are "SSLv2", "SSLv3", "TLSv1", "TLSv1.1" and "TLSv1.2", but an implementation may return other strings if some other protocol is used.
3232
+ * [+key_bits+]
3233
+ * Number of key bits used by the encryption algorithm.
3234
+ * [+cipher+]
3235
+ * A short name of the ciphersuite used, e.g. "DHE-RSA-DES-CBC3-SHA". The names are specific to each SSL implementation.
3236
+ * [+compression+]
3237
+ * If SSL compression is in use, returns the name of the compression algorithm, or "on" if compression is used but the algorithm is not known. If compression is not in use, returns "off".
3238
+ *
3239
+ *
3240
+ * See also #ssl_attribute_names and http://www.postgresql.org/docs/current/interactive/libpq-status.html#LIBPQ-PQSSLATTRIBUTE
3241
+ */
3242
+ static VALUE
3243
+ pgconn_ssl_attribute(VALUE self, VALUE attribute_name)
3244
+ {
3245
+ const char *p_attr;
3246
+
3247
+ p_attr = PQsslAttribute(pg_get_pgconn(self), StringValueCStr(attribute_name));
3248
+ return p_attr ? rb_str_new_cstr(p_attr) : Qnil;
3249
+ }
3250
+
3251
+ /*
3252
+ * call-seq:
3253
+ * conn.ssl_attribute_names -> Array<String>
3254
+ *
3255
+ * Return an array of SSL attribute names available.
3256
+ *
3257
+ * See also #ssl_attribute
3258
+ *
3259
+ */
3260
+ static VALUE
3261
+ pgconn_ssl_attribute_names(VALUE self)
3262
+ {
3263
+ int i;
3264
+ const char * const * p_list = PQsslAttributeNames(pg_get_pgconn(self));
3265
+ VALUE ary = rb_ary_new();
3266
+
3267
+ for ( i = 0; p_list[i]; i++ ) {
3268
+ rb_ary_push( ary, rb_str_new_cstr( p_list[i] ));
3269
+ }
3270
+ return ary;
3271
+ }
3272
+
3273
+
3274
+ #endif
3275
+
3276
+
3160
3277
  /**************************************************************************
3161
3278
  * LARGE OBJECT SUPPORT
3162
3279
  **************************************************************************/
@@ -3704,7 +3821,7 @@ pgconn_encoder_for_put_copy_data_set(VALUE self, VALUE typemap)
3704
3821
  *
3705
3822
  * Returns either:
3706
3823
  * * a kind of PG::Coder
3707
- * * +nil+ - type encoding is disabled, returned data will be a String.
3824
+ * * +nil+ - type encoding is disabled, data must be a String.
3708
3825
  *
3709
3826
  */
3710
3827
  static VALUE
@@ -3765,6 +3882,9 @@ pgconn_decoder_for_get_copy_data_get(VALUE self)
3765
3882
  }
3766
3883
 
3767
3884
 
3885
+ /*
3886
+ * Document-class: PG::Connection
3887
+ */
3768
3888
  void
3769
3889
  init_pg_connection()
3770
3890
  {
@@ -3901,6 +4021,12 @@ init_pg_connection()
3901
4021
  rb_define_alias(rb_cPGconn, "async_query", "async_exec");
3902
4022
  rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
3903
4023
 
4024
+ #ifdef HAVE_PQSSLATTRIBUTE
4025
+ rb_define_method(rb_cPGconn, "ssl_in_use?", pgconn_ssl_in_use, 0);
4026
+ rb_define_method(rb_cPGconn, "ssl_attribute", pgconn_ssl_attribute, 1);
4027
+ rb_define_method(rb_cPGconn, "ssl_attribute_names", pgconn_ssl_attribute_names, 0);
4028
+ #endif
4029
+
3904
4030
  /****** PG::Connection INSTANCE METHODS: Large Object Support ******/
3905
4031
  rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
3906
4032
  rb_define_alias(rb_cPGconn, "locreat", "lo_creat");