pg 0.17.1-x64-mingw32 → 0.18.0.pre20141017160319-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +1885 -169
  5. data/History.rdoc +6 -0
  6. data/Manifest.txt +25 -1
  7. data/README.rdoc +47 -0
  8. data/Rakefile +21 -12
  9. data/Rakefile.cross +39 -33
  10. data/ext/extconf.rb +27 -26
  11. data/ext/pg.c +73 -19
  12. data/ext/pg.h +194 -6
  13. data/ext/pg_binary_decoder.c +160 -0
  14. data/ext/pg_binary_encoder.c +160 -0
  15. data/ext/pg_coder.c +473 -0
  16. data/ext/pg_connection.c +872 -534
  17. data/ext/pg_copy_coder.c +557 -0
  18. data/ext/pg_result.c +266 -111
  19. data/ext/pg_text_decoder.c +424 -0
  20. data/ext/pg_text_encoder.c +631 -0
  21. data/ext/pg_type_map.c +113 -0
  22. data/ext/pg_type_map_all_strings.c +113 -0
  23. data/ext/pg_type_map_by_column.c +254 -0
  24. data/ext/pg_type_map_by_mri_type.c +266 -0
  25. data/ext/pg_type_map_by_oid.c +341 -0
  26. data/ext/util.c +149 -0
  27. data/ext/util.h +65 -0
  28. data/lib/2.0/pg_ext.so +0 -0
  29. data/lib/2.1/pg_ext.so +0 -0
  30. data/lib/pg.rb +11 -1
  31. data/lib/pg/basic_type_mapping.rb +377 -0
  32. data/lib/pg/coder.rb +74 -0
  33. data/lib/pg/connection.rb +43 -1
  34. data/lib/pg/result.rb +13 -3
  35. data/lib/pg/text_decoder.rb +42 -0
  36. data/lib/pg/text_encoder.rb +27 -0
  37. data/lib/pg/type_map_by_column.rb +15 -0
  38. data/lib/x64-mingw32/libpq.dll +0 -0
  39. data/spec/{lib/helpers.rb → helpers.rb} +95 -35
  40. data/spec/pg/basic_type_mapping_spec.rb +251 -0
  41. data/spec/pg/connection_spec.rb +416 -214
  42. data/spec/pg/result_spec.rb +146 -116
  43. data/spec/pg/type_map_by_column_spec.rb +135 -0
  44. data/spec/pg/type_map_by_mri_type_spec.rb +122 -0
  45. data/spec/pg/type_map_by_oid_spec.rb +133 -0
  46. data/spec/pg/type_map_spec.rb +39 -0
  47. data/spec/pg/type_spec.rb +649 -0
  48. data/spec/pg_spec.rb +10 -18
  49. metadata +129 -50
  50. metadata.gz.sig +0 -0
@@ -1,3 +1,9 @@
1
+ == v0.18.0 [unreleased]
2
+
3
+ Enhancements:
4
+
5
+ - Add an extensible type cast system.
6
+
1
7
  == v0.17.1 [2013-12-18] Michael Granger <ged@FaerieMUD.org>
2
8
 
3
9
  Bugfixes:
@@ -20,17 +20,35 @@ ext/gvl_wrappers.c
20
20
  ext/gvl_wrappers.h
21
21
  ext/pg.c
22
22
  ext/pg.h
23
+ ext/pg_binary_decoder.c
24
+ ext/pg_binary_encoder.c
25
+ ext/pg_coder.c
23
26
  ext/pg_connection.c
27
+ ext/pg_copy_coder.c
24
28
  ext/pg_errors.c
25
29
  ext/pg_result.c
30
+ ext/pg_text_decoder.c
31
+ ext/pg_text_encoder.c
32
+ ext/pg_type_map_all_strings.c
33
+ ext/pg_type_map_by_column.c
34
+ ext/pg_type_map_by_mri_type.c
35
+ ext/pg_type_map_by_oid.c
36
+ ext/pg_type_map.c
37
+ ext/util.c
38
+ ext/util.h
26
39
  ext/vc/pg.sln
27
40
  ext/vc/pg_18/pg.vcproj
28
41
  ext/vc/pg_19/pg_19.vcproj
29
42
  lib/pg.rb
43
+ lib/pg/basic_type_mapping.rb
44
+ lib/pg/coder.rb
30
45
  lib/pg/connection.rb
31
46
  lib/pg/constants.rb
32
47
  lib/pg/exceptions.rb
33
48
  lib/pg/result.rb
49
+ lib/pg/text_decoder.rb
50
+ lib/pg/text_encoder.rb
51
+ lib/pg/type_map_by_column.rb
34
52
  sample/array_insert.rb
35
53
  sample/async_api.rb
36
54
  sample/async_copyto.rb
@@ -51,7 +69,13 @@ sample/wal_shipper.rb
51
69
  sample/warehouse_partitions.rb
52
70
  spec/data/expected_trace.out
53
71
  spec/data/random_binary_data
54
- spec/lib/helpers.rb
72
+ spec/helpers.rb
73
+ spec/pg/basic_type_mapping_spec.rb
55
74
  spec/pg/connection_spec.rb
56
75
  spec/pg/result_spec.rb
76
+ spec/pg/type_map_by_column_spec.rb
77
+ spec/pg/type_map_by_mri_type_spec.rb
78
+ spec/pg/type_map_by_oid_spec.rb
79
+ spec/pg/type_map_spec.rb
80
+ spec/pg/type_spec.rb
57
81
  spec/pg_spec.rb
@@ -64,6 +64,53 @@ There's also {a Google+ group}[http://goo.gl/TFy1U] and a
64
64
  want to chat about something.
65
65
 
66
66
 
67
+ == Type Casts
68
+
69
+ Pg can optionally type cast result values and query parameters in Ruby or
70
+ native C code. This can speed up data transfers to and from the database,
71
+ because String allocations are reduced and conversions in (slower) Ruby code
72
+ can be omitted.
73
+
74
+ Very basic type casting can be enabled by:
75
+
76
+ conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
77
+ # ... this works for result value mapping:
78
+ conn.exec("select 1, now(), '{2,3}'::int[]").values
79
+ # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]]
80
+
81
+ conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn
82
+ # ... and this for param value mapping:
83
+ conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values
84
+ # => [["1", "1.2300000000000000E+00", "{2,3}"]]
85
+
86
+ But Pg's type casting is highly customizable. That's why it's divided into
87
+ 2 layers:
88
+
89
+ === Encoders / Decoders (ext/pg_*coder.c, lib/pg/*coder.rb)
90
+
91
+ This is the lower layer, containing encoding classes that convert Ruby
92
+ objects for transmission to the DBMS and decoding classes to convert
93
+ received data back to Ruby objects. The classes are namespaced according
94
+ to their format and direction in PG::TextEncoder, PG::TextDecoder,
95
+ PG::BinaryEncoder and PG::BinaryDecoder.
96
+
97
+ It is possible to assign a type OID, format code (text or binary) and
98
+ optionally a name to an encoder or decoder object. It's also possible
99
+ to build composite types by assigning an element encoder/decoder.
100
+ PG::Coder objects can be used to set up a PG::TypeMap or alternatively
101
+ to convert single values to/from their string representation.
102
+
103
+ === PG::TypeMap and derivations (ext/pg_type_map*.c, lib/pg/type_map*.rb)
104
+
105
+ A TypeMap defines which value will be converted by which encoder/decoder.
106
+ There are different type map strategies, implemented by several derivations
107
+ of this class. They can be chosen and configured according to the particular
108
+ needs for type casting.
109
+
110
+ A type map can be assigned per connection or per query respectively per
111
+ result set. Type maps can also be used for COPY in and out data streaming.
112
+
113
+
67
114
  == Contributing
68
115
 
69
116
  To report bugs, suggest features, or check out the source with Mercurial,
data/Rakefile CHANGED
@@ -53,14 +53,16 @@ $hoespec = Hoe.spec 'pg' do
53
53
  self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
54
54
  self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' )
55
55
  self.extra_rdoc_files.include( 'ext/*.c' )
56
+ self.license :BSD
56
57
 
57
58
  self.developer 'Michael Granger', 'ged@FaerieMUD.org'
58
59
  self.developer 'Lars Kanis', 'lars@greiz-reinsdorf.de'
59
60
 
60
61
  self.dependency 'rake-compiler', '~> 0.9', :developer
61
- self.dependency 'hoe', '~> 3.5.1', :developer
62
- self.dependency 'hoe-deveiate', '~> 0.2', :developer
62
+ self.dependency 'hoe', '~> 3.12', :developer
63
+ self.dependency 'hoe-deveiate', '~> 0.6', :developer
63
64
  self.dependency 'hoe-bundler', '~> 1.0', :developer
65
+ self.dependency 'rspec', '~> 3.0', :developer
64
66
 
65
67
  self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
66
68
  self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
@@ -118,16 +120,23 @@ Rake::ExtensionTask.new do |ext|
118
120
  ext.cross_compile = true
119
121
  ext.cross_platform = CrossLibraries.map &:for_platform
120
122
 
121
- ext.cross_config_options += CrossLibraries.map do |lib|
122
- {
123
- lib.for_platform => [
124
- "--with-pg-include=#{lib.static_postgresql_libdir}",
125
- "--with-opt-include=#{lib.static_postgresql_incdir}",
126
- "--with-pg-lib=#{lib.static_postgresql_libdir}",
127
- "--with-opt-lib=#{lib.static_openssl_builddir}",
128
- ]
129
- }
130
- end
123
+ ext.cross_config_options += CrossLibraries.map do |lib|
124
+ {
125
+ lib.for_platform => [
126
+ "--enable-windows-cross",
127
+ "--with-pg-include=#{lib.static_postgresql_incdir}",
128
+ "--with-pg-lib=#{lib.static_postgresql_libdir}",
129
+ # libpq-fe.h resides in src/interfaces/libpq/ before make install
130
+ "--with-opt-include=#{lib.static_postgresql_libdir}",
131
+ ]
132
+ }
133
+ end
134
+
135
+ # Add libpq.dll to windows binary gemspec
136
+ ext.cross_compiling do |spec|
137
+ # mingw32-platform strings differ (RUBY_PLATFORM=i386-mingw32 vs. x86-mingw32 for rubygems)
138
+ spec.files << "lib/#{spec.platform.to_s.gsub(/^x86-/, "i386-")}/libpq.dll"
139
+ end
131
140
  end
132
141
 
133
142
 
@@ -28,8 +28,8 @@ class CrossLibrary < OpenStruct
28
28
  self.openssl_config = openssl_config
29
29
 
30
30
  # Cross-compilation constants
31
- self.openssl_version = ENV['OPENSSL_VERSION'] || '1.0.1e'
32
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '9.2.3'
31
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '1.0.1i'
32
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '9.3.5'
33
33
 
34
34
  self.compile_home = Pathname( "./build" ).expand_path
35
35
  self.static_sourcesdir = compile_home + 'sources'
@@ -64,7 +64,7 @@ class CrossLibrary < OpenStruct
64
64
  self.postgresql_global_makefile = static_postgresql_srcdir + 'Makefile.global'
65
65
  self.postgresql_shlib_makefile = static_postgresql_srcdir + 'Makefile.shlib'
66
66
  self.postgresql_shlib_mf_orig = static_postgresql_srcdir + 'Makefile.shlib.orig'
67
- self.postgresql_lib = static_postgresql_libdir + 'libpq.a'
67
+ self.postgresql_lib = static_postgresql_libdir + 'libpq.dll'
68
68
  self.postgresql_patches = Rake::FileList[ (MISCDIR + "postgresql-#{postgresql_version}.*.patch").to_s ]
69
69
 
70
70
  # Use rake-compilers config.yml to determine the toolchain that was used
@@ -82,7 +82,7 @@ class CrossLibrary < OpenStruct
82
82
  CLEAN.include( static_builddir.to_s )
83
83
 
84
84
 
85
- ENV['RUBY_CC_VERSION'] ||= '1.8.7:1.9.3:2.0.0'
85
+ ENV['RUBY_CC_VERSION'] ||= '1.9.3:2.0.0'
86
86
 
87
87
  def download(url, save_to)
88
88
  part = save_to+".part"
@@ -136,7 +136,7 @@ class CrossLibrary < OpenStruct
136
136
 
137
137
  # generate the makefile in a clean build location
138
138
  file openssl_makefile => static_openssl_builddir do |t|
139
- Dir.chdir( static_openssl_builddir ) do
139
+ chdir( static_openssl_builddir ) do
140
140
  cmd = cmd_prelude.dup
141
141
  cmd << "./Configure" << openssl_config
142
142
 
@@ -148,7 +148,7 @@ class CrossLibrary < OpenStruct
148
148
  task :openssl_libs => [ libssleay32, libeay32 ]
149
149
 
150
150
  task :compile_static_openssl => openssl_makefile do |t|
151
- Dir.chdir( static_openssl_builddir ) do
151
+ chdir( static_openssl_builddir ) do
152
152
  cmd = cmd_prelude.dup
153
153
  cmd << 'make' << "-j#{NUM_CPUS}" << 'build_libs'
154
154
 
@@ -184,7 +184,6 @@ class CrossLibrary < OpenStruct
184
184
  puts "extracting %s to %s" % [ postgresql_tarball, static_postgresql_builddir.parent ]
185
185
  static_postgresql_builddir.mkpath
186
186
  run 'tar', '-xjf', postgresql_tarball.to_s, '-C', static_postgresql_builddir.parent.to_s
187
- mv postgresql_shlib_makefile, postgresql_shlib_mf_orig
188
187
 
189
188
  postgresql_patches.each do |patchfile|
190
189
  puts " applying patch #{patchfile}..."
@@ -200,17 +199,15 @@ class CrossLibrary < OpenStruct
200
199
  "--host=#{host_platform}",
201
200
  '--with-openssl',
202
201
  '--without-zlib',
203
- '--disable-shared',
204
202
  ]
205
203
 
206
- Dir.chdir( static_postgresql_builddir ) do
204
+ chdir( static_postgresql_builddir ) do
207
205
  configure_path = static_postgresql_builddir + 'configure'
208
206
  cmd = [ configure_path.to_s, *options ]
209
207
  cmd << "CFLAGS=-L#{static_openssl_builddir}"
210
208
  cmd << "LDFLAGS=-L#{static_openssl_builddir}"
211
209
  cmd << "LDFLAGS_SL=-L#{static_openssl_builddir}"
212
210
  cmd << "LIBS=-lwsock32 -lgdi32"
213
- cmd << "DLLWRAP_FLAGS=-lcrypt32"
214
211
  cmd << "CPPFLAGS=-I#{static_openssl_builddir}/include"
215
212
 
216
213
  run( *cmd )
@@ -218,31 +215,32 @@ class CrossLibrary < OpenStruct
218
215
  end
219
216
 
220
217
 
221
- # patch the Makefile.shlib -- depend on the build dir so it's only
222
- # rewritten if the tarball is re-extracted.
223
- file postgresql_shlib_makefile => postgresql_shlib_mf_orig do |t|
224
- tf = Tempfile.new( postgresql_shlib_makefile.basename.to_s )
225
- postgresql_shlib_mf_orig.open( File::RDONLY ) do |ifh|
226
- ifh.each_line do |line|
227
- tf.print( line.sub(/^(\s*haslibarule\s*=\s*yes)/, "# \\1 ") )
228
- end
218
+ # make libpq.dll
219
+ task postgresql_lib => [ postgresql_global_makefile ] do |t|
220
+ chdir( postgresql_lib.dirname ) do
221
+ sh 'make',
222
+ "-j#{NUM_CPUS}",
223
+ postgresql_lib.basename.to_s,
224
+ 'SHLIB_LINK=-lssleay32 -leay32 -lcrypt32 -lgdi32 -lsecur32 -lwsock32 -lws2_32'
229
225
  end
230
- tf.close
231
-
232
- FileUtils.mv( tf.path, t.name, :verbose => $puts )
233
226
  end
234
227
 
235
228
 
236
- # make libpq.a
237
- task postgresql_lib => [ postgresql_global_makefile, postgresql_shlib_makefile ] do |t|
238
- Dir.chdir( postgresql_lib.dirname ) do
239
- sh 'make', "-j#{NUM_CPUS}", postgresql_lib.basename.to_s, 'PORTNAME=win32'
240
- end
241
- end
229
+ #desc 'compile libpg.a'
230
+ task :libpq => postgresql_lib
242
231
 
232
+ # copy libpq.dll to lib dir
233
+ dest_libpq = "lib/#{for_platform}/#{postgresql_lib.basename}"
234
+ directory File.dirname(dest_libpq)
235
+ file dest_libpq => [postgresql_lib, File.dirname(dest_libpq)] do
236
+ cp postgresql_lib, dest_libpq
237
+ end
243
238
 
244
- #desc 'compile static libpg.a'
245
- task :static_libpq => postgresql_lib
239
+ stage_libpq = "tmp/#{for_platform}/stage/#{dest_libpq}"
240
+ directory File.dirname(stage_libpq)
241
+ file stage_libpq => [postgresql_lib, File.dirname(stage_libpq)] do |t|
242
+ cp postgresql_lib, stage_libpq
243
+ end
246
244
  end
247
245
  end
248
246
 
@@ -259,10 +257,7 @@ else
259
257
  end
260
258
 
261
259
  desc 'cross compile pg for win32'
262
- task :cross do
263
- ENV['CROSS_COMPILING'] = 'yes'
264
- end
265
- task :cross => [ :mingw32, :static_libpq ]
260
+ task :cross => [ :mingw32, :libpq ]
266
261
 
267
262
  task :mingw32 do
268
263
  # Use Rake::ExtensionCompiler helpers to find the proper host
@@ -272,3 +267,14 @@ task :mingw32 do
272
267
  fail
273
268
  end
274
269
  end
270
+
271
+ # To reduce the gem file size strip mingw32 dlls before packaging
272
+ ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
273
+ task "tmp/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/pg_ext.so" do |t|
274
+ sh "i686-w64-mingw32-strip -S tmp/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/pg_ext.so"
275
+ end
276
+
277
+ task "tmp/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/pg_ext.so" do |t|
278
+ sh "x86_64-w64-mingw32-strip -S tmp/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/pg_ext.so"
279
+ end
280
+ end
@@ -15,36 +15,35 @@ if pgdir = with_config( 'pg' )
15
15
  ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
16
16
  end
17
17
 
18
- if ENV['CROSS_COMPILING']
19
- $LDFLAGS << " -L#{CONFIG['libdir']}"
20
-
21
- # Link against all required libraries for static build, if they are available
22
- have_library( 'crypt32', 'CertOpenStore' ) && append_library( $libs, 'crypt32' )
23
- have_library( 'gdi32', 'CreateDC' ) && append_library( $libs, 'gdi32' )
24
- have_library( 'secur32' ) && append_library( $libs, 'secur32' )
25
- have_library( 'ws2_32', 'WSASocket') && append_library( $libs, 'ws2_32' )
26
- have_library( 'crypto', 'BIO_new' ) && append_library( $libs, 'crypto' )
27
- have_library( 'ssl', 'SSL_new' ) && append_library( $libs, 'ssl' )
28
- end
18
+ if enable_config("windows-cross")
19
+ # Avoid dependency to external libgcc.dll on x86-mingw32
20
+ $LDFLAGS << " -static-libgcc"
21
+ # Don't use pg_config for cross build, but --with-pg-* path options
22
+ dir_config 'pg'
29
23
 
30
- if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
31
- $stderr.puts "Using config values from %s" % [ pgconfig ]
32
- incdir = `"#{pgconfig}" --includedir`.chomp
33
- libdir = `"#{pgconfig}" --libdir`.chomp
34
- dir_config 'pg', incdir, libdir
35
-
36
- # Try to use runtime path linker option, even if RbConfig doesn't know about it.
37
- # The rpath option is usually set implicit by dir_config(), but so far not
38
- # on MacOS-X.
39
- if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', " -Wl,-rpath,#{libdir}")
40
- $LDFLAGS << " -Wl,-rpath,#{libdir}"
41
- end
42
24
  else
43
- $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
44
- " --with-pg-config=/path/to/pg_config"
45
- dir_config 'pg'
25
+ # Native build
26
+
27
+ if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
28
+ $stderr.puts "Using config values from %s" % [ pgconfig ]
29
+ incdir = `"#{pgconfig}" --includedir`.chomp
30
+ libdir = `"#{pgconfig}" --libdir`.chomp
31
+ dir_config 'pg', incdir, libdir
32
+
33
+ # Try to use runtime path linker option, even if RbConfig doesn't know about it.
34
+ # The rpath option is usually set implicit by dir_config(), but so far not
35
+ # on MacOS-X.
36
+ if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', " -Wl,-rpath,#{libdir}")
37
+ $LDFLAGS << " -Wl,-rpath,#{libdir}"
38
+ end
39
+ else
40
+ $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
41
+ " --with-pg-config=/path/to/pg_config"
42
+ dir_config 'pg'
43
+ end
46
44
  end
47
45
 
46
+
48
47
  find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
49
48
  find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
50
49
  find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
@@ -73,6 +72,7 @@ have_func 'PQsetClientEncoding'
73
72
  have_func 'PQlibVersion'
74
73
  have_func 'PQping'
75
74
  have_func 'PQsetSingleRowMode'
75
+ have_func 'PQconninfo'
76
76
 
77
77
  have_func 'rb_encdb_alias'
78
78
  have_func 'rb_enc_alias'
@@ -80,6 +80,7 @@ have_func 'rb_thread_call_without_gvl'
80
80
  have_func 'rb_thread_call_with_gvl'
81
81
  have_func 'rb_thread_fd_select'
82
82
  have_func 'rb_w32_wrap_io_handle'
83
+ have_func 'rb_str_modify_expand'
83
84
 
84
85
  have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
85
86
  have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
data/ext/pg.c CHANGED
@@ -123,24 +123,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
123
123
  * A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s.
124
124
  */
125
125
  static struct st_table *enc_pg2ruby;
126
- static ID s_id_index;
127
-
128
-
129
- /*
130
- * Get the index of encoding +val+.
131
- * :FIXME: Look into replacing this with rb_enc_get_index() since 1.9.1 isn't really
132
- * used anymore.
133
- */
134
- int
135
- pg_enc_get_index(VALUE val)
136
- {
137
- int i = ENCODING_GET_INLINED(val);
138
- if (i == ENCODING_INLINE_MAX) {
139
- VALUE iv = rb_ivar_get(val, s_id_index);
140
- i = NUM2INT(iv);
141
- }
142
- return i;
143
- }
144
126
 
145
127
 
146
128
  /*
@@ -249,6 +231,68 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
249
231
  #endif /* M17N_SUPPORTED */
250
232
 
251
233
 
234
+ /*
235
+ * Ensures that the given string has enough capacity to take expand_len
236
+ * more data bytes. The new data part of the String is not initialized.
237
+ *
238
+ * current_out must be a pointer within the data part of the String object.
239
+ * This pointer is returned and possibly adjusted, because the location of the data
240
+ * part of the String can change through this function.
241
+ *
242
+ * PG_RB_STR_ENSURE_CAPA can be used to do fast inline checks of the remaining capacity.
243
+ * end_capa it is then set to the first byte after the currently reserved memory,
244
+ * if not NULL.
245
+ *
246
+ * Before the String can be used with other string functions or returned to Ruby space,
247
+ * the string length has to be set with rb_str_set_len().
248
+ *
249
+ * Usage example:
250
+ *
251
+ * VALUE string;
252
+ * char *current_out, *end_capa;
253
+ * PG_RB_STR_NEW( string, current_out, end_capa );
254
+ * while( data_is_going_to_be_processed ){
255
+ * PG_RB_STR_ENSURE_CAPA( string, 2 current_out, end_capa );
256
+ * *current_out++ = databyte1;
257
+ * *current_out++ = databyte2;
258
+ * }
259
+ * rb_str_set_len( string, current_out - RSTRING_PTR(string) );
260
+ *
261
+ */
262
+ #ifdef HAVE_RB_STR_MODIFY_EXPAND
263
+ /* Use somewhat faster version with access to string capacity on MRI */
264
+ char *
265
+ pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
266
+ {
267
+ long curr_len = curr_ptr - RSTRING_PTR(str);
268
+ long curr_capa = rb_str_capacity( str );
269
+ if( curr_capa < curr_len + expand_len ){
270
+ rb_str_set_len( str, curr_len );
271
+ rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
272
+ curr_ptr = RSTRING_PTR(str) + curr_len;
273
+ }
274
+ if( end_ptr )
275
+ *end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
276
+ return curr_ptr;
277
+ }
278
+ #else
279
+ /* Use the more portable version */
280
+ char *
281
+ pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
282
+ {
283
+ long curr_len = curr_ptr - RSTRING_PTR(str);
284
+ long curr_capa = RSTRING_LEN( str );
285
+ if( curr_capa < curr_len + expand_len ){
286
+ rb_str_resize( str, (curr_len + expand_len) * 2 - curr_capa );
287
+ curr_ptr = RSTRING_PTR(str) + curr_len;
288
+ }
289
+ if( end_ptr )
290
+ *end_ptr = RSTRING_PTR(str) + RSTRING_LEN(str);
291
+ return curr_ptr;
292
+ }
293
+ #endif
294
+
295
+
252
296
  /**************************************************************************
253
297
  * Module Methods
254
298
  **************************************************************************/
@@ -534,12 +578,22 @@ Init_pg_ext()
534
578
 
535
579
  #ifdef M17N_SUPPORTED
536
580
  enc_pg2ruby = st_init_numtable();
537
- s_id_index = rb_intern("@encoding");
538
581
  #endif
539
582
 
540
583
  /* Initialize the main extension classes */
541
584
  init_pg_connection();
542
585
  init_pg_result();
543
586
  init_pg_errors();
587
+ init_pg_type_map();
588
+ init_pg_type_map_all_strings();
589
+ init_pg_type_map_by_column();
590
+ init_pg_type_map_by_mri_type();
591
+ init_pg_type_map_by_oid();
592
+ init_pg_coder();
593
+ init_pg_text_encoder();
594
+ init_pg_text_decoder();
595
+ init_pg_binary_encoder();
596
+ init_pg_binary_decoder();
597
+ init_pg_copycoder();
544
598
  }
545
599