pg 0.17.1 → 0.18.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/ChangeLog +2407 -2
  4. data/History.rdoc +68 -0
  5. data/Manifest.txt +29 -1
  6. data/README-Windows.rdoc +15 -26
  7. data/README.rdoc +52 -2
  8. data/Rakefile +56 -18
  9. data/Rakefile.cross +77 -49
  10. data/ext/extconf.rb +33 -26
  11. data/ext/pg.c +142 -21
  12. data/ext/pg.h +242 -6
  13. data/ext/pg_binary_decoder.c +162 -0
  14. data/ext/pg_binary_encoder.c +162 -0
  15. data/ext/pg_coder.c +479 -0
  16. data/ext/pg_connection.c +858 -553
  17. data/ext/pg_copy_coder.c +561 -0
  18. data/ext/pg_errors.c +6 -0
  19. data/ext/pg_result.c +479 -128
  20. data/ext/pg_text_decoder.c +421 -0
  21. data/ext/pg_text_encoder.c +663 -0
  22. data/ext/pg_type_map.c +159 -0
  23. data/ext/pg_type_map_all_strings.c +116 -0
  24. data/ext/pg_type_map_by_class.c +239 -0
  25. data/ext/pg_type_map_by_column.c +312 -0
  26. data/ext/pg_type_map_by_mri_type.c +284 -0
  27. data/ext/pg_type_map_by_oid.c +355 -0
  28. data/ext/pg_type_map_in_ruby.c +299 -0
  29. data/ext/util.c +149 -0
  30. data/ext/util.h +65 -0
  31. data/lib/pg/basic_type_mapping.rb +399 -0
  32. data/lib/pg/coder.rb +83 -0
  33. data/lib/pg/connection.rb +81 -29
  34. data/lib/pg/result.rb +13 -3
  35. data/lib/pg/text_decoder.rb +44 -0
  36. data/lib/pg/text_encoder.rb +27 -0
  37. data/lib/pg/type_map_by_column.rb +15 -0
  38. data/lib/pg.rb +12 -2
  39. data/spec/{lib/helpers.rb → helpers.rb} +101 -39
  40. data/spec/pg/basic_type_mapping_spec.rb +251 -0
  41. data/spec/pg/connection_spec.rb +516 -218
  42. data/spec/pg/result_spec.rb +216 -112
  43. data/spec/pg/type_map_by_class_spec.rb +138 -0
  44. data/spec/pg/type_map_by_column_spec.rb +222 -0
  45. data/spec/pg/type_map_by_mri_type_spec.rb +136 -0
  46. data/spec/pg/type_map_by_oid_spec.rb +149 -0
  47. data/spec/pg/type_map_in_ruby_spec.rb +164 -0
  48. data/spec/pg/type_map_spec.rb +22 -0
  49. data/spec/pg/type_spec.rb +697 -0
  50. data/spec/pg_spec.rb +24 -18
  51. data.tar.gz.sig +0 -0
  52. metadata +111 -45
  53. metadata.gz.sig +0 -0
@@ -0,0 +1,162 @@
1
+ /*
2
+ * pg_column_map.c - PG::ColumnMap class extension
3
+ * $Id: pg_binary_decoder.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
4
+ *
5
+ */
6
+
7
+ #include "pg.h"
8
+ #include "util.h"
9
+ #ifdef HAVE_INTTYPES_H
10
+ #include <inttypes.h>
11
+ #endif
12
+
13
+ VALUE rb_mPG_BinaryDecoder;
14
+
15
+
16
+ /*
17
+ * Document-class: PG::BinaryDecoder::Boolean < PG::SimpleDecoder
18
+ *
19
+ * This is a decoder class for conversion of PostgreSQL binary bool type
20
+ * to Ruby true or false objects.
21
+ *
22
+ */
23
+ static VALUE
24
+ pg_bin_dec_boolean(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
25
+ {
26
+ if (len < 1) {
27
+ rb_raise( rb_eTypeError, "wrong data for binary boolean converter in tuple %d field %d", tuple, field);
28
+ }
29
+ return *val == 0 ? Qfalse : Qtrue;
30
+ }
31
+
32
+ /*
33
+ * Document-class: PG::BinaryDecoder::Integer < PG::SimpleDecoder
34
+ *
35
+ * This is a decoder class for conversion of PostgreSQL binary int2, int4 and int8 types
36
+ * to Ruby Integer objects.
37
+ *
38
+ */
39
+ static VALUE
40
+ pg_bin_dec_integer(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
41
+ {
42
+ switch( len ){
43
+ case 2:
44
+ return INT2NUM(read_nbo16(val));
45
+ case 4:
46
+ return LONG2NUM(read_nbo32(val));
47
+ case 8:
48
+ return LL2NUM(read_nbo64(val));
49
+ default:
50
+ rb_raise( rb_eTypeError, "wrong data for binary integer converter in tuple %d field %d length %d", tuple, field, len);
51
+ }
52
+ }
53
+
54
+ /*
55
+ * Document-class: PG::BinaryDecoder::Float < PG::SimpleDecoder
56
+ *
57
+ * This is a decoder class for conversion of PostgreSQL binary float4 and float8 types
58
+ * to Ruby Float objects.
59
+ *
60
+ */
61
+ static VALUE
62
+ pg_bin_dec_float(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
63
+ {
64
+ union {
65
+ float f;
66
+ int32_t i;
67
+ } swap4;
68
+ union {
69
+ double f;
70
+ int64_t i;
71
+ } swap8;
72
+
73
+ switch( len ){
74
+ case 4:
75
+ swap4.i = read_nbo32(val);
76
+ return rb_float_new(swap4.f);
77
+ case 8:
78
+ swap8.i = read_nbo64(val);
79
+ return rb_float_new(swap8.f);
80
+ default:
81
+ rb_raise( rb_eTypeError, "wrong data for BinaryFloat converter in tuple %d field %d length %d", tuple, field, len);
82
+ }
83
+ }
84
+
85
+ /*
86
+ * Document-class: PG::BinaryDecoder::Bytea < PG::SimpleDecoder
87
+ *
88
+ * This decoder class delivers the data received from the server as binary String object.
89
+ * It is therefore suitable for conversion of PostgreSQL bytea data as well as any other
90
+ * data in binary format.
91
+ *
92
+ */
93
+ VALUE
94
+ pg_bin_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
95
+ {
96
+ VALUE ret;
97
+ ret = rb_tainted_str_new( val, len );
98
+ PG_ENCODING_SET_NOCHECK( ret, rb_ascii8bit_encindex() );
99
+ return ret;
100
+ }
101
+
102
+ /*
103
+ * Document-class: PG::BinaryDecoder::ToBase64 < PG::CompositeDecoder
104
+ *
105
+ * This is a decoder class for conversion of binary (bytea) to base64 data.
106
+ *
107
+ */
108
+ static VALUE
109
+ pg_bin_dec_to_base64(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
110
+ {
111
+ t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
112
+ t_pg_coder_dec_func dec_func = pg_coder_dec_func(this->elem, this->comp.format);
113
+ int encoded_len = BASE64_ENCODED_SIZE(len);
114
+ /* create a buffer of the encoded length */
115
+ VALUE out_value = rb_tainted_str_new(NULL, encoded_len);
116
+
117
+ base64_encode( RSTRING_PTR(out_value), val, len );
118
+
119
+ /* Is it a pure String conversion? Then we can directly send out_value to the user. */
120
+ if( this->comp.format == 0 && dec_func == pg_text_dec_string ){
121
+ PG_ENCODING_SET_NOCHECK( out_value, enc_idx );
122
+ return out_value;
123
+ }
124
+ if( this->comp.format == 1 && dec_func == pg_bin_dec_bytea ){
125
+ PG_ENCODING_SET_NOCHECK( out_value, rb_ascii8bit_encindex() );
126
+ return out_value;
127
+ }
128
+ out_value = dec_func(this->elem, RSTRING_PTR(out_value), encoded_len, tuple, field, enc_idx);
129
+
130
+ return out_value;
131
+ }
132
+
133
+ /*
134
+ * Document-class: PG::BinaryDecoder::String < PG::SimpleDecoder
135
+ *
136
+ * This is a decoder class for conversion of PostgreSQL text output to
137
+ * to Ruby String object. The output value will have the character encoding
138
+ * set with PG::Connection#internal_encoding= .
139
+ *
140
+ */
141
+
142
+ void
143
+ init_pg_binary_decoder()
144
+ {
145
+ /* This module encapsulates all decoder classes with binary input format */
146
+ rb_mPG_BinaryDecoder = rb_define_module_under( rb_mPG, "BinaryDecoder" );
147
+
148
+ /* Make RDoc aware of the decoder classes... */
149
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Boolean", rb_cPG_SimpleDecoder ); */
150
+ pg_define_coder( "Boolean", pg_bin_dec_boolean, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
151
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Integer", rb_cPG_SimpleDecoder ); */
152
+ pg_define_coder( "Integer", pg_bin_dec_integer, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
153
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Float", rb_cPG_SimpleDecoder ); */
154
+ pg_define_coder( "Float", pg_bin_dec_float, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
155
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "String", rb_cPG_SimpleDecoder ); */
156
+ pg_define_coder( "String", pg_text_dec_string, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
157
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Bytea", rb_cPG_SimpleDecoder ); */
158
+ pg_define_coder( "Bytea", pg_bin_dec_bytea, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
159
+
160
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "ToBase64", rb_cPG_CompositeDecoder ); */
161
+ pg_define_coder( "ToBase64", pg_bin_dec_to_base64, rb_cPG_CompositeDecoder, rb_mPG_BinaryDecoder );
162
+ }
@@ -0,0 +1,162 @@
1
+ /*
2
+ * pg_column_map.c - PG::ColumnMap class extension
3
+ * $Id: pg_binary_encoder.c,v 72168db5fb7b 2015/11/04 16:13:42 lars $
4
+ *
5
+ */
6
+
7
+ #include "pg.h"
8
+ #include "util.h"
9
+ #ifdef HAVE_INTTYPES_H
10
+ #include <inttypes.h>
11
+ #endif
12
+
13
+ VALUE rb_mPG_BinaryEncoder;
14
+
15
+
16
+ /*
17
+ * Document-class: PG::BinaryEncoder::Boolean < PG::SimpleEncoder
18
+ *
19
+ * This is the encoder class for the PostgreSQL boolean type.
20
+ *
21
+ * It accepts true and false. Other values will raise an exception.
22
+ *
23
+ */
24
+ static int
25
+ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
26
+ {
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" );
33
+ }
34
+ if(out) *out = mybool;
35
+ return 1;
36
+ }
37
+
38
+ /*
39
+ * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
40
+ *
41
+ * This is the encoder class for the PostgreSQL int2 type.
42
+ *
43
+ * Non-Number values are expected to have method +to_i+ defined.
44
+ *
45
+ */
46
+ static int
47
+ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
48
+ {
49
+ if(out){
50
+ write_nbo16(NUM2INT(*intermediate), out);
51
+ }else{
52
+ *intermediate = pg_obj_to_i(value);
53
+ }
54
+ return 2;
55
+ }
56
+
57
+ /*
58
+ * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
59
+ *
60
+ * This is the encoder class for the PostgreSQL int4 type.
61
+ *
62
+ * Non-Number values are expected to have method +to_i+ defined.
63
+ *
64
+ */
65
+ static int
66
+ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
67
+ {
68
+ if(out){
69
+ write_nbo32(NUM2LONG(*intermediate), out);
70
+ }else{
71
+ *intermediate = pg_obj_to_i(value);
72
+ }
73
+ return 4;
74
+ }
75
+
76
+ /*
77
+ * Document-class: PG::BinaryEncoder::Int2 < PG::SimpleEncoder
78
+ *
79
+ * This is the encoder class for the PostgreSQL int8 type.
80
+ *
81
+ * Non-Number values are expected to have method +to_i+ defined.
82
+ *
83
+ */
84
+ static int
85
+ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
86
+ {
87
+ if(out){
88
+ write_nbo64(NUM2LL(*intermediate), out);
89
+ }else{
90
+ *intermediate = pg_obj_to_i(value);
91
+ }
92
+ return 8;
93
+ }
94
+
95
+ /*
96
+ * Document-class: PG::BinaryEncoder::FromBase64 < PG::CompositeEncoder
97
+ *
98
+ * This is an encoder class for conversion of base64 encoded data
99
+ * to it's binary representation.
100
+ *
101
+ */
102
+ static int
103
+ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
104
+ {
105
+ int strlen;
106
+ VALUE subint;
107
+ t_pg_composite_coder *this = (t_pg_composite_coder *)conv;
108
+ t_pg_coder_enc_func enc_func = pg_coder_enc_func(this->elem);
109
+
110
+ if(out){
111
+ /* Second encoder pass, if required */
112
+ strlen = enc_func(this->elem, value, out, intermediate);
113
+ strlen = base64_decode( out, out, strlen );
114
+
115
+ return strlen;
116
+ } else {
117
+ /* First encoder pass */
118
+ strlen = enc_func(this->elem, value, NULL, &subint);
119
+
120
+ if( strlen == -1 ){
121
+ /* Encoded string is returned in subint */
122
+ VALUE out_str;
123
+
124
+ strlen = RSTRING_LENINT(subint);
125
+ out_str = rb_str_new(NULL, BASE64_DECODED_SIZE(strlen));
126
+
127
+ strlen = base64_decode( RSTRING_PTR(out_str), RSTRING_PTR(subint), strlen);
128
+ rb_str_set_len( out_str, strlen );
129
+ *intermediate = out_str;
130
+
131
+ return -1;
132
+ } else {
133
+ *intermediate = subint;
134
+
135
+ return BASE64_DECODED_SIZE(strlen);
136
+ }
137
+ }
138
+ }
139
+
140
+ void
141
+ init_pg_binary_encoder()
142
+ {
143
+ /* This module encapsulates all encoder classes with binary output format */
144
+ rb_mPG_BinaryEncoder = rb_define_module_under( rb_mPG, "BinaryEncoder" );
145
+
146
+ /* Make RDoc aware of the encoder classes... */
147
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Boolean", rb_cPG_SimpleEncoder ); */
148
+ pg_define_coder( "Boolean", pg_bin_enc_boolean, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
149
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Int2", rb_cPG_SimpleEncoder ); */
150
+ pg_define_coder( "Int2", pg_bin_enc_int2, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
151
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Int4", rb_cPG_SimpleEncoder ); */
152
+ pg_define_coder( "Int4", pg_bin_enc_int4, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
153
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Int8", rb_cPG_SimpleEncoder ); */
154
+ pg_define_coder( "Int8", pg_bin_enc_int8, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
155
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "String", rb_cPG_SimpleEncoder ); */
156
+ pg_define_coder( "String", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
157
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "Bytea", rb_cPG_SimpleEncoder ); */
158
+ pg_define_coder( "Bytea", pg_coder_enc_to_s, rb_cPG_SimpleEncoder, rb_mPG_BinaryEncoder );
159
+
160
+ /* dummy = rb_define_class_under( rb_mPG_BinaryEncoder, "FromBase64", rb_cPG_CompositeEncoder ); */
161
+ pg_define_coder( "FromBase64", pg_bin_enc_from_base64, rb_cPG_CompositeEncoder, rb_mPG_BinaryEncoder );
162
+ }