pg 1.2.0-x64-mingw32 → 1.3.0.rc1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +36 -0
  4. data/.gems +6 -0
  5. data/.github/workflows/binary-gems.yml +80 -0
  6. data/.github/workflows/source-gem.yml +129 -0
  7. data/.gitignore +13 -0
  8. data/.hgsigs +34 -0
  9. data/.hgtags +41 -0
  10. data/.irbrc +23 -0
  11. data/.pryrc +23 -0
  12. data/.tm_properties +21 -0
  13. data/.travis.yml +49 -0
  14. data/Gemfile +14 -0
  15. data/History.rdoc +98 -7
  16. data/Manifest.txt +0 -1
  17. data/README.rdoc +9 -8
  18. data/Rakefile +31 -140
  19. data/Rakefile.cross +54 -56
  20. data/certs/ged.pem +24 -0
  21. data/ext/errorcodes.def +8 -0
  22. data/ext/errorcodes.txt +3 -1
  23. data/ext/extconf.rb +90 -19
  24. data/ext/gvl_wrappers.c +4 -0
  25. data/ext/gvl_wrappers.h +23 -0
  26. data/ext/pg.c +35 -1
  27. data/ext/pg.h +18 -0
  28. data/ext/pg_coder.c +90 -24
  29. data/ext/pg_connection.c +538 -279
  30. data/ext/pg_copy_coder.c +45 -15
  31. data/ext/pg_record_coder.c +38 -9
  32. data/ext/pg_result.c +70 -34
  33. data/ext/pg_text_decoder.c +1 -1
  34. data/ext/pg_text_encoder.c +6 -6
  35. data/ext/pg_tuple.c +47 -21
  36. data/ext/pg_type_map.c +41 -8
  37. data/ext/pg_type_map_all_strings.c +14 -1
  38. data/ext/pg_type_map_by_class.c +50 -21
  39. data/ext/pg_type_map_by_column.c +64 -28
  40. data/ext/pg_type_map_by_mri_type.c +47 -18
  41. data/ext/pg_type_map_by_oid.c +52 -23
  42. data/ext/pg_type_map_in_ruby.c +50 -19
  43. data/ext/pg_util.c +2 -2
  44. data/lib/2.5/pg_ext.so +0 -0
  45. data/lib/2.6/pg_ext.so +0 -0
  46. data/lib/2.7/pg_ext.so +0 -0
  47. data/lib/3.0/pg_ext.so +0 -0
  48. data/lib/pg/basic_type_map_based_on_result.rb +47 -0
  49. data/lib/pg/basic_type_map_for_queries.rb +193 -0
  50. data/lib/pg/basic_type_map_for_results.rb +81 -0
  51. data/lib/pg/basic_type_registry.rb +296 -0
  52. data/lib/pg/coder.rb +1 -1
  53. data/lib/pg/connection.rb +369 -56
  54. data/lib/pg/version.rb +4 -0
  55. data/lib/pg.rb +38 -24
  56. data/lib/x64-mingw32/libpq.dll +0 -0
  57. data/misc/openssl-pg-segfault.rb +31 -0
  58. data/misc/postgres/History.txt +9 -0
  59. data/misc/postgres/Manifest.txt +5 -0
  60. data/misc/postgres/README.txt +21 -0
  61. data/misc/postgres/Rakefile +21 -0
  62. data/misc/postgres/lib/postgres.rb +16 -0
  63. data/misc/ruby-pg/History.txt +9 -0
  64. data/misc/ruby-pg/Manifest.txt +5 -0
  65. data/misc/ruby-pg/README.txt +21 -0
  66. data/misc/ruby-pg/Rakefile +21 -0
  67. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  68. data/pg.gemspec +32 -0
  69. data/sample/array_insert.rb +20 -0
  70. data/sample/async_api.rb +106 -0
  71. data/sample/async_copyto.rb +39 -0
  72. data/sample/async_mixed.rb +56 -0
  73. data/sample/check_conn.rb +21 -0
  74. data/sample/copydata.rb +71 -0
  75. data/sample/copyfrom.rb +81 -0
  76. data/sample/copyto.rb +19 -0
  77. data/sample/cursor.rb +21 -0
  78. data/sample/disk_usage_report.rb +177 -0
  79. data/sample/issue-119.rb +94 -0
  80. data/sample/losample.rb +69 -0
  81. data/sample/minimal-testcase.rb +17 -0
  82. data/sample/notify_wait.rb +72 -0
  83. data/sample/pg_statistics.rb +285 -0
  84. data/sample/replication_monitor.rb +222 -0
  85. data/sample/test_binary_values.rb +33 -0
  86. data/sample/wal_shipper.rb +434 -0
  87. data/sample/warehouse_partitions.rb +311 -0
  88. data.tar.gz.sig +0 -0
  89. metadata +83 -232
  90. metadata.gz.sig +0 -0
  91. data/ChangeLog +0 -0
  92. data/lib/2.2/pg_ext.so +0 -0
  93. data/lib/2.3/pg_ext.so +0 -0
  94. data/lib/2.4/pg_ext.so +0 -0
  95. data/lib/libpq.dll +0 -0
  96. data/lib/pg/basic_type_mapping.rb +0 -522
  97. data/spec/data/expected_trace.out +0 -26
  98. data/spec/data/random_binary_data +0 -0
  99. data/spec/helpers.rb +0 -382
  100. data/spec/pg/basic_type_mapping_spec.rb +0 -645
  101. data/spec/pg/connection_spec.rb +0 -1911
  102. data/spec/pg/connection_sync_spec.rb +0 -41
  103. data/spec/pg/result_spec.rb +0 -681
  104. data/spec/pg/tuple_spec.rb +0 -333
  105. data/spec/pg/type_map_by_class_spec.rb +0 -138
  106. data/spec/pg/type_map_by_column_spec.rb +0 -226
  107. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  108. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  109. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  110. data/spec/pg/type_map_spec.rb +0 -22
  111. data/spec/pg/type_spec.rb +0 -1123
  112. data/spec/pg_spec.rb +0 -50
data/ext/pg_copy_coder.c CHANGED
@@ -21,17 +21,47 @@ typedef struct {
21
21
 
22
22
 
23
23
  static void
24
- pg_copycoder_mark( t_pg_copycoder *this )
24
+ pg_copycoder_mark( void *_this )
25
25
  {
26
- rb_gc_mark(this->typemap);
27
- rb_gc_mark(this->null_string);
26
+ t_pg_copycoder *this = (t_pg_copycoder *)_this;
27
+ rb_gc_mark_movable(this->typemap);
28
+ rb_gc_mark_movable(this->null_string);
28
29
  }
29
30
 
31
+ static size_t
32
+ pg_copycoder_memsize( const void *_this )
33
+ {
34
+ const t_pg_copycoder *this = (const t_pg_copycoder *)_this;
35
+ return sizeof(*this);
36
+ }
37
+
38
+ static void
39
+ pg_copycoder_compact( void *_this )
40
+ {
41
+ t_pg_copycoder *this = (t_pg_copycoder *)_this;
42
+ pg_coder_compact(&this->comp);
43
+ pg_gc_location(this->typemap);
44
+ pg_gc_location(this->null_string);
45
+ }
46
+
47
+ static const rb_data_type_t pg_copycoder_type = {
48
+ "PG::CopyCoder",
49
+ {
50
+ pg_copycoder_mark,
51
+ RUBY_TYPED_DEFAULT_FREE,
52
+ pg_copycoder_memsize,
53
+ pg_compact_callback(pg_copycoder_compact),
54
+ },
55
+ &pg_coder_type,
56
+ 0,
57
+ RUBY_TYPED_FREE_IMMEDIATELY,
58
+ };
59
+
30
60
  static VALUE
31
61
  pg_copycoder_encoder_allocate( VALUE klass )
32
62
  {
33
63
  t_pg_copycoder *this;
34
- VALUE self = Data_Make_Struct( klass, t_pg_copycoder, pg_copycoder_mark, -1, this );
64
+ VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
35
65
  pg_coder_init_encoder( self );
36
66
  this->typemap = pg_typemap_all_strings;
37
67
  this->delimiter = '\t';
@@ -43,7 +73,7 @@ static VALUE
43
73
  pg_copycoder_decoder_allocate( VALUE klass )
44
74
  {
45
75
  t_pg_copycoder *this;
46
- VALUE self = Data_Make_Struct( klass, t_pg_copycoder, pg_copycoder_mark, -1, this );
76
+ VALUE self = TypedData_Make_Struct( klass, t_pg_copycoder, &pg_copycoder_type, this );
47
77
  pg_coder_init_decoder( self );
48
78
  this->typemap = pg_typemap_all_strings;
49
79
  this->delimiter = '\t';
@@ -62,7 +92,7 @@ pg_copycoder_decoder_allocate( VALUE klass )
62
92
  static VALUE
63
93
  pg_copycoder_delimiter_set(VALUE self, VALUE delimiter)
64
94
  {
65
- t_pg_copycoder *this = DATA_PTR(self);
95
+ t_pg_copycoder *this = RTYPEDDATA_DATA(self);
66
96
  StringValue(delimiter);
67
97
  if(RSTRING_LEN(delimiter) != 1)
68
98
  rb_raise( rb_eArgError, "delimiter size must be one byte");
@@ -79,7 +109,7 @@ pg_copycoder_delimiter_set(VALUE self, VALUE delimiter)
79
109
  static VALUE
80
110
  pg_copycoder_delimiter_get(VALUE self)
81
111
  {
82
- t_pg_copycoder *this = DATA_PTR(self);
112
+ t_pg_copycoder *this = RTYPEDDATA_DATA(self);
83
113
  return rb_str_new(&this->delimiter, 1);
84
114
  }
85
115
 
@@ -92,7 +122,7 @@ pg_copycoder_delimiter_get(VALUE self)
92
122
  static VALUE
93
123
  pg_copycoder_null_string_set(VALUE self, VALUE null_string)
94
124
  {
95
- t_pg_copycoder *this = DATA_PTR(self);
125
+ t_pg_copycoder *this = RTYPEDDATA_DATA(self);
96
126
  StringValue(null_string);
97
127
  this->null_string = null_string;
98
128
  return null_string;
@@ -104,7 +134,7 @@ pg_copycoder_null_string_set(VALUE self, VALUE null_string)
104
134
  static VALUE
105
135
  pg_copycoder_null_string_get(VALUE self)
106
136
  {
107
- t_pg_copycoder *this = DATA_PTR(self);
137
+ t_pg_copycoder *this = RTYPEDDATA_DATA(self);
108
138
  return this->null_string;
109
139
  }
110
140
 
@@ -122,7 +152,7 @@ pg_copycoder_null_string_get(VALUE self)
122
152
  static VALUE
123
153
  pg_copycoder_type_map_set(VALUE self, VALUE type_map)
124
154
  {
125
- t_pg_copycoder *this = DATA_PTR( self );
155
+ t_pg_copycoder *this = RTYPEDDATA_DATA( self );
126
156
 
127
157
  if ( !rb_obj_is_kind_of(type_map, rb_cTypeMap) ){
128
158
  rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
@@ -142,7 +172,7 @@ pg_copycoder_type_map_set(VALUE self, VALUE type_map)
142
172
  static VALUE
143
173
  pg_copycoder_type_map_get(VALUE self)
144
174
  {
145
- t_pg_copycoder *this = DATA_PTR( self );
175
+ t_pg_copycoder *this = RTYPEDDATA_DATA( self );
146
176
 
147
177
  return this->typemap;
148
178
  }
@@ -187,7 +217,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
187
217
  char *current_out;
188
218
  char *end_capa_ptr;
189
219
 
190
- p_typemap = DATA_PTR( this->typemap );
220
+ p_typemap = RTYPEDDATA_DATA( this->typemap );
191
221
  p_typemap->funcs.fit_to_query( this->typemap, value );
192
222
 
193
223
  /* Allocate a new string with embedded capacity and realloc exponential when needed. */
@@ -224,7 +254,7 @@ pg_text_enc_copy_row(t_pg_coder *conv, VALUE value, char *out, VALUE *intermedia
224
254
 
225
255
  if( strlen == -1 ){
226
256
  /* we can directly use String value in subint */
227
- strlen = RSTRING_LEN(subint);
257
+ strlen = RSTRING_LENINT(subint);
228
258
 
229
259
  /* size of string assuming the worst case, that every character must be escaped. */
230
260
  PG_RB_STR_ENSURE_CAPA( *intermediate, strlen * 2, current_out, end_capa_ptr );
@@ -375,7 +405,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
375
405
  char *end_capa_ptr;
376
406
  t_typemap *p_typemap;
377
407
 
378
- p_typemap = DATA_PTR( this->typemap );
408
+ p_typemap = RTYPEDDATA_DATA( this->typemap );
379
409
  expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
380
410
 
381
411
  /* The received input string will probably have this->nfields fields. */
@@ -396,7 +426,7 @@ pg_text_dec_copy_row(t_pg_coder *conv, const char *input_line, int len, int _tup
396
426
  int found_delim = 0;
397
427
  const char *start_ptr;
398
428
  const char *end_ptr;
399
- int input_len;
429
+ long input_len;
400
430
 
401
431
  /* Remember start of field on input side */
402
432
  start_ptr = cur_ptr;
@@ -16,16 +16,45 @@ typedef struct {
16
16
 
17
17
 
18
18
  static void
19
- pg_recordcoder_mark( t_pg_recordcoder *this )
19
+ pg_recordcoder_mark( void *_this )
20
20
  {
21
- rb_gc_mark(this->typemap);
21
+ t_pg_recordcoder *this = (t_pg_recordcoder *)_this;
22
+ rb_gc_mark_movable(this->typemap);
22
23
  }
23
24
 
25
+ static size_t
26
+ pg_recordcoder_memsize( const void *_this )
27
+ {
28
+ const t_pg_recordcoder *this = (const t_pg_recordcoder *)_this;
29
+ return sizeof(*this);
30
+ }
31
+
32
+ static void
33
+ pg_recordcoder_compact( void *_this )
34
+ {
35
+ t_pg_recordcoder *this = (t_pg_recordcoder *)_this;
36
+ pg_coder_compact(&this->comp);
37
+ pg_gc_location(this->typemap);
38
+ }
39
+
40
+ static const rb_data_type_t pg_recordcoder_type = {
41
+ "PG::RecordCoder",
42
+ {
43
+ pg_recordcoder_mark,
44
+ RUBY_TYPED_DEFAULT_FREE,
45
+ pg_recordcoder_memsize,
46
+ pg_compact_callback(pg_recordcoder_compact),
47
+ },
48
+ &pg_coder_type,
49
+ 0,
50
+ RUBY_TYPED_FREE_IMMEDIATELY,
51
+ };
52
+
24
53
  static VALUE
25
54
  pg_recordcoder_encoder_allocate( VALUE klass )
26
55
  {
27
56
  t_pg_recordcoder *this;
28
- VALUE self = Data_Make_Struct( klass, t_pg_recordcoder, pg_recordcoder_mark, -1, this );
57
+ VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
29
58
  pg_coder_init_encoder( self );
30
59
  this->typemap = pg_typemap_all_strings;
31
60
  return self;
@@ -35,7 +64,7 @@ static VALUE
35
64
  pg_recordcoder_decoder_allocate( VALUE klass )
36
65
  {
37
66
  t_pg_recordcoder *this;
38
- VALUE self = Data_Make_Struct( klass, t_pg_recordcoder, pg_recordcoder_mark, -1, this );
67
+ VALUE self = TypedData_Make_Struct( klass, t_pg_recordcoder, &pg_recordcoder_type, this );
39
68
  pg_coder_init_decoder( self );
40
69
  this->typemap = pg_typemap_all_strings;
41
70
  return self;
@@ -55,7 +84,7 @@ pg_recordcoder_decoder_allocate( VALUE klass )
55
84
  static VALUE
56
85
  pg_recordcoder_type_map_set(VALUE self, VALUE type_map)
57
86
  {
58
- t_pg_recordcoder *this = DATA_PTR( self );
87
+ t_pg_recordcoder *this = RTYPEDDATA_DATA( self );
59
88
 
60
89
  if ( !rb_obj_is_kind_of(type_map, rb_cTypeMap) ){
61
90
  rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::TypeMap)",
@@ -75,7 +104,7 @@ pg_recordcoder_type_map_set(VALUE self, VALUE type_map)
75
104
  static VALUE
76
105
  pg_recordcoder_type_map_get(VALUE self)
77
106
  {
78
- t_pg_recordcoder *this = DATA_PTR( self );
107
+ t_pg_recordcoder *this = RTYPEDDATA_DATA( self );
79
108
 
80
109
  return this->typemap;
81
110
  }
@@ -155,7 +184,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
155
184
  char *current_out;
156
185
  char *end_capa_ptr;
157
186
 
158
- p_typemap = DATA_PTR( this->typemap );
187
+ p_typemap = RTYPEDDATA_DATA( this->typemap );
159
188
  p_typemap->funcs.fit_to_query( this->typemap, value );
160
189
 
161
190
  /* Allocate a new string with embedded capacity and realloc exponential when needed. */
@@ -167,7 +196,7 @@ pg_text_enc_record(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
167
196
  for( i=0; i<RARRAY_LEN(value); i++){
168
197
  char *ptr1;
169
198
  char *ptr2;
170
- int strlen;
199
+ long strlen;
171
200
  int backslashs;
172
201
  VALUE subint;
173
202
  VALUE entry;
@@ -357,7 +386,7 @@ pg_text_dec_record(t_pg_coder *conv, char *input_line, int len, int _tuple, int
357
386
  char *end_capa_ptr;
358
387
  t_typemap *p_typemap;
359
388
 
360
- p_typemap = DATA_PTR( this->typemap );
389
+ p_typemap = RTYPEDDATA_DATA( this->typemap );
361
390
  expected_fields = p_typemap->funcs.fit_to_copy_get( this->typemap );
362
391
 
363
392
  /* The received input string will probably have this->nfields fields. */
data/ext/pg_result.c CHANGED
@@ -107,17 +107,34 @@ pgresult_approx_size(const PGresult *result)
107
107
  * GC Mark function
108
108
  */
109
109
  static void
110
- pgresult_gc_mark( t_pg_result *this )
110
+ pgresult_gc_mark( void *_this )
111
111
  {
112
+ t_pg_result *this = (t_pg_result *)_this;
112
113
  int i;
113
114
 
114
- rb_gc_mark( this->connection );
115
- rb_gc_mark( this->typemap );
116
- rb_gc_mark( this->tuple_hash );
117
- rb_gc_mark( this->field_map );
115
+ rb_gc_mark_movable( this->connection );
116
+ rb_gc_mark_movable( this->typemap );
117
+ rb_gc_mark_movable( this->tuple_hash );
118
+ rb_gc_mark_movable( this->field_map );
118
119
 
119
120
  for( i=0; i < this->nfields; i++ ){
120
- rb_gc_mark( this->fnames[i] );
121
+ rb_gc_mark_movable( this->fnames[i] );
122
+ }
123
+ }
124
+
125
+ static void
126
+ pgresult_gc_compact( void *_this )
127
+ {
128
+ t_pg_result *this = (t_pg_result *)_this;
129
+ int i;
130
+
131
+ pg_gc_location( this->connection );
132
+ pg_gc_location( this->typemap );
133
+ pg_gc_location( this->tuple_hash );
134
+ pg_gc_location( this->field_map );
135
+
136
+ for( i=0; i < this->nfields; i++ ){
137
+ pg_gc_location( this->fnames[i] );
121
138
  }
122
139
  }
123
140
 
@@ -125,8 +142,9 @@ pgresult_gc_mark( t_pg_result *this )
125
142
  * GC Free function
126
143
  */
127
144
  static void
128
- pgresult_clear( t_pg_result *this )
145
+ pgresult_clear( void *_this )
129
146
  {
147
+ t_pg_result *this = (t_pg_result *)_this;
130
148
  if( this->pgresult && !this->autoclear ){
131
149
  PQclear(this->pgresult);
132
150
  #ifdef HAVE_RB_GC_ADJUST_MEMORY_USAGE
@@ -139,15 +157,17 @@ pgresult_clear( t_pg_result *this )
139
157
  }
140
158
 
141
159
  static void
142
- pgresult_gc_free( t_pg_result *this )
160
+ pgresult_gc_free( void *_this )
143
161
  {
162
+ t_pg_result *this = (t_pg_result *)_this;
144
163
  pgresult_clear( this );
145
164
  xfree(this);
146
165
  }
147
166
 
148
167
  static size_t
149
- pgresult_memsize( t_pg_result *this )
168
+ pgresult_memsize( const void *_this )
150
169
  {
170
+ const t_pg_result *this = (const t_pg_result *)_this;
151
171
  /* Ideally the memory 'this' is pointing to should be taken into account as well.
152
172
  * However we don't want to store two memory sizes in t_pg_result just for reporting by ObjectSpace.memsize_of.
153
173
  */
@@ -155,18 +175,22 @@ pgresult_memsize( t_pg_result *this )
155
175
  }
156
176
 
157
177
  static const rb_data_type_t pgresult_type = {
158
- "pg",
178
+ "PG::Result",
159
179
  {
160
- (void (*)(void*))pgresult_gc_mark,
161
- (void (*)(void*))pgresult_gc_free,
162
- (size_t (*)(const void *))pgresult_memsize,
180
+ pgresult_gc_mark,
181
+ pgresult_gc_free,
182
+ pgresult_memsize,
183
+ pg_compact_callback(pgresult_gc_compact),
163
184
  },
164
185
  0, 0,
165
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
166
186
  RUBY_TYPED_FREE_IMMEDIATELY,
167
- #endif
168
187
  };
169
188
 
189
+ /* Needed by sequel_pg gem, do not delete */
190
+ int pg_get_result_enc_idx(VALUE self)
191
+ {
192
+ return pgresult_get_this(self)->enc_idx;
193
+ }
170
194
 
171
195
  /*
172
196
  * Global functions
@@ -186,7 +210,7 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
186
210
  this->pgresult = result;
187
211
  this->connection = rb_pgconn;
188
212
  this->typemap = pg_typemap_all_strings;
189
- this->p_typemap = DATA_PTR( this->typemap );
213
+ this->p_typemap = RTYPEDDATA_DATA( this->typemap );
190
214
  this->nfields = -1;
191
215
  this->tuple_hash = Qnil;
192
216
  this->field_map = Qnil;
@@ -197,11 +221,11 @@ pg_new_result2(PGresult *result, VALUE rb_pgconn)
197
221
  t_pg_connection *p_conn = pg_get_connection(rb_pgconn);
198
222
  VALUE typemap = p_conn->type_map_for_results;
199
223
  /* Type check is done when assigned to PG::Connection. */
200
- t_typemap *p_typemap = DATA_PTR(typemap);
224
+ t_typemap *p_typemap = RTYPEDDATA_DATA(typemap);
201
225
 
202
226
  this->enc_idx = p_conn->enc_idx;
203
227
  this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
204
- this->p_typemap = DATA_PTR( this->typemap );
228
+ this->p_typemap = RTYPEDDATA_DATA( this->typemap );
205
229
  this->flags = p_conn->flags;
206
230
  } else {
207
231
  this->enc_idx = rb_locale_encindex();
@@ -265,7 +289,11 @@ pg_new_result_autoclear(PGresult *result, VALUE rb_pgconn)
265
289
  * call-seq:
266
290
  * res.check -> nil
267
291
  *
268
- * Raises appropriate exception if PG::Result is in a bad state.
292
+ * Raises appropriate exception if PG::Result is in a bad state, which is:
293
+ * * +PGRES_BAD_RESPONSE+
294
+ * * +PGRES_FATAL_ERROR+
295
+ * * +PGRES_NONFATAL_ERROR+
296
+ * * +PGRES_PIPELINE_ABORTED+
269
297
  */
270
298
  VALUE
271
299
  pg_result_check( VALUE self )
@@ -290,10 +318,16 @@ pg_result_check( VALUE self )
290
318
  case PGRES_SINGLE_TUPLE:
291
319
  case PGRES_EMPTY_QUERY:
292
320
  case PGRES_COMMAND_OK:
321
+ #ifdef HAVE_PQENTERPIPELINEMODE
322
+ case PGRES_PIPELINE_SYNC:
323
+ #endif
293
324
  return self;
294
325
  case PGRES_BAD_RESPONSE:
295
326
  case PGRES_FATAL_ERROR:
296
327
  case PGRES_NONFATAL_ERROR:
328
+ #ifdef HAVE_PQENTERPIPELINEMODE
329
+ case PGRES_PIPELINE_ABORTED:
330
+ #endif
297
331
  error = rb_str_new2( PQresultErrorMessage(this->pgresult) );
298
332
  break;
299
333
  default:
@@ -333,8 +367,7 @@ pg_result_check( VALUE self )
333
367
  * Special care must be taken when PG::Tuple objects are used.
334
368
  * In this case #clear must not be called unless all PG::Tuple objects of this result are fully materialized.
335
369
  *
336
- * If PG::Result#autoclear? is true then the result is marked as cleared
337
- * and the underlying C struct will be cleared automatically by libpq.
370
+ * If PG::Result#autoclear? is +true+ then the result is only marked as cleared but clearing the underlying C struct will happen when the callback returns.
338
371
  *
339
372
  */
340
373
  VALUE
@@ -349,7 +382,7 @@ pg_result_clear(VALUE self)
349
382
  * call-seq:
350
383
  * res.cleared? -> boolean
351
384
  *
352
- * Returns +true+ if the backend result memory has been free'd.
385
+ * Returns +true+ if the backend result memory has been freed.
353
386
  */
354
387
  VALUE
355
388
  pgresult_cleared_p( VALUE self )
@@ -362,8 +395,10 @@ pgresult_cleared_p( VALUE self )
362
395
  * call-seq:
363
396
  * res.autoclear? -> boolean
364
397
  *
365
- * Returns +true+ if the underlying C struct will be cleared automatically by libpq.
366
- * Elsewise the result is cleared by PG::Result#clear or by the GC when it's no longer in use.
398
+ * Returns +true+ if the underlying C struct will be cleared at the end of a callback.
399
+ * This applies only to Result objects received by the block to PG::Connection#set_notice_receiver .
400
+ *
401
+ * All other Result objects are automatically cleared by the GC when the object is no longer in use or manually by PG::Result#clear .
367
402
  *
368
403
  */
369
404
  VALUE
@@ -489,6 +524,9 @@ static void pgresult_init_fnames(VALUE self)
489
524
  * * +PGRES_NONFATAL_ERROR+
490
525
  * * +PGRES_FATAL_ERROR+
491
526
  * * +PGRES_COPY_BOTH+
527
+ * * +PGRES_SINGLE_TUPLE+
528
+ * * +PGRES_PIPELINE_SYNC+
529
+ * * +PGRES_PIPELINE_ABORTED+
492
530
  */
493
531
  static VALUE
494
532
  pgresult_result_status(VALUE self)
@@ -500,7 +538,7 @@ pgresult_result_status(VALUE self)
500
538
  * call-seq:
501
539
  * res.res_status( status ) -> String
502
540
  *
503
- * Returns the string representation of status +status+.
541
+ * Returns the string representation of +status+.
504
542
  *
505
543
  */
506
544
  static VALUE
@@ -997,7 +1035,7 @@ pgresult_cmd_tuples(VALUE self)
997
1035
  {
998
1036
  long n;
999
1037
  n = strtol(PQcmdTuples(pgresult_get(self)),NULL, 10);
1000
- return INT2NUM(n);
1038
+ return LONG2NUM(n);
1001
1039
  }
1002
1040
 
1003
1041
  /*
@@ -1319,14 +1357,11 @@ pgresult_type_map_set(VALUE self, VALUE typemap)
1319
1357
  t_pg_result *this = pgresult_get_this(self);
1320
1358
  t_typemap *p_typemap;
1321
1359
 
1322
- if ( !rb_obj_is_kind_of(typemap, rb_cTypeMap) ) {
1323
- rb_raise( rb_eTypeError, "wrong argument type %s (expected kind of PG::TypeMap)",
1324
- rb_obj_classname( typemap ) );
1325
- }
1326
- Data_Get_Struct(typemap, t_typemap, p_typemap);
1360
+ /* Check type of method param */
1361
+ TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, p_typemap);
1327
1362
 
1328
1363
  this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
1329
- this->p_typemap = DATA_PTR( this->typemap );
1364
+ this->p_typemap = RTYPEDDATA_DATA( this->typemap );
1330
1365
 
1331
1366
  return typemap;
1332
1367
  }
@@ -1525,7 +1560,7 @@ pgresult_stream_each_tuple(VALUE self)
1525
1560
  * It can be set to one of:
1526
1561
  * * +:string+ to use String based field names
1527
1562
  * * +:symbol+ to use Symbol based field names
1528
- * * +:static_symbol+ to use pinned Symbol (can not be garbage collected) - Don't use this, it will probably removed in future.
1563
+ * * +:static_symbol+ to use pinned Symbol (can not be garbage collected) - Don't use this, it will probably be removed in future.
1529
1564
  *
1530
1565
  * The default is retrieved from PG::Connection#field_name_type , which defaults to +:string+ .
1531
1566
  *
@@ -1581,7 +1616,8 @@ init_pg_result()
1581
1616
  sym_symbol = ID2SYM(rb_intern("symbol"));
1582
1617
  sym_static_symbol = ID2SYM(rb_intern("static_symbol"));
1583
1618
 
1584
- rb_cPGresult = rb_define_class_under( rb_mPG, "Result", rb_cData );
1619
+ rb_cPGresult = rb_define_class_under( rb_mPG, "Result", rb_cObject );
1620
+ rb_undef_alloc_func(rb_cPGresult);
1585
1621
  rb_include_module(rb_cPGresult, rb_mEnumerable);
1586
1622
  rb_include_module(rb_cPGresult, rb_mPGconstants);
1587
1623
 
@@ -854,7 +854,7 @@ pg_text_dec_inet(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
854
854
 
855
855
  ip_int_native = read_nbo32(dst);
856
856
 
857
- /* Work around broken IPAddr behavior of convering portion
857
+ /* Work around broken IPAddr behavior of converting portion
858
858
  of address after netmask to 0 */
859
859
  switch (mask) {
860
860
  case 0:
@@ -191,7 +191,7 @@ pg_text_enc_integer(t_pg_coder *this, VALUE value, char *out, VALUE *intermediat
191
191
  if (neg)
192
192
  *out++ = '-';
193
193
 
194
- len = out - start;
194
+ len = (int)(out - start);
195
195
 
196
196
  /* Reverse string. */
197
197
  out--;
@@ -252,7 +252,7 @@ pg_text_enc_float(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
252
252
  }
253
253
 
254
254
  /*
255
- * The following computaion is roughly a conversion kind of
255
+ * The following computation is roughly a conversion kind of
256
256
  * sprintf( out, "%.16E", dvalue);
257
257
  */
258
258
 
@@ -403,11 +403,11 @@ pg_text_enc_bytea(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate,
403
403
  *optr++ = hextab[c >> 4];
404
404
  *optr++ = hextab[c & 0xf];
405
405
  }
406
- return optr - out;
406
+ return (int)(optr - out);
407
407
  }else{
408
408
  *intermediate = rb_obj_as_string(value);
409
409
  /* The output starts with "\x" and each character is converted to hex. */
410
- return 2 + RSTRING_LEN(*intermediate) * 2;
410
+ return 2 + RSTRING_LENINT(*intermediate) * 2;
411
411
  }
412
412
  }
413
413
 
@@ -610,8 +610,8 @@ quote_identifier( VALUE value, VALUE out_string, char *current_out ){
610
610
  static char *
611
611
  pg_text_enc_array_identifier(VALUE value, VALUE string, char *out, int enc_idx)
612
612
  {
613
- int i;
614
- int nr_elems;
613
+ long i;
614
+ long nr_elems;
615
615
 
616
616
  Check_Type(value, T_ARRAY);
617
617
  nr_elems = RARRAY_LEN(value);
data/ext/pg_tuple.c CHANGED
@@ -52,57 +52,83 @@ typedef struct {
52
52
  VALUE values[0];
53
53
  } t_pg_tuple;
54
54
 
55
- static inline VALUE
56
- pg_tuple_get_field_names( t_pg_tuple *this )
55
+ static inline VALUE *
56
+ pg_tuple_get_field_names_ptr( t_pg_tuple *this )
57
57
  {
58
58
  if( this->num_fields != (int)RHASH_SIZE(this->field_map) ){
59
- return this->values[this->num_fields];
59
+ return &this->values[this->num_fields];
60
60
  } else {
61
- return Qfalse;
61
+ static VALUE f = Qfalse;
62
+ return &f;
63
+ }
64
+ }
65
+
66
+ static inline VALUE
67
+ pg_tuple_get_field_names( t_pg_tuple *this )
68
+ {
69
+ return *pg_tuple_get_field_names_ptr(this);
70
+ }
71
+
72
+ static void
73
+ pg_tuple_gc_mark( void *_this )
74
+ {
75
+ t_pg_tuple *this = (t_pg_tuple *)_this;
76
+ int i;
77
+
78
+ if( !this ) return;
79
+ rb_gc_mark_movable( this->result );
80
+ rb_gc_mark_movable( this->typemap );
81
+ rb_gc_mark_movable( this->field_map );
82
+
83
+ for( i = 0; i < this->num_fields; i++ ){
84
+ rb_gc_mark_movable( this->values[i] );
62
85
  }
86
+ rb_gc_mark_movable( pg_tuple_get_field_names(this) );
63
87
  }
64
88
 
65
89
  static void
66
- pg_tuple_gc_mark( t_pg_tuple *this )
90
+ pg_tuple_gc_compact( void *_this )
67
91
  {
92
+ t_pg_tuple *this = (t_pg_tuple *)_this;
68
93
  int i;
69
94
 
70
95
  if( !this ) return;
71
- rb_gc_mark( this->result );
72
- rb_gc_mark( this->typemap );
73
- rb_gc_mark( this->field_map );
96
+ pg_gc_location( this->result );
97
+ pg_gc_location( this->typemap );
98
+ pg_gc_location( this->field_map );
74
99
 
75
100
  for( i = 0; i < this->num_fields; i++ ){
76
- rb_gc_mark( this->values[i] );
101
+ pg_gc_location( this->values[i] );
77
102
  }
78
- rb_gc_mark( pg_tuple_get_field_names(this) );
103
+ pg_gc_location( *pg_tuple_get_field_names_ptr(this) );
79
104
  }
80
105
 
81
106
  static void
82
- pg_tuple_gc_free( t_pg_tuple *this )
107
+ pg_tuple_gc_free( void *_this )
83
108
  {
109
+ t_pg_tuple *this = (t_pg_tuple *)_this;
84
110
  if( !this ) return;
85
111
  xfree(this);
86
112
  }
87
113
 
88
114
  static size_t
89
- pg_tuple_memsize( t_pg_tuple *this )
115
+ pg_tuple_memsize( const void *_this )
90
116
  {
117
+ const t_pg_tuple *this = (const t_pg_tuple *)_this;
91
118
  if( this==NULL ) return 0;
92
119
  return sizeof(*this) + sizeof(*this->values) * this->num_fields;
93
120
  }
94
121
 
95
122
  static const rb_data_type_t pg_tuple_type = {
96
- "pg",
123
+ "PG::Tuple",
97
124
  {
98
- (void (*)(void*))pg_tuple_gc_mark,
99
- (void (*)(void*))pg_tuple_gc_free,
100
- (size_t (*)(const void *))pg_tuple_memsize,
125
+ pg_tuple_gc_mark,
126
+ pg_tuple_gc_free,
127
+ pg_tuple_memsize,
128
+ pg_compact_callback(pg_tuple_gc_compact),
101
129
  },
102
130
  0, 0,
103
- #ifdef RUBY_TYPED_FREE_IMMEDIATELY
104
131
  RUBY_TYPED_FREE_IMMEDIATELY,
105
- #endif
106
132
  };
107
133
 
108
134
  /*
@@ -172,7 +198,7 @@ pg_tuple_materialize_field(t_pg_tuple *this, int col)
172
198
  VALUE value = this->values[col];
173
199
 
174
200
  if( value == Qundef ){
175
- t_typemap *p_typemap = DATA_PTR( this->typemap );
201
+ t_typemap *p_typemap = RTYPEDDATA_DATA( this->typemap );
176
202
 
177
203
  pgresult_get(this->result); /* make sure we have a valid PGresult object */
178
204
  value = p_typemap->funcs.typecast_result_value(p_typemap, this->result, this->row_num, col);
@@ -479,9 +505,9 @@ pg_tuple_load(VALUE self, VALUE a)
479
505
  rb_obj_freeze(field_names);
480
506
  values = RARRAY_AREF(a, 1);
481
507
  Check_Type(values, T_ARRAY);
482
- num_fields = RARRAY_LEN(values);
508
+ num_fields = RARRAY_LENINT(values);
483
509
 
484
- if (RARRAY_LEN(field_names) != num_fields)
510
+ if (RARRAY_LENINT(field_names) != num_fields)
485
511
  rb_raise(rb_eTypeError, "different number of fields and values");
486
512
 
487
513
  field_map = rb_hash_new();