pg 0.18.4-x64-mingw32 → 0.19.0.pre20160817083826-x64-mingw32

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.tar.gz.sig +0 -0
  4. data/ChangeLog +686 -167
  5. data/History.rdoc +23 -0
  6. data/README.rdoc +6 -6
  7. data/Rakefile +10 -12
  8. data/Rakefile.cross +6 -6
  9. data/ext/errorcodes.def +16 -0
  10. data/ext/errorcodes.txt +5 -1
  11. data/ext/extconf.rb +9 -1
  12. data/ext/gvl_wrappers.h +4 -0
  13. data/ext/pg.c +1 -1
  14. data/ext/pg.h +6 -3
  15. data/ext/pg_binary_decoder.c +1 -1
  16. data/ext/pg_binary_encoder.c +8 -8
  17. data/ext/pg_coder.c +30 -9
  18. data/ext/pg_connection.c +203 -77
  19. data/ext/pg_copy_coder.c +34 -4
  20. data/ext/pg_result.c +2 -2
  21. data/ext/pg_text_decoder.c +1 -1
  22. data/ext/pg_text_encoder.c +62 -42
  23. data/ext/pg_type_map.c +1 -1
  24. data/ext/pg_type_map_all_strings.c +1 -1
  25. data/ext/pg_type_map_by_class.c +1 -1
  26. data/ext/pg_type_map_by_column.c +1 -1
  27. data/ext/pg_type_map_by_mri_type.c +1 -1
  28. data/ext/pg_type_map_by_oid.c +1 -1
  29. data/ext/pg_type_map_in_ruby.c +1 -1
  30. data/ext/util.c +1 -1
  31. data/lib/2.0/pg_ext.so +0 -0
  32. data/lib/2.1/pg_ext.so +0 -0
  33. data/lib/2.2/pg_ext.so +0 -0
  34. data/lib/2.3/pg_ext.so +0 -0
  35. data/lib/libpq.dll +0 -0
  36. data/lib/pg.rb +3 -3
  37. data/lib/pg/basic_type_mapping.rb +35 -8
  38. data/lib/pg/connection.rb +46 -6
  39. data/lib/pg/result.rb +6 -2
  40. data/lib/pg/text_decoder.rb +7 -0
  41. data/lib/pg/text_encoder.rb +8 -0
  42. data/sample/disk_usage_report.rb +1 -1
  43. data/sample/pg_statistics.rb +1 -1
  44. data/sample/replication_monitor.rb +1 -1
  45. data/spec/helpers.rb +6 -9
  46. data/spec/pg/basic_type_mapping_spec.rb +54 -0
  47. data/spec/pg/connection_spec.rb +130 -23
  48. data/spec/pg/type_map_by_class_spec.rb +1 -1
  49. data/spec/pg/type_map_by_mri_type_spec.rb +1 -1
  50. data/spec/pg/type_spec.rb +82 -2
  51. metadata +33 -35
  52. metadata.gz.sig +0 -0
  53. data/lib/x64-mingw32/libpq.dll +0 -0
@@ -1,3 +1,26 @@
1
+ == v0.19.0 [YYYY-MM-DD] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Deprecate Ruby 1.9
4
+
5
+ Enhancements:
6
+ - Respect and convert character encoding of all strings sent
7
+ to the server. #231
8
+ - Add PostgreSQL-9.5 functions PQsslInUse(), PQsslAttribute()
9
+ and PQsslAttributeNames().
10
+ - Various documentation fixes and improvements.
11
+ - Add mechanism to build without pg_config:
12
+ gem install pg -- --with-pg-config=ignore
13
+ - Update Windows binary gems to Ruby-2.3, PostgreSQL 9.5.4 and
14
+ OpenSSL 1.0.2f.
15
+ - Add JSON coders and add them to BasicTypeMapForResults and
16
+ BasicTypeMapBasedOnResult
17
+ - Allow build from git per bundler.
18
+
19
+ Bugfixes:
20
+ - Release GVL while calling PQsetClientEncoding(). #245
21
+ - Add __EXTENSIONS__ to Solaris/SmartOS for Ruby >= 2.3.x. #236
22
+
23
+
1
24
  == v0.18.4 [2015-11-13] Michael Granger <ged@FaerieMUD.org>
2
25
 
3
26
  Enhancements:
@@ -11,7 +11,7 @@ docs :: http://deveiate.org/code/pg
11
11
 
12
12
  Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/].
13
13
 
14
- It works with {PostgreSQL 8.4 and later}[http://www.postgresql.org/support/versioning/].
14
+ It works with {PostgreSQL 9.1 and later}[http://www.postgresql.org/support/versioning/].
15
15
 
16
16
  A small example usage:
17
17
 
@@ -23,7 +23,7 @@ A small example usage:
23
23
  conn = PG.connect( dbname: 'sales' )
24
24
  conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
25
25
  puts " PID | User | Query"
26
- result.each do |row|
26
+ result.each do |row|
27
27
  puts " %7d | %-16s | %s " %
28
28
  row.values_at('procpid', 'usename', 'current_query')
29
29
  end
@@ -37,10 +37,10 @@ A small example usage:
37
37
 
38
38
  == Requirements
39
39
 
40
- * Ruby 1.9.3-p392, or 2.0.0-p0.
41
- * PostgreSQL 8.4.x or later (with headers, -dev packages, etc).
40
+ * Ruby 2.2
41
+ * PostgreSQL 9.1.x or later (with headers, -dev packages, etc).
42
42
 
43
- It may work with earlier versions of Ruby/PostgreSQL as well, but those are
43
+ It usually work with earlier versions of Ruby/PostgreSQL as well, but those are
44
44
  not regularly tested.
45
45
 
46
46
 
@@ -112,7 +112,7 @@ needs for type casting. The default type map is PG::TypeMapAllStrings.
112
112
 
113
113
  A type map can be assigned per connection or per query respectively per
114
114
  result set. Type maps can also be used for COPY in and out data streaming.
115
-
115
+ See PG::Connection#copy_data .
116
116
 
117
117
  == Contributing
118
118
 
data/Rakefile CHANGED
@@ -55,22 +55,21 @@ $hoespec = Hoe.spec 'pg' do
55
55
  self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
56
56
  self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' )
57
57
  self.extra_rdoc_files.include( 'ext/*.c' )
58
- self.license :BSD
58
+ self.license 'BSD-3-Clause'
59
59
 
60
60
  self.developer 'Michael Granger', 'ged@FaerieMUD.org'
61
61
  self.developer 'Lars Kanis', 'lars@greiz-reinsdorf.de'
62
62
 
63
63
  self.dependency 'rake-compiler', '~> 0.9', :developer
64
- self.dependency 'rake-compiler-dock', '~> 0.3', :developer
64
+ self.dependency 'rake-compiler-dock', '~> 0.5', :developer
65
65
  self.dependency 'hoe', '~> 3.12', :developer
66
66
  self.dependency 'hoe-deveiate', '~> 0.6', :developer
67
67
  self.dependency 'hoe-bundler', '~> 1.0', :developer
68
68
  self.dependency 'rspec', '~> 3.0', :developer
69
69
 
70
- self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
71
70
  self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
72
71
 
73
- self.require_ruby_version( '>= 1.9.3' )
72
+ self.require_ruby_version( '>= 2.0.0' )
74
73
 
75
74
  self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
76
75
  self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
@@ -81,7 +80,7 @@ end
81
80
  ENV['VERSION'] ||= $hoespec.spec.version.to_s
82
81
 
83
82
  # Tests should pass before checking in
84
- task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
83
+ task 'hg:precheckin' => [ :check_history, :check_manifest, :spec, :gemspec ]
85
84
 
86
85
  # Support for 'rvm specs'
87
86
  task :specs => :spec
@@ -97,7 +96,7 @@ task :test do
97
96
  # the installed gem dir. So we clear the task rake-compiler set up
98
97
  # to break the dependency between :spec and :compile when running under
99
98
  # rubygems-test, and then run :spec.
100
- Rake::Task[ EXT.to_s ].clear
99
+ Rake::Task[ EXT.to_s ].clear if File.exist?(EXT.to_s)
101
100
  Rake::Task[ :spec ].execute
102
101
  end
103
102
 
@@ -132,8 +131,7 @@ Rake::ExtensionTask.new do |ext|
132
131
 
133
132
  # Add libpq.dll to windows binary gemspec
134
133
  ext.cross_compiling do |spec|
135
- # mingw32-platform strings differ (RUBY_PLATFORM=i386-mingw32 vs. x86-mingw32 for rubygems)
136
- spec.files << "lib/#{spec.platform.to_s.gsub(/^x86-/, "i386-")}/libpq.dll"
134
+ spec.files << "lib/libpq.dll"
137
135
  end
138
136
  end
139
137
 
@@ -191,9 +189,7 @@ task :update_error_codes do
191
189
 
192
190
  ERRORCODES_TXT = "ext/errorcodes.txt"
193
191
  sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
194
- end
195
192
 
196
- file 'ext/errorcodes.def' => ['ext/errorcodes.rb', 'ext/errorcodes.txt'] do
197
193
  ruby 'ext/errorcodes.rb', 'ext/errorcodes.txt', 'ext/errorcodes.def'
198
194
  end
199
195
 
@@ -207,12 +203,14 @@ file GEMSPEC => __FILE__
207
203
  task GEMSPEC do |task|
208
204
  spec = $hoespec.spec
209
205
  spec.files.delete( '.gemtest' )
210
- spec.version = "#{spec.version}.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
206
+ spec.signing_key = nil
207
+ spec.version = "#{spec.version.bump}.0.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
208
+ spec.cert_chain = [ 'certs/ged.pem' ]
211
209
  File.open( task.name, 'w' ) do |fh|
212
210
  fh.write( spec.to_ruby )
213
211
  end
214
212
  end
215
213
 
216
- CLOBBER.include( GEMSPEC.to_s )
214
+ CLOBBER.include( '*.gemspec' )
217
215
  task :default => :gemspec
218
216
 
@@ -29,8 +29,8 @@ class CrossLibrary < OpenStruct
29
29
  self.host_platform = toolchain
30
30
 
31
31
  # Cross-compilation constants
32
- self.openssl_version = ENV['OPENSSL_VERSION'] || '1.0.2d'
33
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '9.4.4'
32
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '1.0.2h'
33
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '9.5.4'
34
34
 
35
35
  # Check if symlinks work in the current working directory.
36
36
  # This fails, if rake-compiler-dock is running on a Windows box.
@@ -235,7 +235,7 @@ class CrossLibrary < OpenStruct
235
235
  task :libpq => postgresql_lib
236
236
 
237
237
  # copy libpq.dll to lib dir
238
- dest_libpq = "lib/#{for_platform}/#{postgresql_lib.basename}"
238
+ dest_libpq = "lib/#{postgresql_lib.basename}"
239
239
  directory File.dirname(dest_libpq)
240
240
  file dest_libpq => [postgresql_lib, File.dirname(dest_libpq)] do
241
241
  cp postgresql_lib, dest_libpq
@@ -290,12 +290,12 @@ task 'gem:windows' => ['ChangeLog'] do
290
290
 
291
291
  # Copy gem signing key and certs to be accessable from the docker container
292
292
  mkdir_p 'build/gem'
293
- sh "cp ~/.gem/gem-*.pem build/gem/"
293
+ sh "cp ~/.gem/gem-*.pem build/gem/ || true"
294
294
 
295
295
  RakeCompilerDock.sh <<-EOT
296
296
  mkdir ~/.gem &&
297
- cp build/gem/gem-*.pem ~/.gem/ &&
297
+ (cp build/gem/gem-*.pem ~/.gem/ || true) &&
298
298
  bundle install &&
299
- rake cross native gem RUBYOPT=--disable-rubygems RUBY_CC_VERSION=1.9.3:2.0.0:2.1.6:2.2.2
299
+ rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.6:2.0.0:1.9.3
300
300
  EOT
301
301
  end
@@ -198,6 +198,14 @@
198
198
  VALUE klass = define_error_class( "InvalidRowCountInResultOffsetClause", "22" );
199
199
  register_error_class( "2201X", klass );
200
200
  }
201
+ {
202
+ VALUE klass = define_error_class( "InvalidTablesampleArgument", "22" );
203
+ register_error_class( "2202H", klass );
204
+ }
205
+ {
206
+ VALUE klass = define_error_class( "InvalidTablesampleRepeat", "22" );
207
+ register_error_class( "2202G", klass );
208
+ }
201
209
  {
202
210
  VALUE klass = define_error_class( "InvalidTimeZoneDisplacementValue", "22" );
203
211
  register_error_class( "22009", klass );
@@ -466,6 +474,10 @@
466
474
  VALUE klass = define_error_class( "ERIESrfProtocolViolated", "39" );
467
475
  register_error_class( "39P02", klass );
468
476
  }
477
+ {
478
+ VALUE klass = define_error_class( "ERIEEventTriggerProtocolViolated", "39" );
479
+ register_error_class( "39P03", klass );
480
+ }
469
481
  {
470
482
  VALUE klass = define_error_class( "SavepointException", NULL );
471
483
  register_error_class( "3B000", klass );
@@ -916,6 +928,10 @@
916
928
  VALUE klass = define_error_class( "TooManyRows", "P0" );
917
929
  register_error_class( "P0003", klass );
918
930
  }
931
+ {
932
+ VALUE klass = define_error_class( "AssertFailure", "P0" );
933
+ register_error_class( "P0004", klass );
934
+ }
919
935
  {
920
936
  VALUE klass = define_error_class( "InternalError", NULL );
921
937
  register_error_class( "XX000", klass );
@@ -2,7 +2,7 @@
2
2
  # errcodes.txt
3
3
  # PostgreSQL error codes
4
4
  #
5
- # Copyright (c) 2003-2013, PostgreSQL Global Development Group
5
+ # Copyright (c) 2003-2016, PostgreSQL Global Development Group
6
6
  #
7
7
  # This list serves as the basis for generating source files containing error
8
8
  # codes. It is kept in a common format to make sure all these source files have
@@ -177,6 +177,8 @@ Section: Class 22 - Data Exception
177
177
  2201B E ERRCODE_INVALID_REGULAR_EXPRESSION invalid_regular_expression
178
178
  2201W E ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE invalid_row_count_in_limit_clause
179
179
  2201X E ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE invalid_row_count_in_result_offset_clause
180
+ 2202H E ERRCODE_INVALID_TABLESAMPLE_ARGUMENT invalid_tablesample_argument
181
+ 2202G E ERRCODE_INVALID_TABLESAMPLE_REPEAT invalid_tablesample_repeat
180
182
  22009 E ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE invalid_time_zone_displacement_value
181
183
  2200C E ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER invalid_use_of_escape_character
182
184
  2200G E ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH most_specific_type_mismatch
@@ -278,6 +280,7 @@ Section: Class 39 - External Routine Invocation Exception
278
280
  39004 E ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED null_value_not_allowed
279
281
  39P01 E ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED trigger_protocol_violated
280
282
  39P02 E ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED srf_protocol_violated
283
+ 39P03 E ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED event_trigger_protocol_violated
281
284
 
282
285
  Section: Class 3B - Savepoint Exception
283
286
 
@@ -454,6 +457,7 @@ P0000 E ERRCODE_PLPGSQL_ERROR plp
454
457
  P0001 E ERRCODE_RAISE_EXCEPTION raise_exception
455
458
  P0002 E ERRCODE_NO_DATA_FOUND no_data_found
456
459
  P0003 E ERRCODE_TOO_MANY_ROWS too_many_rows
460
+ P0004 E ERRCODE_ASSERT_FAILURE assert_failure
457
461
 
458
462
  Section: Class XX - Internal Error
459
463
 
@@ -24,7 +24,11 @@ if enable_config("windows-cross")
24
24
  else
25
25
  # Native build
26
26
 
27
- if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
27
+ pgconfig = with_config('pg-config') ||
28
+ with_config('pg_config') ||
29
+ find_executable('pg_config')
30
+
31
+ if pgconfig && pgconfig != 'ignore'
28
32
  $stderr.puts "Using config values from %s" % [ pgconfig ]
29
33
  incdir = `"#{pgconfig}" --includedir`.chomp
30
34
  libdir = `"#{pgconfig}" --libdir`.chomp
@@ -43,6 +47,9 @@ else
43
47
  end
44
48
  end
45
49
 
50
+ if RUBY_VERSION >= '2.3.0' && /solaris/ =~ RUBY_PLATFORM
51
+ append_cppflags( '-D__EXTENSIONS__' )
52
+ end
46
53
 
47
54
  find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
48
55
  find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
@@ -73,6 +80,7 @@ have_func 'PQlibVersion'
73
80
  have_func 'PQping'
74
81
  have_func 'PQsetSingleRowMode'
75
82
  have_func 'PQconninfo'
83
+ have_func 'PQsslAttribute'
76
84
 
77
85
  have_func 'rb_encdb_alias'
78
86
  have_func 'rb_enc_alias'
@@ -195,6 +195,9 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
195
195
  #define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
196
196
  param(PGconn *, conn)
197
197
 
198
+ #define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
199
+ param(PGconn *, conn)
200
+
198
201
  #define FOR_EACH_PARAM_OF_PQisBusy(param)
199
202
 
200
203
  #define FOR_EACH_PARAM_OF_PQcancel(param) \
@@ -226,6 +229,7 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
226
229
  function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
227
230
  function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
228
231
  function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
232
+ function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
229
233
  function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
230
234
  function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
231
235
 
data/ext/pg.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg.c - Toplevel extension
3
- * $Id: pg.c,v b60c89ee93c8 2015/02/11 20:59:36 lars $
3
+ * $Id$
4
4
  *
5
5
  * Author/s:
6
6
  *
data/ext/pg.h CHANGED
@@ -9,6 +9,9 @@
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 */
@@ -205,7 +208,7 @@ typedef struct {
205
208
  } t_pg_result;
206
209
 
207
210
 
208
- typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *);
211
+ typedef int (* t_pg_coder_enc_func)(t_pg_coder *, VALUE, char *, VALUE *, int);
209
212
  typedef VALUE (* t_pg_coder_dec_func)(t_pg_coder *, char *, int, int, int, int);
210
213
  typedef VALUE (* t_pg_fit_to_result)(VALUE, VALUE);
211
214
  typedef VALUE (* t_pg_fit_to_query)(VALUE, VALUE);
@@ -321,8 +324,8 @@ void init_pg_binary_decoder _(( void ));
321
324
  VALUE lookup_error_class _(( const char * ));
322
325
  VALUE pg_bin_dec_bytea _(( t_pg_coder*, char *, int, int, int, int ));
323
326
  VALUE pg_text_dec_string _(( t_pg_coder*, char *, int, int, int, int ));
324
- int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *));
325
- int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *));
327
+ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, char *, VALUE *, int));
328
+ int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
326
329
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
327
330
  t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
328
331
  void pg_define_coder _(( const char *, void *, VALUE, VALUE ));
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_decoder.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_binary_encoder.c,v 72168db5fb7b 2015/11/04 16:13:42 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -22,7 +22,7 @@ VALUE rb_mPG_BinaryEncoder;
22
22
  *
23
23
  */
24
24
  static int
25
- 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)
26
26
  {
27
27
  char mybool;
28
28
  switch(value){
@@ -44,7 +44,7 @@ pg_bin_enc_boolean(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate
44
44
  *
45
45
  */
46
46
  static int
47
- 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)
48
48
  {
49
49
  if(out){
50
50
  write_nbo16(NUM2INT(*intermediate), out);
@@ -63,7 +63,7 @@ pg_bin_enc_int2(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
63
63
  *
64
64
  */
65
65
  static int
66
- 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)
67
67
  {
68
68
  if(out){
69
69
  write_nbo32(NUM2LONG(*intermediate), out);
@@ -82,7 +82,7 @@ pg_bin_enc_int4(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
82
82
  *
83
83
  */
84
84
  static int
85
- 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)
86
86
  {
87
87
  if(out){
88
88
  write_nbo64(NUM2LL(*intermediate), out);
@@ -100,7 +100,7 @@ pg_bin_enc_int8(t_pg_coder *conv, VALUE value, char *out, VALUE *intermediate)
100
100
  *
101
101
  */
102
102
  static int
103
- 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)
104
104
  {
105
105
  int strlen;
106
106
  VALUE subint;
@@ -109,13 +109,13 @@ pg_bin_enc_from_base64(t_pg_coder *conv, VALUE value, char *out, VALUE *intermed
109
109
 
110
110
  if(out){
111
111
  /* Second encoder pass, if required */
112
- strlen = enc_func(this->elem, value, out, intermediate);
112
+ strlen = enc_func(this->elem, value, out, intermediate, enc_idx);
113
113
  strlen = base64_decode( out, out, strlen );
114
114
 
115
115
  return strlen;
116
116
  } else {
117
117
  /* First encoder pass */
118
- strlen = enc_func(this->elem, value, NULL, &subint);
118
+ strlen = enc_func(this->elem, value, NULL, &subint, enc_idx);
119
119
 
120
120
  if( strlen == -1 ){
121
121
  /* Encoded string is returned in subint */
@@ -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 */