pg 0.18.0 → 1.1.4

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 (80) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/BSDL +2 -2
  4. data/ChangeLog +1221 -4
  5. data/History.rdoc +200 -0
  6. data/Manifest.txt +5 -18
  7. data/README-Windows.rdoc +15 -26
  8. data/README.rdoc +27 -10
  9. data/Rakefile +33 -24
  10. data/Rakefile.cross +57 -39
  11. data/ext/errorcodes.def +37 -0
  12. data/ext/errorcodes.rb +1 -1
  13. data/ext/errorcodes.txt +16 -1
  14. data/ext/extconf.rb +29 -35
  15. data/ext/gvl_wrappers.c +4 -0
  16. data/ext/gvl_wrappers.h +27 -39
  17. data/ext/pg.c +27 -53
  18. data/ext/pg.h +66 -83
  19. data/ext/pg_binary_decoder.c +75 -6
  20. data/ext/pg_binary_encoder.c +14 -12
  21. data/ext/pg_coder.c +83 -13
  22. data/ext/pg_connection.c +627 -351
  23. data/ext/pg_copy_coder.c +44 -9
  24. data/ext/pg_result.c +364 -134
  25. data/ext/pg_text_decoder.c +605 -46
  26. data/ext/pg_text_encoder.c +95 -76
  27. data/ext/pg_tuple.c +541 -0
  28. data/ext/pg_type_map.c +20 -13
  29. data/ext/pg_type_map_by_column.c +7 -7
  30. data/ext/pg_type_map_by_mri_type.c +2 -2
  31. data/ext/pg_type_map_in_ruby.c +4 -7
  32. data/ext/util.c +7 -7
  33. data/ext/util.h +3 -3
  34. data/lib/pg/basic_type_mapping.rb +105 -45
  35. data/lib/pg/binary_decoder.rb +22 -0
  36. data/lib/pg/coder.rb +1 -1
  37. data/lib/pg/connection.rb +109 -39
  38. data/lib/pg/constants.rb +1 -1
  39. data/lib/pg/exceptions.rb +1 -1
  40. data/lib/pg/result.rb +11 -6
  41. data/lib/pg/text_decoder.rb +25 -20
  42. data/lib/pg/text_encoder.rb +43 -1
  43. data/lib/pg/tuple.rb +30 -0
  44. data/lib/pg/type_map_by_column.rb +1 -1
  45. data/lib/pg.rb +21 -11
  46. data/spec/helpers.rb +50 -25
  47. data/spec/pg/basic_type_mapping_spec.rb +287 -30
  48. data/spec/pg/connection_spec.rb +695 -282
  49. data/spec/pg/connection_sync_spec.rb +41 -0
  50. data/spec/pg/result_spec.rb +59 -17
  51. data/spec/pg/tuple_spec.rb +280 -0
  52. data/spec/pg/type_map_by_class_spec.rb +3 -3
  53. data/spec/pg/type_map_by_column_spec.rb +1 -1
  54. data/spec/pg/type_map_by_mri_type_spec.rb +2 -2
  55. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  56. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  57. data/spec/pg/type_map_spec.rb +1 -1
  58. data/spec/pg/type_spec.rb +319 -35
  59. data/spec/pg_spec.rb +2 -2
  60. data.tar.gz.sig +0 -0
  61. metadata +68 -68
  62. metadata.gz.sig +0 -0
  63. data/sample/array_insert.rb +0 -20
  64. data/sample/async_api.rb +0 -106
  65. data/sample/async_copyto.rb +0 -39
  66. data/sample/async_mixed.rb +0 -56
  67. data/sample/check_conn.rb +0 -21
  68. data/sample/copyfrom.rb +0 -81
  69. data/sample/copyto.rb +0 -19
  70. data/sample/cursor.rb +0 -21
  71. data/sample/disk_usage_report.rb +0 -186
  72. data/sample/issue-119.rb +0 -94
  73. data/sample/losample.rb +0 -69
  74. data/sample/minimal-testcase.rb +0 -17
  75. data/sample/notify_wait.rb +0 -72
  76. data/sample/pg_statistics.rb +0 -294
  77. data/sample/replication_monitor.rb +0 -231
  78. data/sample/test_binary_values.rb +0 -33
  79. data/sample/wal_shipper.rb +0 -434
  80. data/sample/warehouse_partitions.rb +0 -320
data/ext/pg_coder.c CHANGED
@@ -38,6 +38,7 @@ pg_coder_init_encoder( VALUE self )
38
38
  this->coder_obj = self;
39
39
  this->oid = 0;
40
40
  this->format = 0;
41
+ this->flags = 0;
41
42
  rb_iv_set( self, "@name", Qnil );
42
43
  }
43
44
 
@@ -56,6 +57,7 @@ pg_coder_init_decoder( VALUE self )
56
57
  this->coder_obj = self;
57
58
  this->oid = 0;
58
59
  this->format = 0;
60
+ this->flags = 0;
59
61
  rb_iv_set( self, "@name", Qnil );
60
62
  }
61
63
 
@@ -105,7 +107,7 @@ pg_composite_decoder_allocate( VALUE klass )
105
107
 
106
108
  /*
107
109
  * call-seq:
108
- * coder.encode( value )
110
+ * coder.encode( value [, encoding] )
109
111
  *
110
112
  * Encodes the given Ruby object into string representation, without
111
113
  * sending data to/from the database server.
@@ -114,13 +116,24 @@ pg_composite_decoder_allocate( VALUE klass )
114
116
  *
115
117
  */
116
118
  static VALUE
117
- pg_coder_encode(VALUE self, VALUE value)
119
+ pg_coder_encode(int argc, VALUE *argv, VALUE self)
118
120
  {
119
121
  VALUE res;
120
122
  VALUE intermediate;
123
+ VALUE value;
121
124
  int len, len2;
125
+ int enc_idx;
122
126
  t_pg_coder *this = DATA_PTR(self);
123
127
 
128
+ if(argc < 1 || argc > 2){
129
+ rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
130
+ }else if(argc == 1){
131
+ enc_idx = rb_ascii8bit_encindex();
132
+ }else{
133
+ enc_idx = rb_to_encoding_index(argv[1]);
134
+ }
135
+ value = argv[0];
136
+
124
137
  if( NIL_P(value) )
125
138
  return Qnil;
126
139
 
@@ -128,7 +141,7 @@ pg_coder_encode(VALUE self, VALUE value)
128
141
  rb_raise(rb_eRuntimeError, "no encoder function defined");
129
142
  }
130
143
 
131
- len = this->enc_func( this, value, NULL, &intermediate );
144
+ len = this->enc_func( this, value, NULL, &intermediate, enc_idx );
132
145
 
133
146
  if( len == -1 ){
134
147
  /* The intermediate value is a String that can be used directly. */
@@ -137,7 +150,8 @@ pg_coder_encode(VALUE self, VALUE value)
137
150
  }
138
151
 
139
152
  res = rb_str_new(NULL, len);
140
- len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate);
153
+ PG_ENCODING_SET_NOCHECK(res, enc_idx);
154
+ len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
141
155
  if( len < len2 ){
142
156
  rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
143
157
  rb_obj_classname( self ), len, len2 );
@@ -165,8 +179,8 @@ static VALUE
165
179
  pg_coder_decode(int argc, VALUE *argv, VALUE self)
166
180
  {
167
181
  char *val;
168
- VALUE tuple = -1;
169
- VALUE field = -1;
182
+ int tuple = -1;
183
+ int field = -1;
170
184
  VALUE res;
171
185
  t_pg_coder *this = DATA_PTR(self);
172
186
 
@@ -180,7 +194,11 @@ pg_coder_decode(int argc, VALUE *argv, VALUE self)
180
194
  if( NIL_P(argv[0]) )
181
195
  return Qnil;
182
196
 
183
- val = StringValuePtr(argv[0]);
197
+ if( this->format == 0 ){
198
+ val = StringValueCStr(argv[0]);
199
+ }else{
200
+ val = StringValuePtr(argv[0]);
201
+ }
184
202
  if( !this->dec_func ){
185
203
  rb_raise(rb_eRuntimeError, "no decoder function defined");
186
204
  }
@@ -253,6 +271,36 @@ pg_coder_format_get(VALUE self)
253
271
  return INT2NUM(this->format);
254
272
  }
255
273
 
274
+ /*
275
+ * call-seq:
276
+ * coder.flags = Integer
277
+ *
278
+ * Set coder specific bitwise OR-ed flags.
279
+ * See the particular en- or decoder description for available flags.
280
+ *
281
+ * The default is +0+.
282
+ */
283
+ static VALUE
284
+ pg_coder_flags_set(VALUE self, VALUE flags)
285
+ {
286
+ t_pg_coder *this = DATA_PTR(self);
287
+ this->flags = NUM2INT(flags);
288
+ return flags;
289
+ }
290
+
291
+ /*
292
+ * call-seq:
293
+ * coder.flags -> Integer
294
+ *
295
+ * Get current bitwise OR-ed coder flags.
296
+ */
297
+ static VALUE
298
+ pg_coder_flags_get(VALUE self)
299
+ {
300
+ t_pg_coder *this = DATA_PTR(self);
301
+ return INT2NUM(this->flags);
302
+ }
303
+
256
304
  /*
257
305
  * call-seq:
258
306
  * coder.needs_quotation = Boolean
@@ -359,10 +407,19 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
359
407
 
360
408
 
361
409
  static int
362
- pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
410
+ pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
363
411
  {
364
- *intermediate = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
365
- StringValue( *intermediate );
412
+ int arity = rb_obj_method_arity(conv->coder_obj, s_id_encode);
413
+ if( arity == 1 ){
414
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
415
+ StringValue( out_str );
416
+ *intermediate = rb_str_export_to_enc(out_str, rb_enc_from_index(enc_idx));
417
+ }else{
418
+ VALUE enc = rb_enc_from_encoding(rb_enc_from_index(enc_idx));
419
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 2, value, enc );
420
+ StringValue( out_str );
421
+ *intermediate = out_str;
422
+ }
366
423
  return -1;
367
424
  }
368
425
 
@@ -382,14 +439,14 @@ pg_coder_enc_func(t_pg_coder *this)
382
439
  }
383
440
 
384
441
  static VALUE
385
- pg_text_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
442
+ pg_text_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
386
443
  {
387
444
  VALUE string = pg_text_dec_string(this, val, len, tuple, field, enc_idx);
388
445
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
389
446
  }
390
447
 
391
448
  static VALUE
392
- pg_bin_dec_in_ruby(t_pg_coder *this, char *val, int len, int tuple, int field, int enc_idx)
449
+ pg_bin_dec_in_ruby(t_pg_coder *this, const char *val, int len, int tuple, int field, int enc_idx)
393
450
  {
394
451
  VALUE string = pg_bin_dec_bytea(this, val, len, tuple, field, enc_idx);
395
452
  return rb_funcall( this->coder_obj, s_id_decode, 3, string, INT2NUM(tuple), INT2NUM(field) );
@@ -436,13 +493,26 @@ init_pg_coder()
436
493
  rb_define_method( rb_cPG_Coder, "oid", pg_coder_oid_get, 0 );
437
494
  rb_define_method( rb_cPG_Coder, "format=", pg_coder_format_set, 1 );
438
495
  rb_define_method( rb_cPG_Coder, "format", pg_coder_format_get, 0 );
496
+ rb_define_method( rb_cPG_Coder, "flags=", pg_coder_flags_set, 1 );
497
+ rb_define_method( rb_cPG_Coder, "flags", pg_coder_flags_get, 0 );
498
+
499
+ /* define flags to be used with PG::Coder#flags= */
500
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_UTC", INT2NUM(PG_CODER_TIMESTAMP_DB_UTC));
501
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_DB_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL));
502
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_UTC", INT2NUM(PG_CODER_TIMESTAMP_APP_UTC));
503
+ rb_define_const( rb_cPG_Coder, "TIMESTAMP_APP_LOCAL", INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL));
504
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_MASK", INT2NUM(PG_CODER_FORMAT_ERROR_MASK));
505
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_RAISE", INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE));
506
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_STRING", INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING));
507
+ rb_define_const( rb_cPG_Coder, "FORMAT_ERROR_TO_PARTIAL", INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL));
508
+
439
509
  /*
440
510
  * Name of the coder or the corresponding data type.
441
511
  *
442
512
  * This accessor is only used in PG::Coder#inspect .
443
513
  */
444
514
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
445
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, 1 );
515
+ rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
446
516
  rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
447
517
 
448
518
  /* Document-class: PG::SimpleCoder < PG::Coder */