pg 1.1.3 → 1.3.3

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 (117) 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 +86 -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 +210 -6
  16. data/Manifest.txt +3 -3
  17. data/README-Windows.rdoc +4 -4
  18. data/README.ja.rdoc +1 -2
  19. data/README.rdoc +51 -15
  20. data/Rakefile +31 -140
  21. data/Rakefile.cross +60 -56
  22. data/certs/ged.pem +24 -0
  23. data/certs/larskanis-2022.pem +26 -0
  24. data/ext/errorcodes.def +76 -0
  25. data/ext/errorcodes.txt +21 -2
  26. data/ext/extconf.rb +101 -26
  27. data/ext/gvl_wrappers.c +4 -0
  28. data/ext/gvl_wrappers.h +23 -0
  29. data/ext/pg.c +190 -98
  30. data/ext/pg.h +42 -17
  31. data/ext/pg_binary_decoder.c +20 -16
  32. data/ext/pg_binary_encoder.c +13 -12
  33. data/ext/pg_coder.c +95 -29
  34. data/ext/pg_connection.c +1043 -769
  35. data/ext/pg_copy_coder.c +50 -18
  36. data/ext/pg_record_coder.c +519 -0
  37. data/ext/pg_result.c +326 -142
  38. data/ext/pg_text_decoder.c +15 -9
  39. data/ext/pg_text_encoder.c +185 -53
  40. data/ext/pg_tuple.c +61 -27
  41. data/ext/pg_type_map.c +42 -9
  42. data/ext/pg_type_map_all_strings.c +19 -5
  43. data/ext/pg_type_map_by_class.c +54 -24
  44. data/ext/pg_type_map_by_column.c +73 -34
  45. data/ext/pg_type_map_by_mri_type.c +48 -19
  46. data/ext/pg_type_map_by_oid.c +55 -25
  47. data/ext/pg_type_map_in_ruby.c +51 -20
  48. data/ext/{util.c → pg_util.c} +7 -7
  49. data/ext/{util.h → pg_util.h} +0 -0
  50. data/lib/pg/basic_type_map_based_on_result.rb +47 -0
  51. data/lib/pg/basic_type_map_for_queries.rb +193 -0
  52. data/lib/pg/basic_type_map_for_results.rb +81 -0
  53. data/lib/pg/basic_type_registry.rb +296 -0
  54. data/lib/pg/binary_decoder.rb +1 -0
  55. data/lib/pg/coder.rb +23 -2
  56. data/lib/pg/connection.rb +589 -59
  57. data/lib/pg/constants.rb +1 -0
  58. data/lib/pg/exceptions.rb +1 -0
  59. data/lib/pg/result.rb +13 -1
  60. data/lib/pg/text_decoder.rb +2 -3
  61. data/lib/pg/text_encoder.rb +8 -18
  62. data/lib/pg/type_map_by_column.rb +2 -1
  63. data/lib/pg/version.rb +4 -0
  64. data/lib/pg.rb +48 -33
  65. data/misc/openssl-pg-segfault.rb +31 -0
  66. data/misc/postgres/History.txt +9 -0
  67. data/misc/postgres/Manifest.txt +5 -0
  68. data/misc/postgres/README.txt +21 -0
  69. data/misc/postgres/Rakefile +21 -0
  70. data/misc/postgres/lib/postgres.rb +16 -0
  71. data/misc/ruby-pg/History.txt +9 -0
  72. data/misc/ruby-pg/Manifest.txt +5 -0
  73. data/misc/ruby-pg/README.txt +21 -0
  74. data/misc/ruby-pg/Rakefile +21 -0
  75. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  76. data/pg.gemspec +32 -0
  77. data/rakelib/task_extension.rb +46 -0
  78. data/sample/array_insert.rb +20 -0
  79. data/sample/async_api.rb +106 -0
  80. data/sample/async_copyto.rb +39 -0
  81. data/sample/async_mixed.rb +56 -0
  82. data/sample/check_conn.rb +21 -0
  83. data/sample/copydata.rb +71 -0
  84. data/sample/copyfrom.rb +81 -0
  85. data/sample/copyto.rb +19 -0
  86. data/sample/cursor.rb +21 -0
  87. data/sample/disk_usage_report.rb +177 -0
  88. data/sample/issue-119.rb +94 -0
  89. data/sample/losample.rb +69 -0
  90. data/sample/minimal-testcase.rb +17 -0
  91. data/sample/notify_wait.rb +72 -0
  92. data/sample/pg_statistics.rb +285 -0
  93. data/sample/replication_monitor.rb +222 -0
  94. data/sample/test_binary_values.rb +33 -0
  95. data/sample/wal_shipper.rb +434 -0
  96. data/sample/warehouse_partitions.rb +311 -0
  97. data.tar.gz.sig +0 -0
  98. metadata +94 -237
  99. metadata.gz.sig +0 -0
  100. data/ChangeLog +0 -6595
  101. data/lib/pg/basic_type_mapping.rb +0 -459
  102. data/spec/data/expected_trace.out +0 -26
  103. data/spec/data/random_binary_data +0 -0
  104. data/spec/helpers.rb +0 -381
  105. data/spec/pg/basic_type_mapping_spec.rb +0 -508
  106. data/spec/pg/connection_spec.rb +0 -1849
  107. data/spec/pg/connection_sync_spec.rb +0 -41
  108. data/spec/pg/result_spec.rb +0 -491
  109. data/spec/pg/tuple_spec.rb +0 -280
  110. data/spec/pg/type_map_by_class_spec.rb +0 -138
  111. data/spec/pg/type_map_by_column_spec.rb +0 -222
  112. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  113. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  114. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  115. data/spec/pg/type_map_spec.rb +0 -22
  116. data/spec/pg/type_spec.rb +0 -949
  117. data/spec/pg_spec.rb +0 -50
@@ -1,12 +1,12 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_decoder.c,v 5d166a4d0441 2018/07/29 12:03:00 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "ruby/version.h"
8
8
  #include "pg.h"
9
- #include "util.h"
9
+ #include "pg_util.h"
10
10
  #ifdef HAVE_INTTYPES_H
11
11
  #include <inttypes.h>
12
12
  #endif
@@ -17,8 +17,8 @@ VALUE rb_mPG_BinaryDecoder;
17
17
  /*
18
18
  * Document-class: PG::BinaryDecoder::Boolean < PG::SimpleDecoder
19
19
  *
20
- * This is a decoder class for conversion of PostgreSQL binary bool type
21
- * to Ruby true or false objects.
20
+ * This is a decoder class for conversion of PostgreSQL binary +bool+ type
21
+ * to Ruby +true+ or +false+ objects.
22
22
  *
23
23
  */
24
24
  static VALUE
@@ -33,7 +33,7 @@ pg_bin_dec_boolean(t_pg_coder *conv, const char *val, int len, int tuple, int fi
33
33
  /*
34
34
  * Document-class: PG::BinaryDecoder::Integer < PG::SimpleDecoder
35
35
  *
36
- * This is a decoder class for conversion of PostgreSQL binary int2, int4 and int8 types
36
+ * This is a decoder class for conversion of PostgreSQL binary +int2+, +int4+ and +int8+ types
37
37
  * to Ruby Integer objects.
38
38
  *
39
39
  */
@@ -55,7 +55,7 @@ pg_bin_dec_integer(t_pg_coder *conv, const char *val, int len, int tuple, int fi
55
55
  /*
56
56
  * Document-class: PG::BinaryDecoder::Float < PG::SimpleDecoder
57
57
  *
58
- * This is a decoder class for conversion of PostgreSQL binary float4 and float8 types
58
+ * This is a decoder class for conversion of PostgreSQL binary +float4+ and +float8+ types
59
59
  * to Ruby Float objects.
60
60
  *
61
61
  */
@@ -87,7 +87,7 @@ pg_bin_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
87
87
  * Document-class: PG::BinaryDecoder::Bytea < PG::SimpleDecoder
88
88
  *
89
89
  * This decoder class delivers the data received from the server as binary String object.
90
- * It is therefore suitable for conversion of PostgreSQL bytea data as well as any other
90
+ * It is therefore suitable for conversion of PostgreSQL +bytea+ data as well as any other
91
91
  * data in binary format.
92
92
  *
93
93
  */
@@ -95,7 +95,7 @@ VALUE
95
95
  pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
96
96
  {
97
97
  VALUE ret;
98
- ret = rb_tainted_str_new( val, len );
98
+ ret = rb_str_new( val, len );
99
99
  PG_ENCODING_SET_NOCHECK( ret, rb_ascii8bit_encindex() );
100
100
  return ret;
101
101
  }
@@ -103,7 +103,7 @@ pg_bin_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int fiel
103
103
  /*
104
104
  * Document-class: PG::BinaryDecoder::ToBase64 < PG::CompositeDecoder
105
105
  *
106
- * This is a decoder class for conversion of binary (bytea) to base64 data.
106
+ * This is a decoder class for conversion of binary +bytea+ to base64 data.
107
107
  *
108
108
  */
109
109
  static VALUE
@@ -113,7 +113,7 @@ pg_bin_dec_to_base64(t_pg_coder *conv, const char *val, int len, int tuple, int
113
113
  t_pg_coder_dec_func dec_func = pg_coder_dec_func(this->elem, this->comp.format);
114
114
  int encoded_len = BASE64_ENCODED_SIZE(len);
115
115
  /* create a buffer of the encoded length */
116
- VALUE out_value = rb_tainted_str_new(NULL, encoded_len);
116
+ VALUE out_value = rb_str_new(NULL, encoded_len);
117
117
 
118
118
  base64_encode( RSTRING_PTR(out_value), val, len );
119
119
 
@@ -154,7 +154,8 @@ static VALUE
154
154
  pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
155
155
  {
156
156
  int64_t timestamp;
157
- struct timespec ts;
157
+ int64_t sec;
158
+ int64_t nsec;
158
159
  VALUE t;
159
160
 
160
161
  if( len != sizeof(timestamp) ){
@@ -171,14 +172,17 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
171
172
  default:
172
173
  /* PostgreSQL's timestamp is based on year 2000 and Ruby's time is based on 1970.
173
174
  * Adjust the 30 years difference. */
174
- ts.tv_sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
175
- ts.tv_nsec = (timestamp % 1000000) * 1000;
175
+ sec = (timestamp / 1000000) + 10957L * 24L * 3600L;
176
+ nsec = (timestamp % 1000000) * 1000;
176
177
 
177
- #if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T)
178
+ #if (RUBY_API_VERSION_MAJOR > 2 || (RUBY_API_VERSION_MAJOR == 2 && RUBY_API_VERSION_MINOR >= 3)) && defined(NEGATIVE_TIME_T) && defined(SIZEOF_TIME_T) && SIZEOF_TIME_T >= 8
178
179
  /* Fast path for time conversion */
179
- t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
180
+ {
181
+ struct timespec ts = {sec, nsec};
182
+ t = rb_time_timespec_new(&ts, conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL ? INT_MAX : INT_MAX-1);
183
+ }
180
184
  #else
181
- t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(ts.tv_sec), LL2NUM(ts.tv_nsec / 1000));
185
+ t = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(sec), LL2NUM(nsec / 1000));
182
186
  if( !(conv->flags & PG_CODER_TIMESTAMP_APP_LOCAL) ) {
183
187
  t = rb_funcall(t, rb_intern("utc"), 0);
184
188
  }
@@ -1,11 +1,11 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
- #include "util.h"
8
+ #include "pg_util.h"
9
9
  #ifdef HAVE_INTTYPES_H
10
10
  #include <inttypes.h>
11
11
  #endif
@@ -25,11 +25,12 @@ static int
25
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
- switch(value){
29
- case Qtrue : mybool = 1; break;
30
- case Qfalse : mybool = 0; break;
31
- default :
32
- rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
28
+ if (value == Qtrue) {
29
+ mybool = 1;
30
+ } else if (value == Qfalse) {
31
+ mybool = 0;
32
+ } else {
33
+ rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
33
34
  }
34
35
  if(out) *out = mybool;
35
36
  return 1;
@@ -38,7 +39,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
38
39
  /*
39
40
  * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
40
41
  *
41
- * This is the encoder class for the PostgreSQL int2 type.
42
+ * This is the encoder class for the PostgreSQL +int2+ (alias +smallint+) type.
42
43
  *
43
44
  * Non-Number values are expected to have method +to_i+ defined.
44
45
  *
@@ -55,9 +56,9 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
55
56
  }
56
57
 
57
58
  /*
58
- * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
59
+ * Document-class: PG::BinaryEncoder::Int4 < PG::SimpleEncoder
59
60
  *
60
- * This is the encoder class for the PostgreSQL int4 type.
61
+ * This is the encoder class for the PostgreSQL +int4+ (alias +integer+) type.
61
62
  *
62
63
  * Non-Number values are expected to have method +to_i+ defined.
63
64
  *
@@ -74,9 +75,9 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, i
74
75
  }
75
76
 
76
77
  /*
77
- * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
78
+ * Document-class: PG::BinaryEncoder::Int8 < PG::SimpleEncoder
78
79
  *
79
- * This is the encoder class for the PostgreSQL int8 type.
80
+ * This is the encoder class for the PostgreSQL +int8+ (alias +bigint+) type.
80
81
  *
81
82
  * Non-Number values are expected to have method +to_i+ defined.
82
83
  *
data/ext/pg_coder.c CHANGED
@@ -26,11 +26,11 @@ pg_coder_allocate( VALUE klass )
26
26
  void
27
27
  pg_coder_init_encoder( VALUE self )
28
28
  {
29
- t_pg_coder *this = DATA_PTR( self );
29
+ t_pg_coder *this = RTYPEDDATA_DATA( self );
30
30
  VALUE klass = rb_class_of(self);
31
31
  if( rb_const_defined( klass, s_id_CFUNC ) ){
32
32
  VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
33
- this->enc_func = DATA_PTR(cfunc);
33
+ this->enc_func = RTYPEDDATA_DATA(cfunc);
34
34
  } else {
35
35
  this->enc_func = NULL;
36
36
  }
@@ -45,12 +45,12 @@ pg_coder_init_encoder( VALUE self )
45
45
  void
46
46
  pg_coder_init_decoder( VALUE self )
47
47
  {
48
- t_pg_coder *this = DATA_PTR( self );
48
+ t_pg_coder *this = RTYPEDDATA_DATA( self );
49
49
  VALUE klass = rb_class_of(self);
50
50
  this->enc_func = NULL;
51
51
  if( rb_const_defined( klass, s_id_CFUNC ) ){
52
52
  VALUE cfunc = rb_const_get( klass, s_id_CFUNC );
53
- this->dec_func = DATA_PTR(cfunc);
53
+ this->dec_func = RTYPEDDATA_DATA(cfunc);
54
54
  } else {
55
55
  this->dec_func = NULL;
56
56
  }
@@ -61,20 +61,74 @@ pg_coder_init_decoder( VALUE self )
61
61
  rb_iv_set( self, "@name", Qnil );
62
62
  }
63
63
 
64
+ static size_t
65
+ pg_coder_memsize(const void *_this)
66
+ {
67
+ const t_pg_coder *this = (const t_pg_coder *)_this;
68
+ return sizeof(*this);
69
+ }
70
+
71
+ static size_t
72
+ pg_composite_coder_memsize(const void *_this)
73
+ {
74
+ const t_pg_composite_coder *this = (const t_pg_composite_coder *)_this;
75
+ return sizeof(*this);
76
+ }
77
+
78
+ void
79
+ pg_coder_compact(void *_this)
80
+ {
81
+ t_pg_coder *this = (t_pg_coder *)_this;
82
+ pg_gc_location(this->coder_obj);
83
+ }
84
+
85
+ static void
86
+ pg_composite_coder_compact(void *_this)
87
+ {
88
+ t_pg_composite_coder *this = (t_pg_composite_coder *)_this;
89
+ pg_coder_compact(&this->comp);
90
+ }
91
+
92
+ const rb_data_type_t pg_coder_type = {
93
+ "PG::Coder",
94
+ {
95
+ (RUBY_DATA_FUNC) NULL,
96
+ RUBY_TYPED_DEFAULT_FREE,
97
+ pg_coder_memsize,
98
+ pg_compact_callback(pg_coder_compact),
99
+ },
100
+ 0,
101
+ 0,
102
+ RUBY_TYPED_FREE_IMMEDIATELY,
103
+ };
104
+
64
105
  static VALUE
65
106
  pg_simple_encoder_allocate( VALUE klass )
66
107
  {
67
108
  t_pg_coder *this;
68
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
109
+ VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
69
110
  pg_coder_init_encoder( self );
70
111
  return self;
71
112
  }
72
113
 
114
+ static const rb_data_type_t pg_composite_coder_type = {
115
+ "PG::CompositeCoder",
116
+ {
117
+ (RUBY_DATA_FUNC) NULL,
118
+ RUBY_TYPED_DEFAULT_FREE,
119
+ pg_composite_coder_memsize,
120
+ pg_compact_callback(pg_composite_coder_compact),
121
+ },
122
+ &pg_coder_type,
123
+ 0,
124
+ RUBY_TYPED_FREE_IMMEDIATELY,
125
+ };
126
+
73
127
  static VALUE
74
128
  pg_composite_encoder_allocate( VALUE klass )
75
129
  {
76
130
  t_pg_composite_coder *this;
77
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
131
+ VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
78
132
  pg_coder_init_encoder( self );
79
133
  this->elem = NULL;
80
134
  this->needs_quotation = 1;
@@ -87,7 +141,7 @@ static VALUE
87
141
  pg_simple_decoder_allocate( VALUE klass )
88
142
  {
89
143
  t_pg_coder *this;
90
- VALUE self = Data_Make_Struct( klass, t_pg_coder, NULL, -1, this );
144
+ VALUE self = TypedData_Make_Struct( klass, t_pg_coder, &pg_coder_type, this );
91
145
  pg_coder_init_decoder( self );
92
146
  return self;
93
147
  }
@@ -96,7 +150,7 @@ static VALUE
96
150
  pg_composite_decoder_allocate( VALUE klass )
97
151
  {
98
152
  t_pg_composite_coder *this;
99
- VALUE self = Data_Make_Struct( klass, t_pg_composite_coder, NULL, -1, this );
153
+ VALUE self = TypedData_Make_Struct( klass, t_pg_composite_coder, &pg_composite_coder_type, this );
100
154
  pg_coder_init_decoder( self );
101
155
  this->elem = NULL;
102
156
  this->needs_quotation = 1;
@@ -123,7 +177,7 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
123
177
  VALUE value;
124
178
  int len, len2;
125
179
  int enc_idx;
126
- t_pg_coder *this = DATA_PTR(self);
180
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
127
181
 
128
182
  if(argc < 1 || argc > 2){
129
183
  rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
@@ -145,7 +199,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
145
199
 
146
200
  if( len == -1 ){
147
201
  /* The intermediate value is a String that can be used directly. */
148
- OBJ_INFECT(intermediate, value);
149
202
  return intermediate;
150
203
  }
151
204
 
@@ -157,7 +210,6 @@ pg_coder_encode(int argc, VALUE *argv, VALUE self)
157
210
  rb_obj_classname( self ), len, len2 );
158
211
  }
159
212
  rb_str_set_len( res, len2 );
160
- OBJ_INFECT(res, value);
161
213
 
162
214
  RB_GC_GUARD(intermediate);
163
215
 
@@ -182,7 +234,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
182
234
  int tuple = -1;
183
235
  int field = -1;
184
236
  VALUE res;
185
- t_pg_coder *this = DATA_PTR(self);
237
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
186
238
 
187
239
  if(argc < 1 || argc > 3){
188
240
  rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
@@ -203,8 +255,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
203
255
  rb_raise(rb_eRuntimeError, "no decoder function defined");
204
256
  }
205
257
 
206
- res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
207
- OBJ_INFECT(res, argv[0]);
258
+ res = this->dec_func(this, val, RSTRING_LENINT(argv[0]), tuple, field, ENCODING_GET(argv[0]));
208
259
 
209
260
  return res;
210
261
  }
@@ -221,7 +272,7 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
221
272
  static VALUE
222
273
  pg_coder_oid_set(VALUE self, VALUE oid)
223
274
  {
224
- t_pg_coder *this = DATA_PTR(self);
275
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
225
276
  this->oid = NUM2UINT(oid);
226
277
  return oid;
227
278
  }
@@ -236,7 +287,7 @@ pg_coder_oid_set(VALUE self, VALUE oid)
236
287
  static VALUE
237
288
  pg_coder_oid_get(VALUE self)
238
289
  {
239
- t_pg_coder *this = DATA_PTR(self);
290
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
240
291
  return UINT2NUM(this->oid);
241
292
  }
242
293
 
@@ -252,7 +303,7 @@ pg_coder_oid_get(VALUE self)
252
303
  static VALUE
253
304
  pg_coder_format_set(VALUE self, VALUE format)
254
305
  {
255
- t_pg_coder *this = DATA_PTR(self);
306
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
256
307
  this->format = NUM2INT(format);
257
308
  return format;
258
309
  }
@@ -267,7 +318,7 @@ pg_coder_format_set(VALUE self, VALUE format)
267
318
  static VALUE
268
319
  pg_coder_format_get(VALUE self)
269
320
  {
270
- t_pg_coder *this = DATA_PTR(self);
321
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
271
322
  return INT2NUM(this->format);
272
323
  }
273
324
 
@@ -283,7 +334,7 @@ pg_coder_format_get(VALUE self)
283
334
  static VALUE
284
335
  pg_coder_flags_set(VALUE self, VALUE flags)
285
336
  {
286
- t_pg_coder *this = DATA_PTR(self);
337
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
287
338
  this->flags = NUM2INT(flags);
288
339
  return flags;
289
340
  }
@@ -297,7 +348,7 @@ pg_coder_flags_set(VALUE self, VALUE flags)
297
348
  static VALUE
298
349
  pg_coder_flags_get(VALUE self)
299
350
  {
300
- t_pg_coder *this = DATA_PTR(self);
351
+ t_pg_coder *this = RTYPEDDATA_DATA(self);
301
352
  return INT2NUM(this->flags);
302
353
  }
303
354
 
@@ -314,7 +365,7 @@ pg_coder_flags_get(VALUE self)
314
365
  static VALUE
315
366
  pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
316
367
  {
317
- t_pg_composite_coder *this = DATA_PTR(self);
368
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
318
369
  this->needs_quotation = RTEST(needs_quotation);
319
370
  return needs_quotation;
320
371
  }
@@ -329,7 +380,7 @@ pg_coder_needs_quotation_set(VALUE self, VALUE needs_quotation)
329
380
  static VALUE
330
381
  pg_coder_needs_quotation_get(VALUE self)
331
382
  {
332
- t_pg_composite_coder *this = DATA_PTR(self);
383
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
333
384
  return this->needs_quotation ? Qtrue : Qfalse;
334
385
  }
335
386
 
@@ -344,7 +395,7 @@ pg_coder_needs_quotation_get(VALUE self)
344
395
  static VALUE
345
396
  pg_coder_delimiter_set(VALUE self, VALUE delimiter)
346
397
  {
347
- t_pg_composite_coder *this = DATA_PTR(self);
398
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
348
399
  StringValue(delimiter);
349
400
  if(RSTRING_LEN(delimiter) != 1)
350
401
  rb_raise( rb_eArgError, "delimiter size must be one byte");
@@ -361,7 +412,7 @@ pg_coder_delimiter_set(VALUE self, VALUE delimiter)
361
412
  static VALUE
362
413
  pg_coder_delimiter_get(VALUE self)
363
414
  {
364
- t_pg_composite_coder *this = DATA_PTR(self);
415
+ t_pg_composite_coder *this = RTYPEDDATA_DATA(self);
365
416
  return rb_str_new(&this->delimiter, 1);
366
417
  }
367
418
 
@@ -377,12 +428,12 @@ pg_coder_delimiter_get(VALUE self)
377
428
  static VALUE
378
429
  pg_coder_elements_type_set(VALUE self, VALUE elem_type)
379
430
  {
380
- t_pg_composite_coder *this = DATA_PTR( self );
431
+ t_pg_composite_coder *this = RTYPEDDATA_DATA( self );
381
432
 
382
433
  if ( NIL_P(elem_type) ){
383
434
  this->elem = NULL;
384
435
  } else if ( rb_obj_is_kind_of(elem_type, rb_cPG_Coder) ){
385
- this->elem = DATA_PTR( elem_type );
436
+ this->elem = RTYPEDDATA_DATA( elem_type );
386
437
  } else {
387
438
  rb_raise( rb_eTypeError, "wrong elements type %s (expected some kind of PG::Coder)",
388
439
  rb_obj_classname( elem_type ) );
@@ -392,14 +443,31 @@ pg_coder_elements_type_set(VALUE self, VALUE elem_type)
392
443
  return elem_type;
393
444
  }
394
445
 
446
+ static const rb_data_type_t pg_coder_cfunc_type = {
447
+ "PG::Coder::CFUNC",
448
+ {
449
+ (RUBY_DATA_FUNC)NULL,
450
+ (RUBY_DATA_FUNC)NULL,
451
+ (size_t (*)(const void *))NULL,
452
+ },
453
+ 0,
454
+ 0,
455
+ RUBY_TYPED_FREE_IMMEDIATELY,
456
+ };
457
+
395
458
  void
396
459
  pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
397
460
  {
398
- VALUE cfunc_obj = Data_Wrap_Struct( rb_cObject, NULL, NULL, func );
461
+ VALUE cfunc_obj = TypedData_Wrap_Struct( rb_cObject, &pg_coder_cfunc_type, func );
399
462
  VALUE coder_klass = rb_define_class_under( nsp, name, base_klass );
400
463
  if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_BinaryDecoder )
401
464
  rb_include_module( coder_klass, rb_mPG_BinaryFormatting );
402
465
 
466
+ if( nsp==rb_mPG_BinaryEncoder || nsp==rb_mPG_TextEncoder )
467
+ rb_define_method( coder_klass, "encode", pg_coder_encode, -1 );
468
+ if( nsp==rb_mPG_BinaryDecoder || nsp==rb_mPG_TextDecoder )
469
+ rb_define_method( coder_klass, "decode", pg_coder_decode, -1 );
470
+
403
471
  rb_define_const( coder_klass, "CFUNC", cfunc_obj );
404
472
 
405
473
  RB_GC_GUARD(cfunc_obj);
@@ -512,8 +580,6 @@ init_pg_coder()
512
580
  * This accessor is only used in PG::Coder#inspect .
513
581
  */
514
582
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
515
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
516
- rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
517
583
 
518
584
  /* Document-class: PG::SimpleCoder < PG::Coder */
519
585
  rb_cPG_SimpleCoder = rb_define_class_under( rb_mPG, "SimpleCoder", rb_cPG_Coder );