pg 0.18.0.pre20140820094244 → 0.18.0.pre20141017155815
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +1573 -2
- data/History.rdoc +3 -11
- data/Manifest.txt +24 -0
- data/README.rdoc +51 -4
- data/Rakefile +20 -14
- data/Rakefile.cross +39 -32
- data/ext/extconf.rb +27 -26
- data/ext/pg.c +75 -21
- data/ext/pg.h +194 -6
- data/ext/pg_binary_decoder.c +160 -0
- data/ext/pg_binary_encoder.c +160 -0
- data/ext/pg_coder.c +454 -0
- data/ext/pg_connection.c +815 -518
- data/ext/pg_copy_coder.c +557 -0
- data/ext/pg_result.c +258 -103
- data/ext/pg_text_decoder.c +424 -0
- data/ext/pg_text_encoder.c +608 -0
- data/ext/pg_type_map.c +113 -0
- data/ext/pg_type_map_all_strings.c +113 -0
- data/ext/pg_type_map_by_column.c +254 -0
- data/ext/pg_type_map_by_mri_type.c +266 -0
- data/ext/pg_type_map_by_oid.c +341 -0
- data/ext/util.c +121 -0
- data/ext/util.h +63 -0
- data/lib/pg.rb +11 -1
- data/lib/pg/basic_type_mapping.rb +377 -0
- data/lib/pg/coder.rb +74 -0
- data/lib/pg/connection.rb +38 -5
- data/lib/pg/result.rb +13 -3
- data/lib/pg/text_decoder.rb +42 -0
- data/lib/pg/text_encoder.rb +27 -0
- data/lib/pg/type_map_by_column.rb +15 -0
- data/spec/helpers.rb +9 -1
- data/spec/pg/basic_type_mapping_spec.rb +251 -0
- data/spec/pg/connection_spec.rb +232 -13
- data/spec/pg/result_spec.rb +52 -0
- data/spec/pg/type_map_by_column_spec.rb +135 -0
- data/spec/pg/type_map_by_mri_type_spec.rb +122 -0
- data/spec/pg/type_map_by_oid_spec.rb +133 -0
- data/spec/pg/type_map_spec.rb +39 -0
- data/spec/pg/type_spec.rb +620 -0
- metadata +40 -4
- metadata.gz.sig +0 -0
data/History.rdoc
CHANGED
@@ -1,16 +1,8 @@
|
|
1
|
-
== v0.18.0 [
|
1
|
+
== v0.18.0 [unreleased]
|
2
2
|
|
3
|
-
|
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
|
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
|
38
|
-
* PostgreSQL
|
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-
|
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.
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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.
|
32
|
-
self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '9.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
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
|
-
#
|
236
|
-
task
|
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
|
-
|
244
|
-
|
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
|
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
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
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
|
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-
|
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
|
|