pg 1.2.3 → 1.6.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +986 -0
- data/Gemfile +23 -0
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +300 -0
- data/README.md +327 -0
- data/Rakefile +123 -144
- data/certs/ged.pem +24 -0
- data/certs/kanis@comcard.de.pem +20 -0
- data/certs/larskanis-2022.pem +26 -0
- data/certs/larskanis-2023.pem +24 -0
- data/certs/larskanis-2024.pem +24 -0
- data/ext/errorcodes.def +16 -5
- data/ext/errorcodes.rb +0 -0
- data/ext/errorcodes.txt +5 -5
- data/ext/extconf.rb +259 -33
- data/ext/gvl_wrappers.c +17 -2
- data/ext/gvl_wrappers.h +56 -0
- data/ext/pg.c +89 -63
- data/ext/pg.h +31 -8
- data/ext/pg_binary_decoder.c +232 -1
- data/ext/pg_binary_encoder.c +428 -1
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +148 -36
- data/ext/pg_connection.c +1365 -817
- data/ext/pg_copy_coder.c +360 -38
- data/ext/pg_errors.c +1 -1
- data/ext/pg_record_coder.c +56 -25
- data/ext/pg_result.c +187 -76
- data/ext/pg_text_decoder.c +32 -11
- data/ext/pg_text_encoder.c +65 -33
- data/ext/pg_tuple.c +84 -61
- data/ext/pg_type_map.c +44 -10
- data/ext/pg_type_map_all_strings.c +17 -3
- data/ext/pg_type_map_by_class.c +54 -27
- data/ext/pg_type_map_by_column.c +74 -31
- data/ext/pg_type_map_by_mri_type.c +48 -19
- data/ext/pg_type_map_by_oid.c +61 -27
- data/ext/pg_type_map_in_ruby.c +55 -21
- data/ext/pg_util.c +2 -2
- data/lib/pg/basic_type_map_based_on_result.rb +67 -0
- data/lib/pg/basic_type_map_for_queries.rb +206 -0
- data/lib/pg/basic_type_map_for_results.rb +104 -0
- data/lib/pg/basic_type_registry.rb +311 -0
- data/lib/pg/binary_decoder/date.rb +9 -0
- data/lib/pg/binary_decoder/timestamp.rb +26 -0
- data/lib/pg/binary_encoder/timestamp.rb +20 -0
- data/lib/pg/cancel_connection.rb +53 -0
- data/lib/pg/coder.rb +18 -14
- data/lib/pg/connection.rb +894 -91
- data/lib/pg/exceptions.rb +20 -1
- data/lib/pg/text_decoder/date.rb +21 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +17 -0
- data/lib/pg/text_decoder/numeric.rb +9 -0
- data/lib/pg/text_decoder/timestamp.rb +30 -0
- data/lib/pg/text_encoder/date.rb +13 -0
- data/lib/pg/text_encoder/inet.rb +31 -0
- data/lib/pg/text_encoder/json.rb +17 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- data/lib/pg/version.rb +4 -0
- data/lib/pg.rb +109 -39
- data/misc/openssl-pg-segfault.rb +31 -0
- data/misc/postgres/History.txt +9 -0
- data/misc/postgres/Manifest.txt +5 -0
- data/misc/postgres/README.txt +21 -0
- data/misc/postgres/Rakefile +21 -0
- data/misc/postgres/lib/postgres.rb +16 -0
- data/misc/ruby-pg/History.txt +9 -0
- data/misc/ruby-pg/Manifest.txt +5 -0
- data/misc/ruby-pg/README.txt +21 -0
- data/misc/ruby-pg/Rakefile +21 -0
- data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
- data/misc/yugabyte/Dockerfile +9 -0
- data/misc/yugabyte/docker-compose.yml +28 -0
- data/misc/yugabyte/pg-test.rb +45 -0
- data/pg.gemspec +38 -0
- data/ports/patches/krb5/1.21.3/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/openssl/3.5.1/0001-aarch64-mingw.patch +21 -0
- data/ports/patches/postgresql/17.5/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/ports/patches/postgresql/17.5/0001-libpq-Process-buffered-SSL-read-bytes-to-support-rec.patch +52 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data/rakelib/task_extension.rb +46 -0
- data/sample/array_insert.rb +20 -0
- data/sample/async_api.rb +102 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/async_mixed.rb +56 -0
- data/sample/check_conn.rb +21 -0
- data/sample/copydata.rb +71 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/disk_usage_report.rb +177 -0
- data/sample/issue-119.rb +94 -0
- data/sample/losample.rb +69 -0
- data/sample/minimal-testcase.rb +17 -0
- data/sample/notify_wait.rb +72 -0
- data/sample/pg_statistics.rb +285 -0
- data/sample/replication_monitor.rb +222 -0
- data/sample/test_binary_values.rb +33 -0
- data/sample/wal_shipper.rb +434 -0
- data/sample/warehouse_partitions.rb +311 -0
- data.tar.gz.sig +0 -0
- metadata +139 -213
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/ChangeLog +0 -0
- data/History.rdoc +0 -578
- data/Manifest.txt +0 -73
- data/README.ja.rdoc +0 -13
- data/README.rdoc +0 -213
- data/Rakefile.cross +0 -299
- data/lib/pg/basic_type_mapping.rb +0 -522
- data/lib/pg/binary_decoder.rb +0 -23
- data/lib/pg/constants.rb +0 -12
- data/lib/pg/text_decoder.rb +0 -46
- data/lib/pg/text_encoder.rb +0 -59
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
- data/spec/helpers.rb +0 -380
- data/spec/pg/basic_type_mapping_spec.rb +0 -630
- data/spec/pg/connection_spec.rb +0 -1949
- data/spec/pg/connection_sync_spec.rb +0 -41
- data/spec/pg/result_spec.rb +0 -681
- data/spec/pg/tuple_spec.rb +0 -333
- data/spec/pg/type_map_by_class_spec.rb +0 -138
- data/spec/pg/type_map_by_column_spec.rb +0 -226
- data/spec/pg/type_map_by_mri_type_spec.rb +0 -136
- data/spec/pg/type_map_by_oid_spec.rb +0 -149
- data/spec/pg/type_map_in_ruby_spec.rb +0 -164
- data/spec/pg/type_map_spec.rb +0 -22
- data/spec/pg/type_spec.rb +0 -1123
- data/spec/pg_spec.rb +0 -50
data/ext/extconf.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'pp'
|
2
2
|
require 'mkmf'
|
3
3
|
|
4
|
-
|
5
4
|
if ENV['MAINTAINER_MODE']
|
6
5
|
$stderr.puts "Maintainer mode enabled."
|
7
6
|
$CFLAGS <<
|
@@ -9,18 +8,178 @@ if ENV['MAINTAINER_MODE']
|
|
9
8
|
' -ggdb' <<
|
10
9
|
' -DDEBUG' <<
|
11
10
|
' -pedantic'
|
11
|
+
$LDFLAGS <<
|
12
|
+
' -ggdb'
|
12
13
|
end
|
13
14
|
|
14
15
|
if pgdir = with_config( 'pg' )
|
15
16
|
ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
|
16
17
|
end
|
17
18
|
|
18
|
-
if enable_config("
|
19
|
+
if enable_config("gvl-unlock", true)
|
20
|
+
$defs.push( "-DENABLE_GVL_UNLOCK" )
|
21
|
+
$stderr.puts "Calling libpq with GVL unlocked"
|
22
|
+
else
|
23
|
+
$stderr.puts "Calling libpq with GVL locked"
|
24
|
+
end
|
25
|
+
|
26
|
+
if gem_platform=with_config("cross-build")
|
27
|
+
gem 'mini_portile2', '~>2.1'
|
28
|
+
require 'mini_portile2'
|
29
|
+
|
30
|
+
OPENSSL_VERSION = ENV['OPENSSL_VERSION'] || '3.5.1'
|
31
|
+
OPENSSL_SOURCE_URI = "http://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
|
32
|
+
|
33
|
+
KRB5_VERSION = ENV['KRB5_VERSION'] || '1.21.3'
|
34
|
+
KRB5_SOURCE_URI = "http://kerberos.org/dist/krb5/#{KRB5_VERSION[/^(\d+\.\d+)/]}/krb5-#{KRB5_VERSION}.tar.gz"
|
35
|
+
|
36
|
+
POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '17.5'
|
37
|
+
POSTGRESQL_SOURCE_URI = "http://ftp.postgresql.org/pub/source/v#{POSTGRESQL_VERSION}/postgresql-#{POSTGRESQL_VERSION}.tar.bz2"
|
38
|
+
|
39
|
+
class BuildRecipe < MiniPortile
|
40
|
+
def initialize(name, version, files)
|
41
|
+
super(name, version)
|
42
|
+
self.files = files
|
43
|
+
rootdir = File.expand_path('../..', __FILE__)
|
44
|
+
self.target = File.join(rootdir, "ports")
|
45
|
+
self.patch_files = Dir[File.join(target, "patches", self.name, self.version, "*.patch")].sort
|
46
|
+
end
|
47
|
+
|
48
|
+
def port_path
|
49
|
+
"#{target}/#{RUBY_PLATFORM}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def cook_and_activate
|
53
|
+
checkpoint = File.join(self.target, "#{self.name}-#{self.version}-#{RUBY_PLATFORM}.installed")
|
54
|
+
unless File.exist?(checkpoint)
|
55
|
+
self.cook
|
56
|
+
FileUtils.touch checkpoint
|
57
|
+
end
|
58
|
+
self.activate
|
59
|
+
self
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
openssl_platform = with_config("openssl-platform")
|
64
|
+
toolchain = with_config("toolchain")
|
65
|
+
|
66
|
+
openssl_recipe = BuildRecipe.new("openssl", OPENSSL_VERSION, [OPENSSL_SOURCE_URI]).tap do |recipe|
|
67
|
+
class << recipe
|
68
|
+
attr_accessor :openssl_platform
|
69
|
+
def configure
|
70
|
+
envs = []
|
71
|
+
envs << "CFLAGS=-DDSO_WIN32 -DOPENSSL_THREADS" if RUBY_PLATFORM =~ /mingw|mswin/
|
72
|
+
envs << "CFLAGS=-fPIC -DOPENSSL_THREADS" if RUBY_PLATFORM =~ /linux|darwin/
|
73
|
+
execute('configure', ['env', *envs, "./Configure", openssl_platform, "threads", "-static", "CROSS_COMPILE=#{host}-", configure_prefix], altlog: "config.log")
|
74
|
+
end
|
75
|
+
def compile
|
76
|
+
execute('compile', "#{make_cmd} build_libs")
|
77
|
+
end
|
78
|
+
def install
|
79
|
+
execute('install', "#{make_cmd} install_dev")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
recipe.openssl_platform = openssl_platform
|
84
|
+
recipe.host = toolchain
|
85
|
+
recipe.cook_and_activate
|
86
|
+
end
|
87
|
+
|
88
|
+
if RUBY_PLATFORM =~ /linux|darwin/
|
89
|
+
krb5_recipe = BuildRecipe.new("krb5", KRB5_VERSION, [KRB5_SOURCE_URI]).tap do |recipe|
|
90
|
+
class << recipe
|
91
|
+
def work_path
|
92
|
+
File.join(super, "src")
|
93
|
+
end
|
94
|
+
def configure
|
95
|
+
if RUBY_PLATFORM=~/darwin/
|
96
|
+
ENV["CC"] = host[/^.*[^\.\d]/] + "-clang"
|
97
|
+
ENV["CXX"] = host[/^.*[^\.\d]/] + "-c++"
|
98
|
+
|
99
|
+
# Manually set the correct values for configure checks that libkrb5 won't be
|
100
|
+
# able to perform because we're cross-compiling.
|
101
|
+
ENV["krb5_cv_attr_constructor_destructor"] = "yes"
|
102
|
+
ENV["ac_cv_func_regcomp"] = "yes"
|
103
|
+
ENV["ac_cv_printf_positional"] = "yes"
|
104
|
+
end
|
105
|
+
super
|
106
|
+
end
|
107
|
+
end
|
108
|
+
# We specify -fcommon to get around duplicate definition errors in recent gcc.
|
109
|
+
# See https://github.com/cockroachdb/cockroach/issues/49734
|
110
|
+
recipe.configure_options << "CFLAGS=-fcommon#{" -fPIC" if RUBY_PLATFORM =~ /linux/}"
|
111
|
+
recipe.configure_options << "LDFLAGS=-framework Kerberos" if RUBY_PLATFORM =~ /darwin/
|
112
|
+
recipe.configure_options << "--without-keyutils"
|
113
|
+
recipe.configure_options << "--disable-nls"
|
114
|
+
recipe.configure_options << "--disable-silent-rules"
|
115
|
+
recipe.configure_options << "--without-system-verto"
|
116
|
+
recipe.configure_options << "krb5_cv_attr_constructor_destructor=yes"
|
117
|
+
recipe.configure_options << "ac_cv_func_regcomp=yes"
|
118
|
+
recipe.configure_options << "ac_cv_printf_positional=yes"
|
119
|
+
recipe.host = toolchain
|
120
|
+
recipe.cook_and_activate
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# We build a libpq library file which static links OpenSSL and krb5.
|
125
|
+
# Our builtin libpq is referenced in different ways depending on the OS:
|
126
|
+
# - Window: Add the ports directory at runtime per RubyInstaller::Runtime.add_dll_directory
|
127
|
+
# The file is called "libpq.dll"
|
128
|
+
# - Linux: Add a rpath to pg_ext.so which references the ports directory.
|
129
|
+
# The file is called "libpq-ruby-pg.so.1" to avoid loading of system libpq by accident.
|
130
|
+
# - Macos: Add a reference with relative path in pg_ext.so to the ports directory.
|
131
|
+
# The file is called "libpq-ruby-pg.1.dylib" to avoid loading of other libpq by accident.
|
132
|
+
libpq_orig, libpq_rubypg = case RUBY_PLATFORM
|
133
|
+
when /linux/ then ["libpq.so.5", "libpq-ruby-pg.so.1"]
|
134
|
+
when /darwin/ then ["libpq.5.dylib", "libpq-ruby-pg.1.dylib"]
|
135
|
+
# when /mingw/ then ["libpq.dll", "libpq.dll"] # renaming not needed
|
136
|
+
end
|
137
|
+
|
138
|
+
postgresql_recipe = BuildRecipe.new("postgresql", POSTGRESQL_VERSION, [POSTGRESQL_SOURCE_URI]).tap do |recipe|
|
139
|
+
class << recipe
|
140
|
+
def configure_defaults
|
141
|
+
[
|
142
|
+
"--target=#{host}",
|
143
|
+
"--host=#{host}",
|
144
|
+
'--with-openssl',
|
145
|
+
*(RUBY_PLATFORM=~/linux|darwin/ ? ['--with-gssapi'] : []),
|
146
|
+
'--without-zlib',
|
147
|
+
'--without-icu',
|
148
|
+
'--without-readline',
|
149
|
+
'ac_cv_search_gss_store_cred_into=',
|
150
|
+
]
|
151
|
+
end
|
152
|
+
def compile
|
153
|
+
execute 'compile include', "#{make_cmd} -C src/include install"
|
154
|
+
execute 'compile interfaces', "#{make_cmd} -C src/interfaces install"
|
155
|
+
end
|
156
|
+
def install
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
recipe.host = toolchain
|
161
|
+
recipe.configure_options << "CFLAGS=#{" -fPIC" if RUBY_PLATFORM =~ /linux|darwin/}"
|
162
|
+
recipe.configure_options << "LDFLAGS=-L#{openssl_recipe.path}/lib -L#{openssl_recipe.path}/lib64 -L#{openssl_recipe.path}/lib-arm64 #{"-Wl,-soname,#{libpq_rubypg} -lgssapi_krb5 -lkrb5 -lk5crypto -lkrb5support -ldl" if RUBY_PLATFORM =~ /linux/} #{"-Wl,-install_name,@loader_path/../../ports/#{gem_platform}/lib/#{libpq_rubypg} -lgssapi_krb5 -lkrb5 -lk5crypto -lkrb5support -lresolv -framework Kerberos" if RUBY_PLATFORM =~ /darwin/}"
|
163
|
+
recipe.configure_options << "LIBS=-lkrb5 -lcom_err -lk5crypto -lkrb5support -lresolv" if RUBY_PLATFORM =~ /linux/
|
164
|
+
recipe.configure_options << "LIBS=-lssl -lwsock32 -lgdi32 -lws2_32 -lcrypt32" if RUBY_PLATFORM =~ /mingw|mswin/
|
165
|
+
recipe.configure_options << "CPPFLAGS=-I#{openssl_recipe.path}/include"
|
166
|
+
recipe.cook_and_activate
|
167
|
+
end
|
168
|
+
|
169
|
+
# Use our own library name for libpq to avoid loading of system libpq by accident.
|
170
|
+
FileUtils.ln_sf File.join(postgresql_recipe.port_path, "lib/#{libpq_orig}"),
|
171
|
+
File.join(postgresql_recipe.port_path, "lib/#{libpq_rubypg}")
|
19
172
|
# Avoid dependency to external libgcc.dll on x86-mingw32
|
20
|
-
$LDFLAGS << " -static-libgcc"
|
173
|
+
$LDFLAGS << " -static-libgcc" if RUBY_PLATFORM =~ /mingw|mswin/
|
174
|
+
# Avoid: "libpq.so: undefined reference to `dlopen'" in cross-ruby-2.7.8
|
175
|
+
$LDFLAGS << " -Wl,--no-as-needed" if RUBY_PLATFORM !~ /aarch64|arm64|darwin/
|
176
|
+
# Find libpq in the ports directory coming from lib/3.x
|
177
|
+
# It is shared between all compiled ruby versions.
|
178
|
+
$LDFLAGS << " '-Wl,-rpath=$$ORIGIN/../../ports/#{gem_platform}/lib'" if RUBY_PLATFORM =~ /linux/
|
21
179
|
# Don't use pg_config for cross build, but --with-pg-* path options
|
22
|
-
dir_config
|
180
|
+
dir_config('pg', "#{postgresql_recipe.path}/include", "#{postgresql_recipe.path}/lib")
|
23
181
|
|
182
|
+
$defs.push( "-DPG_IS_BINARY_GEM")
|
24
183
|
else
|
25
184
|
# Native build
|
26
185
|
|
@@ -30,35 +189,101 @@ else
|
|
30
189
|
|
31
190
|
if pgconfig && pgconfig != 'ignore'
|
32
191
|
$stderr.puts "Using config values from %s" % [ pgconfig ]
|
33
|
-
incdir =
|
34
|
-
libdir =
|
192
|
+
incdir = IO.popen([pgconfig, "--includedir"], &:read).chomp
|
193
|
+
libdir = IO.popen([pgconfig, "--libdir"], &:read).chomp
|
35
194
|
dir_config 'pg', incdir, libdir
|
36
195
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
196
|
+
# Windows traditionally stores DLLs beside executables, not in libdir
|
197
|
+
dlldir = RUBY_PLATFORM=~/mingw|mswin/ ? IO.popen([pgconfig, "--bindir"], &:read).chomp : libdir
|
198
|
+
|
199
|
+
elsif checking_for "libpq per pkg-config" do
|
200
|
+
_cflags, ldflags, _libs = pkg_config("libpq")
|
201
|
+
dlldir = ldflags && ldflags[/-L([^ ]+)/] && $1
|
42
202
|
end
|
203
|
+
|
43
204
|
else
|
44
|
-
|
45
|
-
|
46
|
-
dir_config 'pg'
|
205
|
+
incdir, libdir = dir_config 'pg'
|
206
|
+
dlldir = libdir
|
47
207
|
end
|
208
|
+
|
209
|
+
# Try to use runtime path linker option, even if RbConfig doesn't know about it.
|
210
|
+
# The rpath option is usually set implicit by dir_config(), but so far not
|
211
|
+
# on MacOS-X.
|
212
|
+
if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
|
213
|
+
append_ldflags "-Wl,-rpath,#{dlldir.quote}"
|
214
|
+
end
|
215
|
+
|
216
|
+
if /mswin/ =~ RUBY_PLATFORM
|
217
|
+
$libs = append_library($libs, 'ws2_32')
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
$stderr.puts "Using libpq from #{dlldir}"
|
222
|
+
|
223
|
+
File.write("postgresql_lib_path.rb", <<-EOT)
|
224
|
+
module PG
|
225
|
+
POSTGRESQL_LIB_PATH = #{dlldir.inspect}
|
48
226
|
end
|
227
|
+
EOT
|
228
|
+
$INSTALLFILES = {
|
229
|
+
"./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
|
230
|
+
}
|
49
231
|
|
50
|
-
if
|
232
|
+
if /solaris/ =~ RUBY_PLATFORM
|
51
233
|
append_cppflags( '-D__EXTENSIONS__' )
|
52
234
|
end
|
53
235
|
|
54
|
-
|
55
|
-
find_header( 'libpq
|
56
|
-
find_header( '
|
236
|
+
begin
|
237
|
+
find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
|
238
|
+
find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
|
239
|
+
find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
|
57
240
|
|
58
|
-
abort "Can't find the PostgreSQL client library (libpq)" unless
|
59
|
-
|
60
|
-
|
61
|
-
|
241
|
+
abort "Can't find the PostgreSQL client library (libpq)" unless
|
242
|
+
have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
|
243
|
+
have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
|
244
|
+
have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
|
245
|
+
|
246
|
+
rescue SystemExit
|
247
|
+
install_text = case RUBY_PLATFORM
|
248
|
+
when /linux/
|
249
|
+
<<-EOT
|
250
|
+
Please install libpq or postgresql client package like so:
|
251
|
+
sudo apt install libpq-dev
|
252
|
+
sudo yum install postgresql-devel
|
253
|
+
sudo zypper in postgresql-devel
|
254
|
+
sudo pacman -S postgresql-libs
|
255
|
+
EOT
|
256
|
+
when /darwin/
|
257
|
+
<<-EOT
|
258
|
+
Please install libpq or postgresql client package like so:
|
259
|
+
brew install libpq
|
260
|
+
EOT
|
261
|
+
when /mingw/
|
262
|
+
<<-EOT
|
263
|
+
Please install libpq or postgresql client package like so:
|
264
|
+
ridk exec sh -c "pacman -S ${MINGW_PACKAGE_PREFIX}-postgresql"
|
265
|
+
EOT
|
266
|
+
else
|
267
|
+
<<-EOT
|
268
|
+
Please install libpq or postgresql client package.
|
269
|
+
EOT
|
270
|
+
end
|
271
|
+
|
272
|
+
$stderr.puts <<-EOT
|
273
|
+
*****************************************************************************
|
274
|
+
|
275
|
+
Unable to find PostgreSQL client library.
|
276
|
+
|
277
|
+
#{install_text}
|
278
|
+
or try again with:
|
279
|
+
gem install pg -- --with-pg-config=/path/to/pg_config
|
280
|
+
|
281
|
+
or set library paths manually with:
|
282
|
+
gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/
|
283
|
+
|
284
|
+
EOT
|
285
|
+
raise
|
286
|
+
end
|
62
287
|
|
63
288
|
if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
64
289
|
# Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
|
@@ -69,21 +294,22 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
|
69
294
|
end
|
70
295
|
end
|
71
296
|
|
72
|
-
#
|
73
|
-
have_func 'PQsetSingleRowMode' or
|
297
|
+
have_func 'PQencryptPasswordConn', 'libpq-fe.h' or # since PostgreSQL-10
|
74
298
|
abort "Your PostgreSQL is too old. Either install an older version " +
|
75
|
-
"of this gem or upgrade your database to at least PostgreSQL-
|
76
|
-
|
77
|
-
have_func '
|
78
|
-
have_func '
|
79
|
-
|
80
|
-
|
299
|
+
"of this gem or upgrade your database to at least PostgreSQL-10."
|
300
|
+
# optional headers/functions
|
301
|
+
have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
|
302
|
+
have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
|
303
|
+
# Ensure header files fit as well
|
304
|
+
src + " int con(){ return PGRES_PIPELINE_SYNC; }"
|
305
|
+
end
|
306
|
+
have_func 'PQsetChunkedRowsMode', 'libpq-fe.h' # since PostgreSQL-17
|
81
307
|
have_func 'timegm'
|
82
|
-
have_func '
|
308
|
+
have_func 'rb_io_wait' # since ruby-3.0
|
309
|
+
have_func 'rb_io_descriptor' # since ruby-3.1
|
83
310
|
|
84
|
-
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
85
|
-
have_header 'unistd.h'
|
86
311
|
have_header 'inttypes.h'
|
312
|
+
have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
|
87
313
|
|
88
314
|
checking_for "C99 variable length arrays" do
|
89
315
|
$defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
|
data/ext/gvl_wrappers.c
CHANGED
@@ -5,13 +5,28 @@
|
|
5
5
|
|
6
6
|
#include "pg.h"
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
10
|
+
PGresult *PQclosePrepared(PGconn *conn, const char *stmtName){return NULL;}
|
11
|
+
PGresult *PQclosePortal(PGconn *conn, const char *portalName){return NULL;}
|
12
|
+
int PQsendClosePrepared(PGconn *conn, const char *stmtName){return 0;}
|
13
|
+
int PQsendClosePortal(PGconn *conn, const char *portalName){return 0;}
|
14
|
+
int PQsendPipelineSync(PGconn *conn){return 0;}
|
15
|
+
int PQcancelBlocking(PGcancelConn *cancelConn){return 0;}
|
16
|
+
int PQcancelStart(PGcancelConn *cancelConn){return 0;}
|
17
|
+
PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn){return PGRES_POLLING_FAILED;}
|
18
|
+
#endif
|
19
|
+
#ifndef HAVE_PQENTERPIPELINEMODE
|
20
|
+
int PQpipelineSync(PGconn *conn){return 0;}
|
10
21
|
#endif
|
11
22
|
|
23
|
+
#ifdef ENABLE_GVL_UNLOCK
|
12
24
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
|
13
25
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
|
26
|
+
#endif
|
14
27
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
|
28
|
+
#ifdef ENABLE_GVL_UNLOCK
|
15
29
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
|
16
30
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON );
|
31
|
+
#endif
|
17
32
|
FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB );
|
data/ext/gvl_wrappers.h
CHANGED
@@ -17,6 +17,14 @@
|
|
17
17
|
|
18
18
|
#include <ruby/thread.h>
|
19
19
|
|
20
|
+
#ifdef RUBY_EXTCONF_H
|
21
|
+
# include RUBY_EXTCONF_H
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
25
|
+
typedef struct pg_cancel_conn PGcancelConn;
|
26
|
+
#endif
|
27
|
+
|
20
28
|
#define DEFINE_PARAM_LIST1(type, name) \
|
21
29
|
name,
|
22
30
|
|
@@ -46,6 +54,7 @@
|
|
46
54
|
return NULL; \
|
47
55
|
}
|
48
56
|
|
57
|
+
#ifdef ENABLE_GVL_UNLOCK
|
49
58
|
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
50
59
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
51
60
|
struct gvl_wrapper_##name##_params params = { \
|
@@ -54,6 +63,13 @@
|
|
54
63
|
rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \
|
55
64
|
when_non_void( return params.retval; ) \
|
56
65
|
}
|
66
|
+
#else
|
67
|
+
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
68
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
69
|
+
when_non_void( return ) \
|
70
|
+
name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
71
|
+
}
|
72
|
+
#endif
|
57
73
|
|
58
74
|
#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
59
75
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
|
@@ -66,6 +82,7 @@
|
|
66
82
|
return NULL; \
|
67
83
|
}
|
68
84
|
|
85
|
+
#ifdef ENABLE_GVL_UNLOCK
|
69
86
|
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
70
87
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
71
88
|
struct gvl_wrapper_##name##_params params = { \
|
@@ -74,6 +91,13 @@
|
|
74
91
|
rb_thread_call_with_gvl(gvl_##name##_skeleton, ¶ms); \
|
75
92
|
when_non_void( return params.retval; ) \
|
76
93
|
}
|
94
|
+
#else
|
95
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
96
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
97
|
+
when_non_void( return ) \
|
98
|
+
name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
99
|
+
}
|
100
|
+
#endif
|
77
101
|
|
78
102
|
#define GVL_TYPE_VOID(string)
|
79
103
|
#define GVL_TYPE_NONVOID(string) string
|
@@ -95,6 +119,8 @@
|
|
95
119
|
|
96
120
|
#define FOR_EACH_PARAM_OF_PQresetPoll(param)
|
97
121
|
|
122
|
+
#define FOR_EACH_PARAM_OF_PQping(param)
|
123
|
+
|
98
124
|
#define FOR_EACH_PARAM_OF_PQexec(param) \
|
99
125
|
param(PGconn *, conn)
|
100
126
|
|
@@ -127,6 +153,12 @@
|
|
127
153
|
#define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
|
128
154
|
param(PGconn *, conn)
|
129
155
|
|
156
|
+
#define FOR_EACH_PARAM_OF_PQclosePrepared(param) \
|
157
|
+
param(PGconn *, conn)
|
158
|
+
|
159
|
+
#define FOR_EACH_PARAM_OF_PQclosePortal(param) \
|
160
|
+
param(PGconn *, conn)
|
161
|
+
|
130
162
|
#define FOR_EACH_PARAM_OF_PQgetResult(param)
|
131
163
|
|
132
164
|
#define FOR_EACH_PARAM_OF_PQputCopyData(param) \
|
@@ -174,11 +206,25 @@
|
|
174
206
|
#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
|
175
207
|
param(PGconn *, conn)
|
176
208
|
|
209
|
+
#define FOR_EACH_PARAM_OF_PQsendClosePrepared(param) \
|
210
|
+
param(PGconn *, conn)
|
211
|
+
|
212
|
+
#define FOR_EACH_PARAM_OF_PQsendClosePortal(param) \
|
213
|
+
param(PGconn *, conn)
|
214
|
+
|
215
|
+
#define FOR_EACH_PARAM_OF_PQpipelineSync(param)
|
216
|
+
|
217
|
+
#define FOR_EACH_PARAM_OF_PQsendPipelineSync(param)
|
218
|
+
|
177
219
|
#define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
|
178
220
|
param(PGconn *, conn)
|
179
221
|
|
180
222
|
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
181
223
|
|
224
|
+
#define FOR_EACH_PARAM_OF_PQcancelBlocking(param)
|
225
|
+
#define FOR_EACH_PARAM_OF_PQcancelStart(param)
|
226
|
+
#define FOR_EACH_PARAM_OF_PQcancelPoll(param)
|
227
|
+
|
182
228
|
#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
|
183
229
|
param(PGconn *, conn) \
|
184
230
|
param(const char *, passwd) \
|
@@ -196,12 +242,15 @@
|
|
196
242
|
function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
|
197
243
|
function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
198
244
|
function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
245
|
+
function(PQping, GVL_TYPE_NONVOID, PGPing, const char *, conninfo) \
|
199
246
|
function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
|
200
247
|
function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
201
248
|
function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
202
249
|
function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
|
203
250
|
function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
204
251
|
function(PQdescribePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
|
252
|
+
function(PQclosePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
253
|
+
function(PQclosePortal, GVL_TYPE_NONVOID, PGresult *, const char *, portalName) \
|
205
254
|
function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
|
206
255
|
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
|
207
256
|
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
@@ -213,8 +262,15 @@
|
|
213
262
|
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
214
263
|
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
215
264
|
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
265
|
+
function(PQsendClosePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
266
|
+
function(PQsendClosePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
267
|
+
function(PQpipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
268
|
+
function(PQsendPipelineSync, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
216
269
|
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
|
217
270
|
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
271
|
+
function(PQcancelBlocking, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
|
272
|
+
function(PQcancelStart, GVL_TYPE_NONVOID, int, PGcancelConn *, conn) \
|
273
|
+
function(PQcancelPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGcancelConn *, conn) \
|
218
274
|
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
|
219
275
|
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
220
276
|
|