pg 0.18.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
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 */