pg 0.21.0 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.rdoc +98 -0
  5. data/Manifest.txt +5 -1
  6. data/README.rdoc +14 -4
  7. data/Rakefile +4 -5
  8. data/Rakefile.cross +17 -21
  9. data/ext/errorcodes.def +12 -0
  10. data/ext/errorcodes.rb +1 -1
  11. data/ext/errorcodes.txt +4 -1
  12. data/ext/extconf.rb +14 -32
  13. data/ext/gvl_wrappers.c +4 -0
  14. data/ext/gvl_wrappers.h +23 -39
  15. data/ext/pg.c +23 -50
  16. data/ext/pg.h +51 -81
  17. data/ext/pg_binary_decoder.c +73 -6
  18. data/ext/pg_coder.c +52 -3
  19. data/ext/pg_connection.c +369 -219
  20. data/ext/pg_copy_coder.c +10 -5
  21. data/ext/pg_result.c +343 -119
  22. data/ext/pg_text_decoder.c +597 -37
  23. data/ext/pg_text_encoder.c +6 -7
  24. data/ext/pg_tuple.c +541 -0
  25. data/ext/util.c +6 -6
  26. data/ext/util.h +2 -2
  27. data/lib/pg.rb +5 -7
  28. data/lib/pg/basic_type_mapping.rb +40 -7
  29. data/lib/pg/binary_decoder.rb +22 -0
  30. data/lib/pg/coder.rb +1 -1
  31. data/lib/pg/connection.rb +27 -3
  32. data/lib/pg/constants.rb +1 -1
  33. data/lib/pg/exceptions.rb +1 -1
  34. data/lib/pg/result.rb +1 -1
  35. data/lib/pg/text_decoder.rb +19 -23
  36. data/lib/pg/text_encoder.rb +35 -1
  37. data/lib/pg/tuple.rb +30 -0
  38. data/lib/pg/type_map_by_column.rb +1 -1
  39. data/spec/helpers.rb +49 -21
  40. data/spec/pg/basic_type_mapping_spec.rb +230 -27
  41. data/spec/pg/connection_spec.rb +473 -277
  42. data/spec/pg/connection_sync_spec.rb +41 -0
  43. data/spec/pg/result_spec.rb +48 -13
  44. data/spec/pg/tuple_spec.rb +280 -0
  45. data/spec/pg/type_map_by_class_spec.rb +1 -1
  46. data/spec/pg/type_map_by_column_spec.rb +1 -1
  47. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  48. data/spec/pg/type_map_by_oid_spec.rb +1 -1
  49. data/spec/pg/type_map_in_ruby_spec.rb +1 -1
  50. data/spec/pg/type_map_spec.rb +1 -1
  51. data/spec/pg/type_spec.rb +184 -12
  52. data/spec/pg_spec.rb +2 -2
  53. metadata +37 -33
  54. metadata.gz.sig +0 -0
  55. data/lib/pg/deprecated_constants.rb +0 -21
@@ -5,6 +5,10 @@
5
5
 
6
6
  #include "pg.h"
7
7
 
8
+ #ifndef HAVE_PQENCRYPTPASSWORDCONN
9
+ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm){return NULL;}
10
+ #endif
11
+
8
12
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
9
13
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
10
14
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
@@ -15,14 +15,7 @@
15
15
  #ifndef __gvl_wrappers_h
16
16
  #define __gvl_wrappers_h
17
17
 
18
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
19
- extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
20
- #endif
21
-
22
- #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
23
- extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
24
- rb_unblock_function_t *ubf, void *data2);
25
- #endif
18
+ #include <ruby/thread.h>
26
19
 
27
20
  #define DEFINE_PARAM_LIST1(type, name) \
28
21
  name,
@@ -53,21 +46,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
53
46
  return NULL; \
54
47
  }
55
48
 
56
- #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
57
- #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
58
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
59
- struct gvl_wrapper_##name##_params params = { \
60
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
61
- }; \
62
- rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
63
- when_non_void( return params.retval; ) \
64
- }
65
- #else
66
- #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
67
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
68
- return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
69
- }
70
- #endif
49
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
50
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
51
+ struct gvl_wrapper_##name##_params params = { \
52
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
53
+ }; \
54
+ rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
55
+ when_non_void( return params.retval; ) \
56
+ }
71
57
 
72
58
  #define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
73
59
  rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
@@ -80,21 +66,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
80
66
  return NULL; \
81
67
  }
82
68
 
83
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
84
- #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
85
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
86
- struct gvl_wrapper_##name##_params params = { \
87
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
88
- }; \
89
- rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
90
- when_non_void( return params.retval; ) \
91
- }
92
- #else
93
- #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
94
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
95
- return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
96
- }
97
- #endif
69
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
70
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
71
+ struct gvl_wrapper_##name##_params params = { \
72
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
73
+ }; \
74
+ rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
75
+ when_non_void( return params.retval; ) \
76
+ }
98
77
 
99
78
  #define GVL_TYPE_VOID(string)
100
79
  #define GVL_TYPE_NONVOID(string) string
@@ -200,6 +179,11 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
200
179
 
201
180
  #define FOR_EACH_PARAM_OF_PQisBusy(param)
202
181
 
182
+ #define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
183
+ param(PGconn *, conn) \
184
+ param(const char *, passwd) \
185
+ param(const char *, user)
186
+
203
187
  #define FOR_EACH_PARAM_OF_PQcancel(param) \
204
188
  param(PGcancel *, cancel) \
205
189
  param(char *, errbuf)
@@ -231,9 +215,9 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
231
215
  function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
232
216
  function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
233
217
  function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
218
+ function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
234
219
  function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
235
220
 
236
-
237
221
  FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
238
222
 
239
223
 
data/ext/pg.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg.c - Toplevel extension
3
- * $Id: pg.c,v c77d0997b4e4 2016/08/20 17:30:03 ged $
3
+ * $Id: pg.c,v 2d334508484a 2018/08/27 11:33:43 lars $
4
4
  *
5
5
  * Author/s:
6
6
  *
@@ -48,6 +48,7 @@
48
48
 
49
49
  #include "pg.h"
50
50
 
51
+ int pg_skip_deprecation_warning;
51
52
  VALUE rb_mPG;
52
53
  VALUE rb_mPGconstants;
53
54
 
@@ -69,7 +70,6 @@ VALUE rb_mPGconstants;
69
70
  * M17n functions
70
71
  */
71
72
 
72
- #ifdef M17N_SUPPORTED
73
73
  /**
74
74
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
75
75
  */
@@ -143,9 +143,6 @@ pg_find_or_create_johab(void)
143
143
  }
144
144
 
145
145
  enc_index = rb_define_dummy_encoding(aliases[0]);
146
- for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
147
- ENC_ALIAS(aliases[i], aliases[0]);
148
- }
149
146
  return rb_enc_from_index(enc_index);
150
147
  }
151
148
 
@@ -229,8 +226,6 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
229
226
  return encname;
230
227
  }
231
228
 
232
- #endif /* M17N_SUPPORTED */
233
-
234
229
 
235
230
  /*
236
231
  * Ensures that the given string has enough capacity to take expand_len
@@ -260,45 +255,26 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
260
255
  * rb_str_set_len( string, current_out - RSTRING_PTR(string) );
261
256
  *
262
257
  */
263
- #ifdef HAVE_RB_STR_MODIFY_EXPAND
264
- /* Use somewhat faster version with access to string capacity on MRI */
265
- char *
266
- pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
267
- {
268
- long curr_len = curr_ptr - RSTRING_PTR(str);
269
- long curr_capa = rb_str_capacity( str );
270
- if( curr_capa < curr_len + expand_len ){
271
- rb_str_set_len( str, curr_len );
272
- rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
273
- curr_ptr = RSTRING_PTR(str) + curr_len;
274
- }
275
- if( end_ptr )
276
- *end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
277
- return curr_ptr;
278
- }
279
- #else
280
- /* Use the more portable version */
281
- char *
282
- pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
283
- {
284
- long curr_len = curr_ptr - RSTRING_PTR(str);
285
- long curr_capa = RSTRING_LEN( str );
286
- if( curr_capa < curr_len + expand_len ){
287
- rb_str_resize( str, (curr_len + expand_len) * 2 - curr_capa );
288
- curr_ptr = RSTRING_PTR(str) + curr_len;
289
- }
290
- if( end_ptr )
291
- *end_ptr = RSTRING_PTR(str) + RSTRING_LEN(str);
292
- return curr_ptr;
258
+ char *
259
+ pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
260
+ {
261
+ long curr_len = curr_ptr - RSTRING_PTR(str);
262
+ long curr_capa = rb_str_capacity( str );
263
+ if( curr_capa < curr_len + expand_len ){
264
+ rb_str_set_len( str, curr_len );
265
+ rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
266
+ curr_ptr = RSTRING_PTR(str) + curr_len;
293
267
  }
294
- #endif
268
+ if( end_ptr )
269
+ *end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
270
+ return curr_ptr;
271
+ }
295
272
 
296
273
 
297
274
  /**************************************************************************
298
275
  * Module Methods
299
276
  **************************************************************************/
300
277
 
301
- #ifdef HAVE_PQLIBVERSION
302
278
  /*
303
279
  * call-seq:
304
280
  * PG.library_version -> Integer
@@ -316,7 +292,6 @@ pg_s_library_version(VALUE self)
316
292
  UNUSED( self );
317
293
  return INT2NUM(PQlibVersion());
318
294
  }
319
- #endif
320
295
 
321
296
 
322
297
  /*
@@ -404,15 +379,20 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
404
379
  void
405
380
  Init_pg_ext()
406
381
  {
382
+ if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
383
+ /* Set all bits to disable all deprecation warnings. */
384
+ pg_skip_deprecation_warning = 0xFFFF;
385
+ } else {
386
+ pg_skip_deprecation_warning = 0;
387
+ }
388
+
407
389
  rb_mPG = rb_define_module( "PG" );
408
390
  rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
409
391
 
410
392
  /*************************
411
393
  * PG module methods
412
394
  *************************/
413
- #ifdef HAVE_PQLIBVERSION
414
395
  rb_define_singleton_method( rb_mPG, "library_version", pg_s_library_version, 0 );
415
- #endif
416
396
  rb_define_singleton_method( rb_mPG, "isthreadsafe", pg_s_threadsafe_p, 0 );
417
397
  SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
418
398
  SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
@@ -478,7 +458,6 @@ Init_pg_ext()
478
458
  /* Verbose error verbosity level (#set_error_verbosity) */
479
459
  rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
480
460
 
481
- #ifdef HAVE_PQPING
482
461
  /****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
483
462
 
484
463
  /* Server is accepting connections. */
@@ -489,7 +468,6 @@ Init_pg_ext()
489
468
  rb_define_const(rb_mPGconstants, "PQPING_NO_RESPONSE", INT2FIX(PQPING_NO_RESPONSE));
490
469
  /* Connection not attempted (bad params). */
491
470
  rb_define_const(rb_mPGconstants, "PQPING_NO_ATTEMPT", INT2FIX(PQPING_NO_ATTEMPT));
492
- #endif
493
471
 
494
472
  /****** PG::Connection CLASS CONSTANTS: Large Objects ******/
495
473
 
@@ -524,13 +502,9 @@ Init_pg_ext()
524
502
  /* #result_status constant: A fatal error occurred. */
525
503
  rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
526
504
  /* #result_status constant: Copy In/Out data transfer in progress. */
527
- #ifdef HAVE_CONST_PGRES_COPY_BOTH
528
505
  rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
529
- #endif
530
506
  /* #result_status constant: Single tuple from larger resultset. */
531
- #ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
532
507
  rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
533
- #endif
534
508
 
535
509
  /****** Result CONSTANTS: result error field codes ******/
536
510
 
@@ -642,9 +616,7 @@ Init_pg_ext()
642
616
  /* Add the constants to the toplevel namespace */
643
617
  rb_include_module( rb_mPG, rb_mPGconstants );
644
618
 
645
- #ifdef M17N_SUPPORTED
646
619
  enc_pg2ruby = st_init_numtable();
647
- #endif
648
620
 
649
621
  /* Initialize the main extension classes */
650
622
  init_pg_connection();
@@ -663,5 +635,6 @@ Init_pg_ext()
663
635
  init_pg_binary_encoder();
664
636
  init_pg_binary_decoder();
665
637
  init_pg_copycoder();
638
+ init_pg_tuple();
666
639
  }
667
640
 
data/ext/pg.h CHANGED
@@ -18,89 +18,18 @@
18
18
 
19
19
  /* Ruby headers */
20
20
  #include "ruby.h"
21
- #ifdef HAVE_RUBY_ST_H
22
- # include "ruby/st.h"
23
- #elif HAVE_ST_H
24
- # include "st.h"
25
- #endif
21
+ #include "ruby/st.h"
22
+ #include "ruby/encoding.h"
26
23
 
27
- #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
28
- # include "ruby/encoding.h"
29
- # define M17N_SUPPORTED
30
- # ifdef HAVE_RB_ENCDB_ALIAS
31
- extern int rb_encdb_alias(const char *, const char *);
32
- # define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
33
- # elif HAVE_RB_ENC_ALIAS
34
- extern int rb_enc_alias(const char *, const char *);
35
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
36
- # else
37
- extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */
38
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
39
- # endif
40
-
41
-
42
- # if !defined(ENCODING_SET_INLINED)
43
- /* Rubinius doesn't define ENCODING_SET_INLINED, so we fall back to the more
44
- * portable version.
45
- */
46
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
47
- do { \
48
- rb_enc_set_index((obj), (i)); \
49
- } while(0)
50
- # else
51
- # define PG_ENCODING_SET_NOCHECK(obj,i) \
24
+ #define PG_ENCODING_SET_NOCHECK(obj,i) \
52
25
  do { \
53
26
  if ((i) < ENCODING_INLINE_MAX) \
54
27
  ENCODING_SET_INLINED((obj), (i)); \
55
28
  else \
56
29
  rb_enc_set_index((obj), (i)); \
57
30
  } while(0)
58
- # endif
59
-
60
- #else
61
- # define PG_ENCODING_SET_NOCHECK(obj,i) /* nothing */
62
- #endif
63
-
64
- #if RUBY_VM != 1
65
- # define RUBY_18_COMPAT
66
- #endif
67
-
68
- #ifndef RARRAY_LEN
69
- # define RARRAY_LEN(x) RARRAY((x))->len
70
- #endif /* RARRAY_LEN */
71
-
72
- #ifndef RSTRING_LEN
73
- # define RSTRING_LEN(x) RSTRING((x))->len
74
- #endif /* RSTRING_LEN */
75
-
76
- #ifndef RSTRING_PTR
77
- # define RSTRING_PTR(x) RSTRING((x))->ptr
78
- #endif /* RSTRING_PTR */
79
-
80
- #ifndef StringValuePtr
81
- # define StringValuePtr(x) STR2CSTR(x)
82
- #endif /* StringValuePtr */
83
-
84
- #ifdef RUBY_18_COMPAT
85
- # define rb_io_stdio_file GetWriteFile
86
- # include "rubyio.h"
87
- #else
88
- # include "ruby/io.h"
89
- #endif
90
-
91
- #ifdef RUBINIUS
92
- /* Workaround for wrong FIXNUM_MAX definition */
93
- typedef intptr_t native_int;
94
- #endif
95
31
 
96
- #ifndef RETURN_SIZED_ENUMERATOR
97
- #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) RETURN_ENUMERATOR((obj), (argc), (argv))
98
- #endif
99
-
100
- #ifndef HAVE_RB_HASH_DUP
101
- /* Rubinius doesn't define rb_hash_dup() */
102
- #define rb_hash_dup(tuple) rb_funcall((tuple), rb_intern("dup"), 0)
103
- #endif
32
+ #include "ruby/io.h"
104
33
 
105
34
  #ifndef timeradd
106
35
  #define timeradd(a, b, result) \
@@ -145,6 +74,10 @@ typedef long suseconds_t;
145
74
  #define PG_MAX_COLUMNS 4000
146
75
  #endif
147
76
 
77
+ #ifndef RARRAY_AREF
78
+ #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
79
+ #endif
80
+
148
81
  /* The data behind each PG::Connection object */
149
82
  typedef struct {
150
83
  PGconn *pgconn;
@@ -168,6 +101,13 @@ typedef struct {
168
101
  /* Kind of PG::Coder object for casting COPY rows to ruby values */
169
102
  VALUE decoder_for_get_copy_data;
170
103
 
104
+ /* enable/disable guessing size of PGresult's allocated memory */
105
+ int guess_result_memsize;
106
+
107
+ #if defined(_WIN32)
108
+ /* File descriptor to be used for rb_w32_unwrap_io_handle() */
109
+ int ruby_sd;
110
+ #endif
171
111
  } t_pg_connection;
172
112
 
173
113
  typedef struct pg_coder t_pg_coder;
@@ -198,9 +138,15 @@ typedef struct {
198
138
  */
199
139
  int nfields;
200
140
 
141
+ /* Size of PGresult as published to ruby memory management. */
142
+ ssize_t result_size;
143
+
201
144
  /* Prefilled tuple Hash with fnames[] as keys. */
202
145
  VALUE tuple_hash;
203
146
 
147
+ /* Hash with fnames[] to field number mapping. */
148
+ VALUE field_map;
149
+
204
150
  /* List of field names as frozen String objects.
205
151
  * Only valid if nfields != -1
206
152
  */
@@ -209,7 +155,7 @@ typedef struct {
209
155
 
210
156
 
211
157
  typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
212
- typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
158
+ typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, const char *, int, int, int, int);
213
159
  typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
214
160
  typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
215
161
  typedef int (* t_pg_fit_to_copy_get)(VALUE);
@@ -217,12 +163,23 @@ typedef VALUE (* t_pg_typecast_result)(t_typemap *, VALUE, int, int);
217
163
  typedef t_pg_coder *(* t_pg_typecast_query_param)(t_typemap *, VALUE, int);
218
164
  typedef VALUE (* t_pg_typecast_copy_get)( t_typemap *, VALUE, int, int, int );
219
165
 
166
+ #define PG_CODER_TIMESTAMP_DB_UTC 0x0
167
+ #define PG_CODER_TIMESTAMP_DB_LOCAL 0x1
168
+ #define PG_CODER_TIMESTAMP_APP_UTC 0x0
169
+ #define PG_CODER_TIMESTAMP_APP_LOCAL 0x2
170
+ #define PG_CODER_FORMAT_ERROR_MASK 0xc
171
+ #define PG_CODER_FORMAT_ERROR_TO_RAISE 0x4
172
+ #define PG_CODER_FORMAT_ERROR_TO_STRING 0x8
173
+ #define PG_CODER_FORMAT_ERROR_TO_PARTIAL 0xc
174
+
220
175
  struct pg_coder {
221
176
  t_pg_coder_enc_func enc_func;
222
177
  t_pg_coder_dec_func dec_func;
223
178
  VALUE coder_obj;
224
179
  Oid oid;
225
180
  int format;
181
+ /* OR-ed values out of PG_CODER_* */
182
+ int flags;
226
183
  };
227
184
 
228
185
  typedef struct {
@@ -259,6 +216,7 @@ typedef struct {
259
216
  * Globals
260
217
  **************************************************************************/
261
218
 
219
+ extern int pg_skip_deprecation_warning;
262
220
  extern VALUE rb_mPG;
263
221
  extern VALUE rb_ePGerror;
264
222
  extern VALUE rb_eServerError;
@@ -321,9 +279,10 @@ void init_pg_text_encoder _(( void ));
321
279
  void init_pg_text_decoder _(( void ));
322
280
  void init_pg_binary_encoder _(( void ));
323
281
  void init_pg_binary_decoder _(( void ));
282
+ void init_pg_tuple _(( void ));
324
283
  VALUE lookup_error_class _(( const char * ));
325
- VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
326
- VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
284
+ VALUE pg_bin_dec_bytea _(( t_pg_coder*, const char *, int, int, int, int ));
285
+ VALUE pg_text_dec_string _(( t_pg_coder*, const char *, int, int, int, int ));
327
286
  int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
328
287
  int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
329
288
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
@@ -366,6 +325,7 @@ VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
366
325
  PGresult* pgresult_get _(( VALUE ));
367
326
  VALUE pg_result_check _(( VALUE ));
368
327
  VALUE pg_result_clear _(( VALUE ));
328
+ VALUE pg_tuple_new _(( VALUE, int ));
369
329
 
370
330
  /*
371
331
  * Fetch the data pointer for the result object
@@ -373,7 +333,7 @@ VALUE pg_result_clear _(( VALUE ));
373
333
  static inline t_pg_result *
374
334
  pgresult_get_this( VALUE self )
375
335
  {
376
- t_pg_result *this = DATA_PTR(self);
336
+ t_pg_result *this = RTYPEDDATA_DATA(self);
377
337
 
378
338
  if( this == NULL )
379
339
  rb_raise(rb_ePGerror, "result has been cleared");
@@ -382,14 +342,24 @@ pgresult_get_this( VALUE self )
382
342
  }
383
343
 
384
344
 
385
- #ifdef M17N_SUPPORTED
386
345
  rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
387
346
  rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
388
347
  const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
389
348
  rb_encoding *pg_conn_enc_get _(( PGconn * ));
390
- #endif /* M17N_SUPPORTED */
391
349
 
392
350
  void notice_receiver_proxy(void *arg, const PGresult *result);
393
351
  void notice_processor_proxy(void *arg, const char *message);
394
352
 
353
+ /* reports if `-W' specified and PG_SKIP_DEPRECATION_WARNING environment variable isn't set
354
+ *
355
+ * message_id identifies the warning, so that it's reported only once.
356
+ */
357
+ #define pg_deprecated(message_id, format_args) \
358
+ do { \
359
+ if( !(pg_skip_deprecation_warning & (1 << message_id)) ){ \
360
+ pg_skip_deprecation_warning |= 1 << message_id; \
361
+ rb_warning format_args; \
362
+ } \
363
+ } while(0);
364
+
395
365
  #endif /* end __pg_h */