pg 0.18.0 → 1.0.0

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 (66) 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 +130 -0
  6. data/Manifest.txt +0 -18
  7. data/README-Windows.rdoc +15 -26
  8. data/README.rdoc +16 -10
  9. data/Rakefile +32 -23
  10. data/Rakefile.cross +56 -38
  11. data/ext/errorcodes.def +33 -0
  12. data/ext/errorcodes.txt +15 -1
  13. data/ext/extconf.rb +27 -35
  14. data/ext/gvl_wrappers.c +4 -0
  15. data/ext/gvl_wrappers.h +27 -39
  16. data/ext/pg.c +19 -51
  17. data/ext/pg.h +22 -79
  18. data/ext/pg_binary_decoder.c +3 -1
  19. data/ext/pg_binary_encoder.c +14 -12
  20. data/ext/pg_coder.c +31 -10
  21. data/ext/pg_connection.c +350 -263
  22. data/ext/pg_copy_coder.c +34 -4
  23. data/ext/pg_result.c +27 -25
  24. data/ext/pg_text_decoder.c +9 -10
  25. data/ext/pg_text_encoder.c +93 -73
  26. data/ext/pg_type_map.c +20 -13
  27. data/ext/pg_type_map_by_column.c +7 -7
  28. data/ext/pg_type_map_by_mri_type.c +2 -2
  29. data/ext/pg_type_map_in_ruby.c +4 -7
  30. data/ext/util.c +3 -3
  31. data/ext/util.h +1 -1
  32. data/lib/pg/basic_type_mapping.rb +69 -42
  33. data/lib/pg/connection.rb +89 -38
  34. data/lib/pg/result.rb +10 -5
  35. data/lib/pg/text_decoder.rb +12 -3
  36. data/lib/pg/text_encoder.rb +8 -0
  37. data/lib/pg.rb +18 -10
  38. data/spec/helpers.rb +9 -16
  39. data/spec/pg/basic_type_mapping_spec.rb +58 -4
  40. data/spec/pg/connection_spec.rb +477 -217
  41. data/spec/pg/result_spec.rb +14 -7
  42. data/spec/pg/type_map_by_class_spec.rb +2 -2
  43. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  44. data/spec/pg/type_spec.rb +145 -33
  45. data/spec/pg_spec.rb +1 -1
  46. data.tar.gz.sig +0 -0
  47. metadata +67 -66
  48. metadata.gz.sig +0 -0
  49. data/sample/array_insert.rb +0 -20
  50. data/sample/async_api.rb +0 -106
  51. data/sample/async_copyto.rb +0 -39
  52. data/sample/async_mixed.rb +0 -56
  53. data/sample/check_conn.rb +0 -21
  54. data/sample/copyfrom.rb +0 -81
  55. data/sample/copyto.rb +0 -19
  56. data/sample/cursor.rb +0 -21
  57. data/sample/disk_usage_report.rb +0 -186
  58. data/sample/issue-119.rb +0 -94
  59. data/sample/losample.rb +0 -69
  60. data/sample/minimal-testcase.rb +0 -17
  61. data/sample/notify_wait.rb +0 -72
  62. data/sample/pg_statistics.rb +0 -294
  63. data/sample/replication_monitor.rb +0 -231
  64. data/sample/test_binary_values.rb +0 -33
  65. data/sample/wal_shipper.rb +0 -434
  66. data/sample/warehouse_partitions.rb +0 -320
data/ext/pg.h CHANGED
@@ -9,95 +9,30 @@
9
9
  #include <stdio.h>
10
10
  #include <stdlib.h>
11
11
  #include <sys/types.h>
12
+ #if !defined(_WIN32)
13
+ # include <sys/time.h>
14
+ #endif
12
15
  #if defined(HAVE_UNISTD_H) && !defined(_WIN32)
13
16
  # include <unistd.h>
14
17
  #endif /* HAVE_UNISTD_H */
15
18
 
16
19
  /* Ruby headers */
17
20
  #include "ruby.h"
18
- #ifdef HAVE_RUBY_ST_H
19
- # include "ruby/st.h"
20
- #elif HAVE_ST_H
21
- # include "st.h"
22
- #endif
21
+ #include "ruby/st.h"
22
+ #include "ruby/encoding.h"
23
23
 
24
- #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
25
- # include "ruby/encoding.h"
26
- # define M17N_SUPPORTED
27
- # ifdef HAVE_RB_ENCDB_ALIAS
28
- extern int rb_encdb_alias(const char *, const char *);
29
- # define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
30
- # elif HAVE_RB_ENC_ALIAS
31
- extern int rb_enc_alias(const char *, const char *);
32
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
33
- # else
34
- extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */
35
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
36
- # endif
37
-
38
-
39
- # if !defined(ENCODING_SET_INLINED)
40
- /* Rubinius doesn't define ENCODING_SET_INLINED, so we fall back to the more
41
- * portable version.
42
- */
43
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
44
- do { \
45
- rb_enc_set_index((obj), (i)); \
46
- } while(0)
47
- # else
48
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
24
+ /* exported by ruby-1.9.3+ but not declared */
25
+ extern int rb_encdb_alias(const char *, const char *);
26
+
27
+ #define PG_ENCODING_SET_NOCHECK(obj,i) \
49
28
  do { \
50
29
  if ((i) < ENCODING_INLINE_MAX) \
51
30
  ENCODING_SET_INLINED((obj), (i)); \
52
31
  else \
53
32
  rb_enc_set_index((obj), (i)); \
54
33
  } while(0)
55
- # endif
56
-
57
- #else
58
- # define PG_ENCODING_SET_NOCHECK(obj,i) /* nothing */
59
- #endif
60
-
61
- #if RUBY_VM != 1
62
- # define RUBY_18_COMPAT
63
- #endif
64
-
65
- #ifndef RARRAY_LEN
66
- # define RARRAY_LEN(x) RARRAY((x))->len
67
- #endif /* RARRAY_LEN */
68
-
69
- #ifndef RSTRING_LEN
70
- # define RSTRING_LEN(x) RSTRING((x))->len
71
- #endif /* RSTRING_LEN */
72
-
73
- #ifndef RSTRING_PTR
74
- # define RSTRING_PTR(x) RSTRING((x))->ptr
75
- #endif /* RSTRING_PTR */
76
34
 
77
- #ifndef StringValuePtr
78
- # define StringValuePtr(x) STR2CSTR(x)
79
- #endif /* StringValuePtr */
80
-
81
- #ifdef RUBY_18_COMPAT
82
- # define rb_io_stdio_file GetWriteFile
83
- # include "rubyio.h"
84
- #else
85
- # include "ruby/io.h"
86
- #endif
87
-
88
- #ifdef RUBINIUS
89
- /* Workaround for wrong FIXNUM_MAX definition */
90
- typedef intptr_t native_int;
91
- #endif
92
-
93
- #ifndef RETURN_SIZED_ENUMERATOR
94
- #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR((obj), (argc), (argv))
95
- #endif
96
-
97
- #ifndef HAVE_RB_HASH_DUP
98
- /* Rubinius doesn't define rb_hash_dup() */
99
- #define rb_hash_dup(tuple) rb_funcall((tuple), rb_intern("dup"), 0)
100
- #endif
35
+ #include "ruby/io.h"
101
36
 
102
37
  #ifndef timeradd
103
38
  #define timeradd(a, b, result) \
@@ -133,6 +68,15 @@
133
68
  typedef long suseconds_t;
134
69
  #endif
135
70
 
71
+ #if defined(HAVE_VARIABLE_LENGTH_ARRAYS)
72
+ #define PG_VARIABLE_LENGTH_ARRAY(type, name, len, maxlen) type name[(len)];
73
+ #else
74
+ #define PG_VARIABLE_LENGTH_ARRAY(type, name, len, maxlen) \
75
+ type name[(maxlen)] = {(len)>(maxlen) ? (rb_raise(rb_eArgError, "Number of " #name " (%d) exceeds allowed maximum of " #maxlen, (len) ), (type)1) : (type)0};
76
+
77
+ #define PG_MAX_COLUMNS 4000
78
+ #endif
79
+
136
80
  /* The data behind each PG::Connection object */
137
81
  typedef struct {
138
82
  PGconn *pgconn;
@@ -196,7 +140,7 @@ typedef struct {
196
140
  } t_pg_result;
197
141
 
198
142
 
199
- typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *);
143
+ typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
200
144
  typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
201
145
  typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
202
146
  typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
@@ -312,7 +256,8 @@ void init_pg_binary_decoder _(( void ));
312
256
  VALUE lookup_error_class _(( const char * ));
313
257
  VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
314
258
  VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
315
- int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *));
259
+ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
260
+ int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
316
261
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
317
262
  t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
318
263
  void pg_define_coder _(( const char *, void *, VALUE, VALUE ));
@@ -369,12 +314,10 @@ pgresult_get_this( VALUE self )
369
314
  }
370
315
 
371
316
 
372
- #ifdef M17N_SUPPORTED
373
317
  rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
374
318
  rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
375
319
  const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
376
320
  rb_encoding *pg_conn_enc_get _(( PGconn * ));
377
- #endif /* M17N_SUPPORTED */
378
321
 
379
322
  void notice_receiver_proxy(void *arg, const PGresult *result);
380
323
  void notice_processor_proxy(void *arg, const char *message);
@@ -1,12 +1,14 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_decoder.c,v 185638b52684 2014/11/08 20:43:53 lars $
3
+ * $Id: pg_binary_decoder.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
8
  #include "util.h"
9
+ #ifdef HAVE_INTTYPES_H
9
10
  #include <inttypes.h>
11
+ #endif
10
12
 
11
13
  VALUE rb_mPG_BinaryDecoder;
12
14
 
@@ -1,12 +1,14 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_encoder.c,v ac23631c96d9 2014/10/14 11:50:21 lars $
3
+ * $Id: pg_binary_encoder.c,v e61a06f1f5ed 2015/12/25 21:14:21 lars $
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
8
  #include "util.h"
9
+ #ifdef HAVE_INTTYPES_H
9
10
  #include <inttypes.h>
11
+ #endif
10
12
 
11
13
  VALUE rb_mPG_BinaryEncoder;
12
14
 
@@ -20,16 +22,16 @@ VALUE rb_mPG_BinaryEncoder;
20
22
  *
21
23
  */
22
24
  static int
23
- pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
25
+ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
24
26
  {
25
- char bool;
27
+ char mybool;
26
28
  switch(value){
27
- case Qtrue : bool = 1; break;
28
- case Qfalse : bool = 0; break;
29
+ case Qtrue : mybool = 1; break;
30
+ case Qfalse : mybool = 0; break;
29
31
  default :
30
32
  rb_raise( rb_eTypeError, "wrong data for binary boolean converter" );
31
33
  }
32
- if(out) *out = bool;
34
+ if(out) *out = mybool;
33
35
  return 1;
34
36
  }
35
37
 
@@ -42,7 +44,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
42
44
  *
43
45
  */
44
46
  static int
45
- pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
47
+ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
46
48
  {
47
49
  if(out){
48
50
  write_nbo16(NUM2INT(*intermediate), out);
@@ -61,7 +63,7 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
61
63
  *
62
64
  */
63
65
  static int
64
- pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
66
+ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
65
67
  {
66
68
  if(out){
67
69
  write_nbo32(NUM2LONG(*intermediate), out);
@@ -80,7 +82,7 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
80
82
  *
81
83
  */
82
84
  static int
83
- pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
85
+ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
84
86
  {
85
87
  if(out){
86
88
  write_nbo64(NUM2LL(*intermediate), out);
@@ -98,7 +100,7 @@ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
98
100
  *
99
101
  */
100
102
  static int
101
- pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
103
+ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
102
104
  {
103
105
  int strlen;
104
106
  VALUE subint;
@@ -107,13 +109,13 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
107
109
 
108
110
  if(out){
109
111
  /* Second encoder pass, if required */
110
- strlen = enc_func(this->elem, value, out, intermediate);
112
+ strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
111
113
  strlen = base64_decode( out, out, strlen );
112
114
 
113
115
  return strlen;
114
116
  } else {
115
117
  /* First encoder pass */
116
- strlen = enc_func(this->elem, value, NULL, &subint);
118
+ strlen = enc_func(this->elem, value, NULL, &subint, enc_idx);
117
119
 
118
120
  if( strlen == -1 ){
119
121
  /* Encoded string is returned in subint */
data/ext/pg_coder.c CHANGED
@@ -105,7 +105,7 @@ pg_composite_decoder_allocate( VALUE klass )
105
105
 
106
106
  /*
107
107
  * call-seq:
108
- * coder.encode( value )
108
+ * coder.encode( value [, encoding] )
109
109
  *
110
110
  * Encodes the given Ruby object into string representation, without
111
111
  * sending data to/from the database server.
@@ -114,13 +114,24 @@ pg_composite_decoder_allocate( VALUE klass )
114
114
  *
115
115
  */
116
116
  static VALUE
117
- pg_coder_encode(VALUE self, VALUE value)
117
+ pg_coder_encode(int argc, VALUE *argv, VALUE self)
118
118
  {
119
119
  VALUE res;
120
120
  VALUE intermediate;
121
+ VALUE value;
121
122
  int len, len2;
123
+ int enc_idx;
122
124
  t_pg_coder *this = DATA_PTR(self);
123
125
 
126
+ if(argc < 1 || argc > 2){
127
+ rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
128
+ }else if(argc == 1){
129
+ enc_idx = rb_ascii8bit_encindex();
130
+ }else{
131
+ enc_idx = rb_to_encoding_index(argv[1]);
132
+ }
133
+ value = argv[0];
134
+
124
135
  if( NIL_P(value) )
125
136
  return Qnil;
126
137
 
@@ -128,7 +139,7 @@ pg_coder_encode(VALUE self, VALUE value)
128
139
  rb_raise(rb_eRuntimeError, "no encoder function defined");
129
140
  }
130
141
 
131
- len = this->enc_func( this, value, NULL, &intermediate );
142
+ len = this->enc_func( this, value, NULL, &intermediate, enc_idx );
132
143
 
133
144
  if( len == -1 ){
134
145
  /* The intermediate value is a String that can be used directly. */
@@ -137,7 +148,8 @@ pg_coder_encode(VALUE self, VALUE value)
137
148
  }
138
149
 
139
150
  res = rb_str_new(NULL, len);
140
- len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate);
151
+ PG_ENCODING_SET_NOCHECK(res, enc_idx);
152
+ len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
141
153
  if( len < len2 ){
142
154
  rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
143
155
  rb_obj_classname( self ), len, len2 );
@@ -165,8 +177,8 @@ static VALUE
165
177
  pg_coder_decode(int argc, VALUE *argv, VALUE self)
166
178
  {
167
179
  char *val;
168
- VALUE tuple = -1;
169
- VALUE field = -1;
180
+ int tuple = -1;
181
+ int field = -1;
170
182
  VALUE res;
171
183
  t_pg_coder *this = DATA_PTR(self);
172
184
 
@@ -359,10 +371,19 @@ pg_define_coder( const char *name, void *func, VALUE base_klass, VALUE nsp )
359
371
 
360
372
 
361
373
  static int
362
- pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
374
+ pg_text_enc_in_ruby(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate, int enc_idx)
363
375
  {
364
- *intermediate = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
365
- StringValue( *intermediate );
376
+ int arity = rb_obj_method_arity(conv->coder_obj, s_id_encode);
377
+ if( arity == 1 ){
378
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 1, value );
379
+ StringValue( out_str );
380
+ *intermediate = rb_str_export_to_enc(out_str, rb_enc_from_index(enc_idx));
381
+ }else{
382
+ VALUE enc = rb_enc_from_encoding(rb_enc_from_index(enc_idx));
383
+ VALUE out_str = rb_funcall( conv->coder_obj, s_id_encode, 2, value, enc );
384
+ StringValue( out_str );
385
+ *intermediate = out_str;
386
+ }
366
387
  return -1;
367
388
  }
368
389
 
@@ -442,7 +463,7 @@ init_pg_coder()
442
463
  * This accessor is only used in PG::Coder#inspect .
443
464
  */
444
465
  rb_define_attr( rb_cPG_Coder, "name", 1, 1 );
445
- rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, 1 );
466
+ rb_define_method( rb_cPG_Coder, "encode", pg_coder_encode, -1 );
446
467
  rb_define_method( rb_cPG_Coder, "decode", pg_coder_decode, -1 );
447
468
 
448
469
  /* Document-class: PG::SimpleCoder < PG::Coder */