pg 1.1.3 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) 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 +291 -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.rb +0 -0
  26. data/ext/errorcodes.txt +21 -2
  27. data/ext/extconf.rb +101 -26
  28. data/ext/gvl_wrappers.c +4 -0
  29. data/ext/gvl_wrappers.h +23 -0
  30. data/ext/pg.c +190 -122
  31. data/ext/pg.h +43 -17
  32. data/ext/pg_binary_decoder.c +20 -16
  33. data/ext/pg_binary_encoder.c +13 -12
  34. data/ext/pg_coder.c +95 -29
  35. data/ext/pg_connection.c +1214 -919
  36. data/ext/pg_copy_coder.c +50 -18
  37. data/ext/pg_record_coder.c +521 -0
  38. data/ext/pg_result.c +344 -153
  39. data/ext/pg_text_decoder.c +15 -9
  40. data/ext/pg_text_encoder.c +185 -53
  41. data/ext/pg_tuple.c +63 -35
  42. data/ext/pg_type_map.c +42 -9
  43. data/ext/pg_type_map_all_strings.c +19 -5
  44. data/ext/pg_type_map_by_class.c +54 -24
  45. data/ext/pg_type_map_by_column.c +73 -34
  46. data/ext/pg_type_map_by_mri_type.c +48 -19
  47. data/ext/pg_type_map_by_oid.c +55 -25
  48. data/ext/pg_type_map_in_ruby.c +51 -20
  49. data/ext/{util.c → pg_util.c} +7 -7
  50. data/ext/{util.h → pg_util.h} +0 -0
  51. data/lib/pg/basic_type_map_based_on_result.rb +47 -0
  52. data/lib/pg/basic_type_map_for_queries.rb +193 -0
  53. data/lib/pg/basic_type_map_for_results.rb +81 -0
  54. data/lib/pg/basic_type_registry.rb +301 -0
  55. data/lib/pg/binary_decoder.rb +1 -0
  56. data/lib/pg/coder.rb +23 -2
  57. data/lib/pg/connection.rb +669 -71
  58. data/lib/pg/constants.rb +1 -0
  59. data/lib/pg/exceptions.rb +8 -1
  60. data/lib/pg/result.rb +13 -1
  61. data/lib/pg/text_decoder.rb +2 -3
  62. data/lib/pg/text_encoder.rb +8 -18
  63. data/lib/pg/type_map_by_column.rb +2 -1
  64. data/lib/pg/version.rb +4 -0
  65. data/lib/pg.rb +48 -33
  66. data/misc/openssl-pg-segfault.rb +31 -0
  67. data/misc/postgres/History.txt +9 -0
  68. data/misc/postgres/Manifest.txt +5 -0
  69. data/misc/postgres/README.txt +21 -0
  70. data/misc/postgres/Rakefile +21 -0
  71. data/misc/postgres/lib/postgres.rb +16 -0
  72. data/misc/ruby-pg/History.txt +9 -0
  73. data/misc/ruby-pg/Manifest.txt +5 -0
  74. data/misc/ruby-pg/README.txt +21 -0
  75. data/misc/ruby-pg/Rakefile +21 -0
  76. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  77. data/pg.gemspec +32 -0
  78. data/rakelib/task_extension.rb +46 -0
  79. data/sample/array_insert.rb +20 -0
  80. data/sample/async_api.rb +102 -0
  81. data/sample/async_copyto.rb +39 -0
  82. data/sample/async_mixed.rb +56 -0
  83. data/sample/check_conn.rb +21 -0
  84. data/sample/copydata.rb +71 -0
  85. data/sample/copyfrom.rb +81 -0
  86. data/sample/copyto.rb +19 -0
  87. data/sample/cursor.rb +21 -0
  88. data/sample/disk_usage_report.rb +177 -0
  89. data/sample/issue-119.rb +94 -0
  90. data/sample/losample.rb +69 -0
  91. data/sample/minimal-testcase.rb +17 -0
  92. data/sample/notify_wait.rb +72 -0
  93. data/sample/pg_statistics.rb +285 -0
  94. data/sample/replication_monitor.rb +222 -0
  95. data/sample/test_binary_values.rb +33 -0
  96. data/sample/wal_shipper.rb +434 -0
  97. data/sample/warehouse_partitions.rb +311 -0
  98. data.tar.gz.sig +0 -0
  99. metadata +94 -237
  100. metadata.gz.sig +0 -0
  101. data/ChangeLog +0 -6595
  102. data/lib/pg/basic_type_mapping.rb +0 -459
  103. data/spec/data/expected_trace.out +0 -26
  104. data/spec/data/random_binary_data +0 -0
  105. data/spec/helpers.rb +0 -381
  106. data/spec/pg/basic_type_mapping_spec.rb +0 -508
  107. data/spec/pg/connection_spec.rb +0 -1849
  108. data/spec/pg/connection_sync_spec.rb +0 -41
  109. data/spec/pg/result_spec.rb +0 -491
  110. data/spec/pg/tuple_spec.rb +0 -280
  111. data/spec/pg/type_map_by_class_spec.rb +0 -138
  112. data/spec/pg/type_map_by_column_spec.rb +0 -222
  113. data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
  114. data/spec/pg/type_map_by_oid_spec.rb +0 -149
  115. data/spec/pg/type_map_in_ruby_spec.rb +0 -164
  116. data/spec/pg/type_map_spec.rb +0 -22
  117. data/spec/pg/type_spec.rb +0 -949
  118. 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 );