pg 0.19.0 → 1.1.0

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.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/ChangeLog +218 -1
  4. data/History.rdoc +106 -0
  5. data/Manifest.txt +5 -18
  6. data/README.rdoc +15 -5
  7. data/Rakefile +8 -9
  8. data/Rakefile.cross +19 -22
  9. data/ext/errorcodes.def +17 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +11 -1
  12. data/ext/extconf.rb +14 -32
  13. data/ext/gvl_wrappers.c +4 -0
  14. data/ext/gvl_wrappers.h +23 -39
  15. data/ext/pg.c +19 -48
  16. data/ext/pg.h +46 -81
  17. data/ext/pg_binary_decoder.c +69 -6
  18. data/ext/pg_coder.c +53 -4
  19. data/ext/pg_connection.c +401 -253
  20. data/ext/pg_copy_coder.c +10 -5
  21. data/ext/pg_result.c +359 -131
  22. data/ext/pg_text_decoder.c +597 -37
  23. data/ext/pg_text_encoder.c +6 -7
  24. data/ext/pg_tuple.c +541 -0
  25. data/ext/pg_type_map.c +14 -7
  26. data/ext/util.c +6 -6
  27. data/ext/util.h +2 -2
  28. data/lib/pg/basic_type_mapping.rb +40 -7
  29. data/lib/pg/binary_decoder.rb +22 -0
  30. data/lib/pg/coder.rb +1 -1
  31. data/lib/pg/connection.rb +27 -7
  32. data/lib/pg/constants.rb +1 -1
  33. data/lib/pg/exceptions.rb +1 -1
  34. data/lib/pg/result.rb +6 -5
  35. data/lib/pg/text_decoder.rb +19 -23
  36. data/lib/pg/text_encoder.rb +36 -2
  37. data/lib/pg/tuple.rb +30 -0
  38. data/lib/pg/type_map_by_column.rb +1 -1
  39. data/lib/pg.rb +21 -11
  40. data/spec/helpers.rb +47 -19
  41. data/spec/pg/basic_type_mapping_spec.rb +230 -27
  42. data/spec/pg/connection_spec.rb +402 -275
  43. data/spec/pg/connection_sync_spec.rb +41 -0
  44. data/spec/pg/result_spec.rb +59 -17
  45. data/spec/pg/tuple_spec.rb +280 -0
  46. data/spec/pg/type_map_by_class_spec.rb +2 -2
  47. data/spec/pg/type_map_by_column_spec.rb +1 -1
  48. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  49. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  50. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  51. data/spec/pg/type_map_spec.rb +1 -1
  52. data/spec/pg/type_spec.rb +184 -12
  53. data/spec/pg_spec.rb +2 -2
  54. data.tar.gz.sig +0 -0
  55. metadata +47 -53
  56. metadata.gz.sig +0 -0
  57. data/sample/array_insert.rb +0 -20
  58. data/sample/async_api.rb +0 -106
  59. data/sample/async_copyto.rb +0 -39
  60. data/sample/async_mixed.rb +0 -56
  61. data/sample/check_conn.rb +0 -21
  62. data/sample/copyfrom.rb +0 -81
  63. data/sample/copyto.rb +0 -19
  64. data/sample/cursor.rb +0 -21
  65. data/sample/disk_usage_report.rb +0 -186
  66. data/sample/issue-119.rb +0 -94
  67. data/sample/losample.rb +0 -69
  68. data/sample/minimal-testcase.rb +0 -17
  69. data/sample/notify_wait.rb +0 -72
  70. data/sample/pg_statistics.rb +0 -294
  71. data/sample/replication_monitor.rb +0 -231
  72. data/sample/test_binary_values.rb +0 -33
  73. data/sample/wal_shipper.rb +0 -434
  74. data/sample/warehouse_partitions.rb +0 -320
data/ext/errorcodes.txt CHANGED
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2016, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2017, 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
@@ -15,6 +15,9 @@
15
15
  # src/pl/plpgsql/src/plerrcodes.h
16
16
  # a list of PL/pgSQL condition names and their SQLSTATE codes
17
17
  #
18
+ # src/pl/tcl/pltclerrcodes.h
19
+ # the same, for PL/Tcl
20
+ #
18
21
  # doc/src/sgml/errcodes-list.sgml
19
22
  # a SGML table of error codes for inclusion in the documentation
20
23
  #
@@ -185,6 +188,7 @@ Section: Class 22 - Data Exception
185
188
  22004 E ERRCODE_NULL_VALUE_NOT_ALLOWED null_value_not_allowed
186
189
  22002 E ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER null_value_no_indicator_parameter
187
190
  22003 E ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE numeric_value_out_of_range
191
+ 2200H E ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED sequence_generator_limit_exceeded
188
192
  22026 E ERRCODE_STRING_DATA_LENGTH_MISMATCH string_data_length_mismatch
189
193
  22001 E ERRCODE_STRING_DATA_RIGHT_TRUNCATION string_data_right_truncation
190
194
  22011 E ERRCODE_SUBSTRING_ERROR substring_error
@@ -229,6 +233,7 @@ Section: Class 25 - Invalid Transaction State
229
233
  25007 E ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED schema_and_data_statement_mixing_not_supported
230
234
  25P01 E ERRCODE_NO_ACTIVE_SQL_TRANSACTION no_active_sql_transaction
231
235
  25P02 E ERRCODE_IN_FAILED_SQL_TRANSACTION in_failed_sql_transaction
236
+ 25P03 E ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT idle_in_transaction_session_timeout
232
237
 
233
238
  Section: Class 26 - Invalid SQL Statement Name
234
239
 
@@ -322,6 +327,7 @@ Section: Class 42 - Syntax Error or Access Rule Violation
322
327
  42P21 E ERRCODE_COLLATION_MISMATCH collation_mismatch
323
328
  42P22 E ERRCODE_INDETERMINATE_COLLATION indeterminate_collation
324
329
  42809 E ERRCODE_WRONG_OBJECT_TYPE wrong_object_type
330
+ 428C9 E ERRCODE_GENERATED_ALWAYS generated_always
325
331
 
326
332
  # Note: for ERRCODE purposes, we divide namable objects into these categories:
327
333
  # databases, schemas, prepared statements, cursors, tables, columns,
@@ -413,6 +419,10 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
413
419
  58P01 E ERRCODE_UNDEFINED_FILE undefined_file
414
420
  58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
415
421
 
422
+ Section: Class 72 - Snapshot Failure
423
+ # (class borrowed from Oracle)
424
+ 72000 E ERRCODE_SNAPSHOT_TOO_OLD snapshot_too_old
425
+
416
426
  Section: Class F0 - Configuration File Error
417
427
 
418
428
  # (PostgreSQL-specific error class)
data/ext/extconf.rb CHANGED
@@ -60,48 +60,30 @@ abort "Can't find the PostgreSQL client library (libpq)" unless
60
60
  have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
61
61
  have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
62
62
 
63
+ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
64
+ # Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
65
+ checking_for "workaround gcc version with link issue" do
66
+ `#{RbConfig::MAKEFILE_CONFIG['CC']} --version`.chomp =~ /\s(\d+)\.\d+\.\d+(\s|$)/ &&
67
+ $1.to_i >= 6 &&
68
+ have_library(':libpq.lib') # Prefer linking to libpq.lib over libpq.dll if available
69
+ end
70
+ end
71
+
63
72
  # optional headers/functions
64
- have_func 'PQconnectionUsedPassword' or
73
+ have_func 'PQsetSingleRowMode' or
65
74
  abort "Your PostgreSQL is too old. Either install an older version " +
66
- "of this gem or upgrade your database."
67
- have_func 'PQisthreadsafe'
68
- have_func 'PQprepare'
69
- have_func 'PQexecParams'
70
- have_func 'PQescapeString'
71
- have_func 'PQescapeStringConn'
72
- have_func 'PQescapeLiteral'
73
- have_func 'PQescapeIdentifier'
74
- have_func 'PQgetCancel'
75
- have_func 'lo_create'
76
- have_func 'pg_encoding_to_char'
77
- have_func 'pg_char_to_encoding'
78
- have_func 'PQsetClientEncoding'
79
- have_func 'PQlibVersion'
80
- have_func 'PQping'
81
- have_func 'PQsetSingleRowMode'
75
+ "of this gem or upgrade your database to at least PostgreSQL-9.2."
82
76
  have_func 'PQconninfo'
83
77
  have_func 'PQsslAttribute'
78
+ have_func 'PQencryptPasswordConn'
79
+ have_func 'timegm'
80
+ have_func 'rb_gc_adjust_memory_usage'
84
81
 
85
- have_func 'rb_encdb_alias'
86
- have_func 'rb_enc_alias'
87
- have_func 'rb_thread_call_without_gvl'
88
- have_func 'rb_thread_call_with_gvl'
89
- have_func 'rb_thread_fd_select'
90
- have_func 'rb_w32_wrap_io_handle'
91
- have_func 'rb_str_modify_expand'
92
- have_func 'rb_hash_dup'
93
-
94
- have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
95
- have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
96
82
  have_const 'PG_DIAG_TABLE_NAME', 'libpq-fe.h'
97
83
 
98
- $defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
99
- have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
100
-
101
84
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
102
85
  have_header 'unistd.h'
103
86
  have_header 'inttypes.h'
104
- have_header 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h header"
105
87
 
106
88
  checking_for "C99 variable length arrays" do
107
89
  $defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
data/ext/gvl_wrappers.c CHANGED
@@ -5,6 +5,10 @@
5
5
 
6
6
  #include "pg.h"
7
7
 
8
+ #ifndef HAVE_PQENCRYPTPASSWORDCONN
9
+ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm){return NULL;}
10
+ #endif
11
+
8
12
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
9
13
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
10
14
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
data/ext/gvl_wrappers.h CHANGED
@@ -15,14 +15,7 @@
15
15
  #ifndef __gvl_wrappers_h
16
16
  #define __gvl_wrappers_h
17
17
 
18
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
19
- extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
20
- #endif
21
-
22
- #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
23
- extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
24
- rb_unblock_function_t *ubf, void *data2);
25
- #endif
18
+ #include <ruby/thread.h>
26
19
 
27
20
  #define DEFINE_PARAM_LIST1(type, name) \
28
21
  name,
@@ -53,21 +46,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
53
46
  return NULL; \
54
47
  }
55
48
 
56
- #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
57
- #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
58
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
59
- struct gvl_wrapper_##name##_params params = { \
60
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
61
- }; \
62
- rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
63
- when_non_void( return params.retval; ) \
64
- }
65
- #else
66
- #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
67
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
68
- return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
69
- }
70
- #endif
49
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
50
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
51
+ struct gvl_wrapper_##name##_params params = { \
52
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
53
+ }; \
54
+ rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
55
+ when_non_void( return params.retval; ) \
56
+ }
71
57
 
72
58
  #define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
73
59
  rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
@@ -80,21 +66,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
80
66
  return NULL; \
81
67
  }
82
68
 
83
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
84
- #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
85
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
86
- struct gvl_wrapper_##name##_params params = { \
87
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
88
- }; \
89
- rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
90
- when_non_void( return params.retval; ) \
91
- }
92
- #else
93
- #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
94
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
95
- return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
96
- }
97
- #endif
69
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
70
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
71
+ struct gvl_wrapper_##name##_params params = { \
72
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
73
+ }; \
74
+ rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
75
+ when_non_void( return params.retval; ) \
76
+ }
98
77
 
99
78
  #define GVL_TYPE_VOID(string)
100
79
  #define GVL_TYPE_NONVOID(string) string
@@ -200,6 +179,11 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
200
179
 
201
180
  #define FOR_EACH_PARAM_OF_PQisBusy(param)
202
181
 
182
+ #define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
183
+ param(PGconn *, conn) \
184
+ param(const char *, passwd) \
185
+ param(const char *, user)
186
+
203
187
  #define FOR_EACH_PARAM_OF_PQcancel(param) \
204
188
  param(PGcancel *, cancel) \
205
189
  param(char *, errbuf)
@@ -231,9 +215,9 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
231
215
  function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
232
216
  function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
233
217
  function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
218
+ function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
234
219
  function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
235
220
 
236
-
237
221
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
238
222
 
239
223
 
data/ext/pg.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg.c - Toplevel extension
3
- * $Id: pg.c,v c77d0997b4e4 2016/08/20 17:30:03 ged $
3
+ * $Id: pg.c,v 0d4acc8a0bc5 2018/08/05 09:07:58 lars $
4
4
  *
5
5
  * Author/s:
6
6
  *
@@ -48,6 +48,7 @@
48
48
 
49
49
  #include "pg.h"
50
50
 
51
+ int pg_skip_deprecation_warning;
51
52
  VALUE rb_mPG;
52
53
  VALUE rb_mPGconstants;
53
54
 
@@ -69,7 +70,6 @@ VALUE rb_mPGconstants;
69
70
  * M17n functions
70
71
  */
71
72
 
72
- #ifdef M17N_SUPPORTED
73
73
  /**
74
74
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
75
75
  */
@@ -144,7 +144,7 @@ pg_find_or_create_johab(void)
144
144
 
145
145
  enc_index = rb_define_dummy_encoding(aliases[0]);
146
146
  for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
147
- ENC_ALIAS(aliases[i], aliases[0]);
147
+ rb_enc_alias(aliases[i], aliases[0]);
148
148
  }
149
149
  return rb_enc_from_index(enc_index);
150
150
  }
@@ -229,8 +229,6 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
229
229
  return encname;
230
230
  }
231
231
 
232
- #endif /* M17N_SUPPORTED */
233
-
234
232
 
235
233
  /*
236
234
  * Ensures that the given string has enough capacity to take expand_len
@@ -260,45 +258,26 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
260
258
  * rb_str_set_len( string, current_out - RSTRING_PTR(string) );
261
259
  *
262
260
  */
263
- #ifdef HAVE_RB_STR_MODIFY_EXPAND
264
- /* Use somewhat faster version with access to string capacity on MRI */
265
- char *
266
- pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
267
- {
268
- long curr_len = curr_ptr - RSTRING_PTR(str);
269
- long curr_capa = rb_str_capacity( str );
270
- if( curr_capa < curr_len + expand_len ){
271
- rb_str_set_len( str, curr_len );
272
- rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
273
- curr_ptr = RSTRING_PTR(str) + curr_len;
274
- }
275
- if( end_ptr )
276
- *end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
277
- return curr_ptr;
278
- }
279
- #else
280
- /* Use the more portable version */
281
- char *
282
- pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
283
- {
284
- long curr_len = curr_ptr - RSTRING_PTR(str);
285
- long curr_capa = RSTRING_LEN( str );
286
- if( curr_capa < curr_len + expand_len ){
287
- rb_str_resize( str, (curr_len + expand_len) * 2 - curr_capa );
288
- curr_ptr = RSTRING_PTR(str) + curr_len;
289
- }
290
- if( end_ptr )
291
- *end_ptr = RSTRING_PTR(str) + RSTRING_LEN(str);
292
- return curr_ptr;
261
+ char *
262
+ pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
263
+ {
264
+ long curr_len = curr_ptr - RSTRING_PTR(str);
265
+ long curr_capa = rb_str_capacity( str );
266
+ if( curr_capa < curr_len + expand_len ){
267
+ rb_str_set_len( str, curr_len );
268
+ rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
269
+ curr_ptr = RSTRING_PTR(str) + curr_len;
293
270
  }
294
- #endif
271
+ if( end_ptr )
272
+ *end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
273
+ return curr_ptr;
274
+ }
295
275
 
296
276
 
297
277
  /**************************************************************************
298
278
  * Module Methods
299
279
  **************************************************************************/
300
280
 
301
- #ifdef HAVE_PQLIBVERSION
302
281
  /*
303
282
  * call-seq:
304
283
  * PG.library_version -> Integer
@@ -316,7 +295,6 @@ pg_s_library_version(VALUE self)
316
295
  UNUSED( self );
317
296
  return INT2NUM(PQlibVersion());
318
297
  }
319
- #endif
320
298
 
321
299
 
322
300
  /*
@@ -404,15 +382,15 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
404
382
  void
405
383
  Init_pg_ext()
406
384
  {
385
+ pg_skip_deprecation_warning = RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']"));
386
+
407
387
  rb_mPG = rb_define_module( "PG" );
408
388
  rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
409
389
 
410
390
  /*************************
411
391
  * PG module methods
412
392
  *************************/
413
- #ifdef HAVE_PQLIBVERSION
414
393
  rb_define_singleton_method( rb_mPG, "library_version", pg_s_library_version, 0 );
415
- #endif
416
394
  rb_define_singleton_method( rb_mPG, "isthreadsafe", pg_s_threadsafe_p, 0 );
417
395
  SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
418
396
  SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
@@ -478,7 +456,6 @@ Init_pg_ext()
478
456
  /* Verbose error verbosity level (#set_error_verbosity) */
479
457
  rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
480
458
 
481
- #ifdef HAVE_PQPING
482
459
  /****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
483
460
 
484
461
  /* Server is accepting connections. */
@@ -489,7 +466,6 @@ Init_pg_ext()
489
466
  rb_define_const(rb_mPGconstants, "PQPING_NO_RESPONSE", INT2FIX(PQPING_NO_RESPONSE));
490
467
  /* Connection not attempted (bad params). */
491
468
  rb_define_const(rb_mPGconstants, "PQPING_NO_ATTEMPT", INT2FIX(PQPING_NO_ATTEMPT));
492
- #endif
493
469
 
494
470
  /****** PG::Connection CLASS CONSTANTS: Large Objects ******/
495
471
 
@@ -524,13 +500,9 @@ Init_pg_ext()
524
500
  /* #result_status constant: A fatal error occurred. */
525
501
  rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
526
502
  /* #result_status constant: Copy In/Out data transfer in progress. */
527
- #ifdef HAVE_CONST_PGRES_COPY_BOTH
528
503
  rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
529
- #endif
530
504
  /* #result_status constant: Single tuple from larger resultset. */
531
- #ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
532
505
  rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
533
- #endif
534
506
 
535
507
  /****** Result CONSTANTS: result error field codes ******/
536
508
 
@@ -642,9 +614,7 @@ Init_pg_ext()
642
614
  /* Add the constants to the toplevel namespace */
643
615
  rb_include_module( rb_mPG, rb_mPGconstants );
644
616
 
645
- #ifdef M17N_SUPPORTED
646
617
  enc_pg2ruby = st_init_numtable();
647
- #endif
648
618
 
649
619
  /* Initialize the main extension classes */
650
620
  init_pg_connection();
@@ -663,5 +633,6 @@ Init_pg_ext()
663
633
  init_pg_binary_encoder();
664
634
  init_pg_binary_decoder();
665
635
  init_pg_copycoder();
636
+ init_pg_tuple();
666
637
  }
667
638
 
data/ext/pg.h CHANGED
@@ -18,89 +18,21 @@
18
18
 
19
19
  /* Ruby headers */
20
20
  #include "ruby.h"
21
- #ifdef HAVE_RUBY_ST_H
22
- # include "ruby/st.h"
23
- #elif HAVE_ST_H
24
- # include "st.h"
25
- #endif
21
+ #include "ruby/st.h"
22
+ #include "ruby/encoding.h"
26
23
 
27
- #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
28
- # include "ruby/encoding.h"
29
- # define M17N_SUPPORTED
30
- # ifdef HAVE_RB_ENCDB_ALIAS
31
- extern int rb_encdb_alias(const char *, const char *);
32
- # define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
33
- # elif HAVE_RB_ENC_ALIAS
34
- extern int rb_enc_alias(const char *, const char *);
35
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
36
- # else
37
- extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */
38
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
39
- # endif
40
-
41
-
42
- # if !defined(ENCODING_SET_INLINED)
43
- /* Rubinius doesn't define ENCODING_SET_INLINED, so we fall back to the more
44
- * portable version.
45
- */
46
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
47
- do { \
48
- rb_enc_set_index((obj), (i)); \
49
- } while(0)
50
- # else
51
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
24
+ /* exported by ruby-1.9.3+ but not declared */
25
+ extern int rb_enc_alias(const char *, const char *);
26
+
27
+ #define PG_ENCODING_SET_NOCHECK(obj,i) \
52
28
  do { \
53
29
  if ((i) < ENCODING_INLINE_MAX) \
54
30
  ENCODING_SET_INLINED((obj), (i)); \
55
31
  else \
56
32
  rb_enc_set_index((obj), (i)); \
57
33
  } while(0)
58
- # endif
59
-
60
- #else
61
- # define PG_ENCODING_SET_NOCHECK(obj,i) /* nothing */
62
- #endif
63
34
 
64
- #if RUBY_VM != 1
65
- # define RUBY_18_COMPAT
66
- #endif
67
-
68
- #ifndef RARRAY_LEN
69
- # define RARRAY_LEN(x) RARRAY((x))->len
70
- #endif /* RARRAY_LEN */
71
-
72
- #ifndef RSTRING_LEN
73
- # define RSTRING_LEN(x) RSTRING((x))->len
74
- #endif /* RSTRING_LEN */
75
-
76
- #ifndef RSTRING_PTR
77
- # define RSTRING_PTR(x) RSTRING((x))->ptr
78
- #endif /* RSTRING_PTR */
79
-
80
- #ifndef StringValuePtr
81
- # define StringValuePtr(x) STR2CSTR(x)
82
- #endif /* StringValuePtr */
83
-
84
- #ifdef RUBY_18_COMPAT
85
- # define rb_io_stdio_file GetWriteFile
86
- # include "rubyio.h"
87
- #else
88
- # include "ruby/io.h"
89
- #endif
90
-
91
- #ifdef RUBINIUS
92
- /* Workaround for wrong FIXNUM_MAX definition */
93
- typedef intptr_t native_int;
94
- #endif
95
-
96
- #ifndef RETURN_SIZED_ENUMERATOR
97
- #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR((obj), (argc), (argv))
98
- #endif
99
-
100
- #ifndef HAVE_RB_HASH_DUP
101
- /* Rubinius doesn't define rb_hash_dup() */
102
- #define rb_hash_dup(tuple) rb_funcall((tuple), rb_intern("dup"), 0)
103
- #endif
35
+ #include "ruby/io.h"
104
36
 
105
37
  #ifndef timeradd
106
38
  #define timeradd(a, b, result) \
@@ -145,6 +77,10 @@ typedef long suseconds_t;
145
77
  #define PG_MAX_COLUMNS 4000
146
78
  #endif
147
79
 
80
+ #ifndef RARRAY_AREF
81
+ #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
82
+ #endif
83
+
148
84
  /* The data behind each PG::Connection object */
149
85
  typedef struct {
150
86
  PGconn *pgconn;
@@ -168,6 +104,11 @@ typedef struct {
168
104
  /* Kind of PG::Coder object for casting COPY rows to ruby values */
169
105
  VALUE decoder_for_get_copy_data;
170
106
 
107
+ /* The connection socket, used for rb_wait_for_single_fd() */
108
+ int socket;
109
+
110
+ /* enable/disable guessing size of PGresult's allocated memory */
111
+ int guess_result_memsize;
171
112
  } t_pg_connection;
172
113
 
173
114
  typedef struct pg_coder t_pg_coder;
@@ -198,9 +139,15 @@ typedef struct {
198
139
  */
199
140
  int nfields;
200
141
 
142
+ /* Size of PGresult as published to ruby memory management. */
143
+ ssize_t result_size;
144
+
201
145
  /* Prefilled tuple Hash with fnames[] as keys. */
202
146
  VALUE tuple_hash;
203
147
 
148
+ /* Hash with fnames[] to field number mapping. */
149
+ VALUE field_map;
150
+
204
151
  /* List of field names as frozen String objects.
205
152
  * Only valid if nfields != -1
206
153
  */
@@ -209,7 +156,7 @@ typedef struct {
209
156
 
210
157
 
211
158
  typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
212
- typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
159
+ typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, const char *, int, int, int, int);
213
160
  typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
214
161
  typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
215
162
  typedef int (* t_pg_fit_to_copy_get)(VALUE);
@@ -217,12 +164,23 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
217
164
  typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
218
165
  typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
219
166
 
167
+ #define PG_CODER_TIMESTAMP_DB_UTC 0x0
168
+ #define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
169
+ #define PG_CODER_TIMESTAMP_APP_UTC 0x0
170
+ #define PG_CODER_TIMESTAMP_APP_LOCAL 0x2
171
+ #define PG_CODER_FORMAT_ERROR_MASK 0xc
172
+ #define PG_CODER_FORMAT_ERROR_TO_RAISE 0x4
173
+ #define PG_CODER_FORMAT_ERROR_TO_STRING 0x8
174
+ #define PG_CODER_FORMAT_ERROR_TO_PARTIAL 0xc
175
+
220
176
  struct pg_coder {
221
177
  t_pg_coder_enc_func enc_func;
222
178
  t_pg_coder_dec_func dec_func;
223
179
  VALUE coder_obj;
224
180
  Oid oid;
225
181
  int format;
182
+ /* OR-ed values out of PG_CODER_* */
183
+ int flags;
226
184
  };
227
185
 
228
186
  typedef struct {
@@ -259,6 +217,7 @@ typedef struct {
259
217
  * Globals
260
218
  **************************************************************************/
261
219
 
220
+ extern int pg_skip_deprecation_warning;
262
221
  extern VALUE rb_mPG;
263
222
  extern VALUE rb_ePGerror;
264
223
  extern VALUE rb_eServerError;
@@ -321,9 +280,10 @@ void init_pg_text_encoder _(( void ));
321
280
  void init_pg_text_decoder _(( void ));
322
281
  void init_pg_binary_encoder _(( void ));
323
282
  void init_pg_binary_decoder _(( void ));
283
+ void init_pg_tuple _(( void ));
324
284
  VALUE lookup_error_class _(( const char * ));
325
- VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
326
- VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
285
+ VALUE pg_bin_dec_bytea _(( t_pg_coder*, const char *, int, int, int, int ));
286
+ VALUE pg_text_dec_string _(( t_pg_coder*, const char *, int, int, int, int ));
327
287
  int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
328
288
  int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
329
289
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
@@ -366,6 +326,7 @@ VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
366
326
  PGresult* pgresult_get _(( VALUE ));
367
327
  VALUE pg_result_check _(( VALUE ));
368
328
  VALUE pg_result_clear _(( VALUE ));
329
+ VALUE pg_tuple_new _(( VALUE, int ));
369
330
 
370
331
  /*
371
332
  * Fetch the data pointer for the result object
@@ -373,7 +334,7 @@ VALUE pg_result_clear _(( VALUE ));
373
334
  static inline t_pg_result *
374
335
  pgresult_get_this( VALUE self )
375
336
  {
376
- t_pg_result *this = DATA_PTR(self);
337
+ t_pg_result *this = RTYPEDDATA_DATA(self);
377
338
 
378
339
  if( this == NULL )
379
340
  rb_raise(rb_ePGerror, "result has been cleared");
@@ -382,14 +343,18 @@ pgresult_get_this( VALUE self )
382
343
  }
383
344
 
384
345
 
385
- #ifdef M17N_SUPPORTED
386
346
  rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
387
347
  rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
388
348
  const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
389
349
  rb_encoding *pg_conn_enc_get _(( PGconn * ));
390
- #endif /* M17N_SUPPORTED */
391
350
 
392
351
  void notice_receiver_proxy(void *arg, const PGresult *result);
393
352
  void notice_processor_proxy(void *arg, const char *message);
394
353
 
354
+ /* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set */
355
+ #define pg_deprecated(x) \
356
+ do { \
357
+ if( !pg_skip_deprecation_warning ) rb_warning x; \
358
+ } while(0);
359
+
395
360
  #endif /* end __pg_h */