pg 0.18.0.pre20140820094244 → 0.18.0.pre20141017155815

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +1573 -2
  5. data/History.rdoc +3 -11
  6. data/Manifest.txt +24 -0
  7. data/README.rdoc +51 -4
  8. data/Rakefile +20 -14
  9. data/Rakefile.cross +39 -32
  10. data/ext/extconf.rb +27 -26
  11. data/ext/pg.c +75 -21
  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 +454 -0
  16. data/ext/pg_connection.c +815 -518
  17. data/ext/pg_copy_coder.c +557 -0
  18. data/ext/pg_result.c +258 -103
  19. data/ext/pg_text_decoder.c +424 -0
  20. data/ext/pg_text_encoder.c +608 -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 +121 -0
  27. data/ext/util.h +63 -0
  28. data/lib/pg.rb +11 -1
  29. data/lib/pg/basic_type_mapping.rb +377 -0
  30. data/lib/pg/coder.rb +74 -0
  31. data/lib/pg/connection.rb +38 -5
  32. data/lib/pg/result.rb +13 -3
  33. data/lib/pg/text_decoder.rb +42 -0
  34. data/lib/pg/text_encoder.rb +27 -0
  35. data/lib/pg/type_map_by_column.rb +15 -0
  36. data/spec/helpers.rb +9 -1
  37. data/spec/pg/basic_type_mapping_spec.rb +251 -0
  38. data/spec/pg/connection_spec.rb +232 -13
  39. data/spec/pg/result_spec.rb +52 -0
  40. data/spec/pg/type_map_by_column_spec.rb +135 -0
  41. data/spec/pg/type_map_by_mri_type_spec.rb +122 -0
  42. data/spec/pg/type_map_by_oid_spec.rb +133 -0
  43. data/spec/pg/type_map_spec.rb +39 -0
  44. data/spec/pg/type_spec.rb +620 -0
  45. metadata +40 -4
  46. metadata.gz.sig +0 -0
data/History.rdoc CHANGED
@@ -1,16 +1,8 @@
1
- == v0.18.0 [2014-08-20] Michael Granger <ged@FaerieMUD.org>
1
+ == v0.18.0 [unreleased]
2
2
 
3
- New:
4
-
5
- - Add PG::Connection#conninfo
6
- - Convert specs to expect syntax for RSpec 3
7
- - Check connection status with a matcher in specs
8
-
9
- Bugfixes:
10
-
11
- - Fix some type mismatches for Oid return values. Thanks to Mina Naguib for the fix.
12
- - Fix typo in documentation.
3
+ Enhancements:
13
4
 
5
+ - Add an extensible type cast system.
14
6
 
15
7
  == v0.17.1 [2013-12-18] Michael Granger <ged@FaerieMUD.org>
16
8
 
data/Manifest.txt CHANGED
@@ -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
@@ -52,6 +70,12 @@ sample/warehouse_partitions.rb
52
70
  spec/data/expected_trace.out
53
71
  spec/data/random_binary_data
54
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
data/README.rdoc CHANGED
@@ -9,7 +9,7 @@ docs :: http://deveiate.org/code/pg
9
9
 
10
10
  Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/].
11
11
 
12
- It works with {PostgreSQL 9.0 and later}[http://www.postgresql.org/support/versioning/].
12
+ It works with {PostgreSQL 8.4 and later}[http://www.postgresql.org/support/versioning/].
13
13
 
14
14
  A small example usage:
15
15
 
@@ -34,8 +34,8 @@ A small example usage:
34
34
 
35
35
  == Requirements
36
36
 
37
- * Ruby 1.9.3 or later.
38
- * PostgreSQL 9.0.x or later (with headers, -dev packages, etc).
37
+ * Ruby 1.9.3-p392, or 2.0.0-p0.
38
+ * PostgreSQL 8.4.x or later (with headers, -dev packages, etc).
39
39
 
40
40
  It may work with earlier versions of Ruby/PostgreSQL as well, but those are
41
41
  not regularly tested.
@@ -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,
@@ -83,7 +130,7 @@ Lars Kanis <lars@greiz-reinsdorf.de>.
83
130
 
84
131
  == Copying
85
132
 
86
- Copyright (c) 1997-2014 by the authors.
133
+ Copyright (c) 1997-2013 by the authors.
87
134
 
88
135
  * Jeff Davis <ruby-pg@j-davis.com>
89
136
  * Guy Decoux (ts) <decoux@moulon.inra.fr>
data/Rakefile CHANGED
@@ -29,10 +29,10 @@ TMPDIR = BASEDIR + 'tmp'
29
29
  DLEXT = RbConfig::CONFIG['DLEXT']
30
30
  EXT = LIBDIR + "pg_ext.#{DLEXT}"
31
31
 
32
- TEST_DIRECTORY = BASEDIR + "tmp_test_specs"
33
-
34
32
  GEMSPEC = 'pg.gemspec'
35
33
 
34
+ TEST_DIRECTORY = BASEDIR + "tmp_test_specs"
35
+
36
36
  CLOBBER.include( TEST_DIRECTORY.to_s )
37
37
  CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
38
38
 
@@ -69,7 +69,7 @@ $hoespec = Hoe.spec 'pg' do
69
69
  self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
70
70
  self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
71
71
 
72
- self.require_ruby_version( '>= 1.9.3' )
72
+ self.require_ruby_version( '>= 1.8.7' )
73
73
 
74
74
  self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
75
75
  self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
@@ -122,16 +122,23 @@ Rake::ExtensionTask.new do |ext|
122
122
  ext.cross_compile = true
123
123
  ext.cross_platform = CrossLibraries.map &:for_platform
124
124
 
125
- ext.cross_config_options += CrossLibraries.map do |lib|
126
- {
127
- lib.for_platform => [
128
- "--with-pg-include=#{lib.static_postgresql_libdir}",
129
- "--with-opt-include=#{lib.static_postgresql_incdir}",
130
- "--with-pg-lib=#{lib.static_postgresql_libdir}",
131
- "--with-opt-lib=#{lib.static_openssl_builddir}",
132
- ]
133
- }
134
- end
125
+ ext.cross_config_options += CrossLibraries.map do |lib|
126
+ {
127
+ lib.for_platform => [
128
+ "--enable-windows-cross",
129
+ "--with-pg-include=#{lib.static_postgresql_incdir}",
130
+ "--with-pg-lib=#{lib.static_postgresql_libdir}",
131
+ # libpq-fe.h resides in src/interfaces/libpq/ before make install
132
+ "--with-opt-include=#{lib.static_postgresql_libdir}",
133
+ ]
134
+ }
135
+ end
136
+
137
+ # Add libpq.dll to windows binary gemspec
138
+ ext.cross_compiling do |spec|
139
+ # mingw32-platform strings differ (RUBY_PLATFORM=i386-mingw32 vs. x86-mingw32 for rubygems)
140
+ spec.files << "lib/#{spec.platform.to_s.gsub(/^x86-/, "i386-")}/libpq.dll"
141
+ end
135
142
  end
136
143
 
137
144
 
@@ -183,7 +190,6 @@ file 'ext/pg_errors.c' => ['ext/errorcodes.def'] do
183
190
  touch 'ext/pg_errors.c'
184
191
  end
185
192
 
186
-
187
193
  task :gemspec => GEMSPEC
188
194
  file GEMSPEC => __FILE__
189
195
  task GEMSPEC do |task|
data/Rakefile.cross CHANGED
@@ -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,10 +199,9 @@ 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}"
@@ -217,31 +215,32 @@ class CrossLibrary < OpenStruct
217
215
  end
218
216
 
219
217
 
220
- # patch the Makefile.shlib -- depend on the build dir so it's only
221
- # rewritten if the tarball is re-extracted.
222
- file postgresql_shlib_makefile => postgresql_shlib_mf_orig do |t|
223
- tf = Tempfile.new( postgresql_shlib_makefile.basename.to_s )
224
- postgresql_shlib_mf_orig.open( File::RDONLY ) do |ifh|
225
- ifh.each_line do |line|
226
- tf.print( line.sub(/^(\s*haslibarule\s*=\s*yes)/, "# \\1 ") )
227
- 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'
228
225
  end
229
- tf.close
230
-
231
- FileUtils.mv( tf.path, t.name, :verbose => $puts )
232
226
  end
233
227
 
234
228
 
235
- # make libpq.a
236
- task postgresql_lib => [ postgresql_global_makefile, postgresql_shlib_makefile ] do |t|
237
- Dir.chdir( postgresql_lib.dirname ) do
238
- sh 'make', "-j#{NUM_CPUS}", postgresql_lib.basename.to_s, 'PORTNAME=win32'
239
- end
240
- end
229
+ #desc 'compile libpg.a'
230
+ task :libpq => postgresql_lib
241
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
242
238
 
243
- #desc 'compile static libpg.a'
244
- 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
245
244
  end
246
245
  end
247
246
 
@@ -258,10 +257,7 @@ else
258
257
  end
259
258
 
260
259
  desc 'cross compile pg for win32'
261
- task :cross do
262
- ENV['CROSS_COMPILING'] = 'yes'
263
- end
264
- task :cross => [ :mingw32, :static_libpq ]
260
+ task :cross => [ :mingw32, :libpq ]
265
261
 
266
262
  task :mingw32 do
267
263
  # Use Rake::ExtensionCompiler helpers to find the proper host
@@ -271,3 +267,14 @@ task :mingw32 do
271
267
  fail
272
268
  end
273
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
data/ext/extconf.rb CHANGED
@@ -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
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg.c - Toplevel extension
3
- * $Id: pg.c,v 8e95248e80f6 2014/08/20 16:42:14 ged $
3
+ * $Id: pg.c,v c2e817ef9b8c 2014/09/27 16:40:13 lars $
4
4
  *
5
5
  * Author/s:
6
6
  *
@@ -15,7 +15,7 @@
15
15
  * See Contributors.rdoc for the many additional fine people that have contributed
16
16
  * to this library over the years.
17
17
  *
18
- * Copyright (c) 1997-2014 by the authors.
18
+ * Copyright (c) 1997-2012 by the authors.
19
19
  *
20
20
  * You may redistribute this software under the same terms as Ruby itself; see
21
21
  * http://www.ruby-lang.org/en/LICENSE.txt or the LICENSE file in the source
@@ -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