pg 1.5.9 → 1.7.0
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/{History.md → CHANGELOG.md} +126 -0
- data/Gemfile +11 -7
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +83 -32
- data/README.md +79 -29
- data/Rakefile +84 -19
- data/certs/larskanis-2026.pem +24 -0
- data/ext/errorcodes.def +9 -0
- data/ext/errorcodes.rb +1 -1
- data/ext/errorcodes.txt +8 -1
- data/ext/extconf.rb +194 -30
- data/ext/gvl_wrappers.c +13 -2
- data/ext/gvl_wrappers.h +47 -134
- data/ext/pg.c +23 -16
- data/ext/pg.h +23 -24
- data/ext/pg_binary_decoder.c +157 -3
- data/ext/pg_binary_encoder.c +219 -9
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +58 -9
- data/ext/pg_connection.c +558 -291
- data/ext/pg_copy_coder.c +36 -23
- data/ext/pg_record_coder.c +11 -7
- data/ext/pg_result.c +144 -76
- data/ext/pg_text_decoder.c +7 -7
- data/ext/pg_text_encoder.c +29 -11
- data/ext/pg_tuple.c +9 -9
- data/ext/pg_type_map.c +45 -3
- data/ext/pg_type_map_all_strings.c +3 -3
- data/ext/pg_type_map_by_class.c +2 -2
- data/ext/pg_type_map_by_column.c +4 -3
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +4 -2
- data/ext/pg_type_map_in_ruby.c +2 -2
- data/ext/pg_util.c +2 -2
- data/ext/pg_util.h +2 -2
- data/lib/pg/basic_type_map_based_on_result.rb +5 -0
- data/lib/pg/basic_type_map_for_queries.rb +16 -5
- data/lib/pg/basic_type_map_for_results.rb +5 -0
- data/lib/pg/basic_type_registry.rb +2 -2
- data/lib/pg/cancel_connection.rb +53 -0
- data/lib/pg/coder.rb +4 -2
- data/lib/pg/connection.rb +393 -180
- data/lib/pg/text_decoder/date.rb +1 -1
- data/lib/pg/text_decoder/json.rb +1 -1
- data/lib/pg/text_encoder/date.rb +7 -1
- data/lib/pg/text_encoder/json.rb +1 -1
- data/lib/pg/version.rb +2 -1
- data/lib/pg.rb +156 -130
- data/misc/glibc/Dockerfile +20 -0
- data/misc/glibc/docker-compose.yml +9 -0
- data/misc/glibc/glibc_spec.rb +5 -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 +5 -3
- data/ports/patches/krb5/1.22.2/0001-Allow-static-linking-krb5-library.patch +30 -0
- data/ports/patches/krb5/1.22.2/0002-unknown-command-line-option-on-clang.patch +12 -0
- data/ports/patches/postgresql/18.6/0001-Use-workaround-of-__builtin_setjmp-only-on-MINGW-on-.patch +42 -0
- data/rakelib/pg_gem_helper.rb +64 -0
- data/sample/async_mixed.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +36 -22
- metadata.gz.sig +0 -0
- data/Manifest.txt +0 -72
- data/Rakefile.cross +0 -303
data/Rakefile
CHANGED
|
@@ -11,6 +11,7 @@ require 'rake/clean'
|
|
|
11
11
|
require 'rspec/core/rake_task'
|
|
12
12
|
require 'bundler'
|
|
13
13
|
require 'bundler/gem_helper'
|
|
14
|
+
require_relative "rakelib/pg_gem_helper"
|
|
14
15
|
|
|
15
16
|
# Build directory constants
|
|
16
17
|
BASEDIR = Pathname( __FILE__ ).dirname
|
|
@@ -31,10 +32,10 @@ CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
|
|
|
31
32
|
CLEAN.include "lib/*/libpq.dll"
|
|
32
33
|
CLEAN.include "lib/pg_ext.*"
|
|
33
34
|
CLEAN.include "lib/pg/postgresql_lib_path.rb"
|
|
35
|
+
CLEAN.include "ports/*.installed"
|
|
36
|
+
CLEAN.include "ports/*mingw*", "ports/*linux*", "ports/*darwin*"
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Bundler::GemHelper.install_tasks
|
|
38
|
+
PgGemHelper.install_tasks
|
|
38
39
|
$gem_spec = Bundler.load_gemspec(GEMSPEC)
|
|
39
40
|
|
|
40
41
|
desc "Turn on warnings and debugging in the build."
|
|
@@ -42,6 +43,23 @@ task :maint do
|
|
|
42
43
|
ENV['MAINTAINER_MODE'] = 'yes'
|
|
43
44
|
end
|
|
44
45
|
|
|
46
|
+
CrossLibrary = Struct.new :platform, :openssl_config, :toolchain
|
|
47
|
+
CrossLibraries = [
|
|
48
|
+
['aarch64-mingw-ucrt', 'mingwarm64', 'aarch64-w64-mingw32'],
|
|
49
|
+
['x64-mingw-ucrt', 'mingw64', 'x86_64-w64-mingw32'],
|
|
50
|
+
['x86_64-linux', 'linux-x86_64', 'x86_64-linux-gnu'],
|
|
51
|
+
['x86_64-linux-musl', 'linux-x86_64', 'x86_64-unknown-linux-musl'],
|
|
52
|
+
['aarch64-linux', 'linux-aarch64', 'aarch64-linux-gnu'],
|
|
53
|
+
['aarch64-linux-musl', 'linux-aarch64', 'aarch64-linux-musl'],
|
|
54
|
+
['x86_64-darwin', 'darwin64-x86_64', 'x86_64-apple-darwin'],
|
|
55
|
+
['arm64-darwin', 'darwin64-arm64', 'arm64-apple-darwin'],
|
|
56
|
+
].map do |platform, openssl_config, toolchain|
|
|
57
|
+
CrossLibrary.new platform, openssl_config, toolchain
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Register binary gems to be pushed to rubygems.org
|
|
61
|
+
Bundler::GemHelper.instance.cross_platforms = CrossLibraries.map(&:platform)
|
|
62
|
+
|
|
45
63
|
# Rake-compiler task
|
|
46
64
|
Rake::ExtensionTask.new do |ext|
|
|
47
65
|
ext.name = 'pg_ext'
|
|
@@ -50,26 +68,70 @@ Rake::ExtensionTask.new do |ext|
|
|
|
50
68
|
ext.lib_dir = 'lib'
|
|
51
69
|
ext.source_pattern = "*.{c,h}"
|
|
52
70
|
ext.cross_compile = true
|
|
53
|
-
ext.cross_platform = CrossLibraries.map(&:for_platform)
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
# Activate current cross compiled platform only.
|
|
73
|
+
# This is to work around the issue that `linux` platform is selected in `linux-musl` image.
|
|
74
|
+
ext.cross_platform = CrossLibraries.map(&:platform).select do |pl|
|
|
75
|
+
m = ENV["RCD_IMAGE"]&.match(/:(?<ruby_ver>[\w\.]+)-mri-(?<platform>[-\w]+)$/)
|
|
76
|
+
m && m[:platform] == pl
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
ext.cross_config_options += CrossLibraries.map do |xlib|
|
|
56
80
|
{
|
|
57
|
-
|
|
58
|
-
"--
|
|
59
|
-
"--with-
|
|
60
|
-
"--with-
|
|
61
|
-
# libpq-fe.h resides in src/interfaces/libpq/ before make install
|
|
62
|
-
"--with-opt-include=#{lib.static_postgresql_libdir}",
|
|
81
|
+
xlib.platform => [
|
|
82
|
+
"--with-cross-build=#{xlib.platform}",
|
|
83
|
+
"--with-openssl-platform=#{xlib.openssl_config}",
|
|
84
|
+
"--with-toolchain=#{xlib.toolchain}",
|
|
63
85
|
]
|
|
64
86
|
}
|
|
65
87
|
end
|
|
66
88
|
|
|
67
|
-
# Add libpq.dll to
|
|
89
|
+
# Add libpq.dll/.so to fat binary gemspecs
|
|
68
90
|
ext.cross_compiling do |spec|
|
|
69
|
-
spec.files << "
|
|
91
|
+
spec.files << "ports/#{spec.platform.to_s}/lib/libpq-ruby-pg.so.1" if spec.platform.to_s =~ /linux/
|
|
92
|
+
spec.files << "ports/#{spec.platform.to_s}/lib/libpq-ruby-pg.1.dylib" if spec.platform.to_s =~ /darwin/
|
|
93
|
+
spec.files << "ports/#{spec.platform.to_s}/lib/libpq.dll" if spec.platform.to_s =~ /mingw|mswin/
|
|
94
|
+
|
|
95
|
+
# Binary gems don't need postgresql header+lib files
|
|
96
|
+
spec.metadata.delete("msys2_mingw_dependencies")
|
|
70
97
|
end
|
|
71
98
|
end
|
|
72
99
|
|
|
100
|
+
task 'gem:native:prepare' do
|
|
101
|
+
require 'io/console'
|
|
102
|
+
require 'rake_compiler_dock'
|
|
103
|
+
|
|
104
|
+
# Copy gem signing key and certs to be accessible from the docker container
|
|
105
|
+
mkdir_p 'build/gem'
|
|
106
|
+
sh "cp ~/.gem/gem-*.pem build/gem/ || true"
|
|
107
|
+
sh "bundle config set cache_all false"
|
|
108
|
+
sh "bundle package"
|
|
109
|
+
begin
|
|
110
|
+
OpenSSL::PKey.read(File.read(File.expand_path("~/.gem/gem-private_key.pem")), ENV["GEM_PRIVATE_KEY_PASSPHRASE"] || "")
|
|
111
|
+
rescue OpenSSL::PKey::PKeyError
|
|
112
|
+
ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = STDIN.getpass("Enter passphrase of gem signature key: ")
|
|
113
|
+
retry
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
CrossLibraries.each do |xlib|
|
|
118
|
+
platform = xlib.platform
|
|
119
|
+
desc "Build fat binary gem for platform #{platform}"
|
|
120
|
+
task "gem:native:#{platform}" => ['gem:native:prepare'] do
|
|
121
|
+
RakeCompilerDock.sh <<-EOT, platform: platform
|
|
122
|
+
#{ "sudo apt-get update && sudo apt-get install -y bison flex &&" if platform =~ /darwin/ }
|
|
123
|
+
#{ # remove nm on Linux to suppress PostgreSQL's check for exit which raises thread_exit as a false positive:
|
|
124
|
+
"sudo mv `which nm` `which nm`.bak &&" if platform =~ /linux/ }
|
|
125
|
+
sudo apt-get update && sudo apt-get install -y bison flex &&
|
|
126
|
+
(cp build/gem/gem-*.pem ~/.gem/ || true) &&
|
|
127
|
+
bundle install --local &&
|
|
128
|
+
rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEFLAGS="-j`nproc` V=1" RUBY_CC_VERSION=#{RakeCompilerDock.ruby_cc_version("~>4.0", "~>3.1")}
|
|
129
|
+
EOT
|
|
130
|
+
end
|
|
131
|
+
desc "Build the native binary gems"
|
|
132
|
+
multitask 'gem:native' => "gem:native:#{platform}"
|
|
133
|
+
end
|
|
134
|
+
|
|
73
135
|
RSpec::Core::RakeTask.new(:spec).rspec_opts = "--profile -cfdoc"
|
|
74
136
|
task :test => :spec
|
|
75
137
|
|
|
@@ -94,7 +156,8 @@ end
|
|
|
94
156
|
|
|
95
157
|
desc "Update list of server error codes"
|
|
96
158
|
task :update_error_codes do
|
|
97
|
-
URL_ERRORCODES_TXT = "
|
|
159
|
+
# URL_ERRORCODES_TXT = "https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_18_0"
|
|
160
|
+
URL_ERRORCODES_TXT = "https://raw.githubusercontent.com/postgres/postgres/refs/tags/REL_18_0/src/backend/utils/errcodes.txt"
|
|
98
161
|
|
|
99
162
|
ERRORCODES_TXT = "ext/errorcodes.txt"
|
|
100
163
|
sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
|
|
@@ -109,10 +172,12 @@ end
|
|
|
109
172
|
|
|
110
173
|
desc "Translate readme"
|
|
111
174
|
task :translate do
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
175
|
+
cd "translation" do
|
|
176
|
+
# po4a's lexer might change, so record its version for reference
|
|
177
|
+
sh "LANG=C po4a --version > .po4a-version"
|
|
115
178
|
|
|
116
|
-
|
|
117
|
-
|
|
179
|
+
pot = 'po/en.pot'
|
|
180
|
+
File.file?(pot) or FileUtils.touch(pot)
|
|
181
|
+
sh "po4a po4a.cfg"
|
|
182
|
+
end
|
|
118
183
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIEBDCCAmygAwIBAgIBBDANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
|
|
3
|
+
L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNjAyMTQyMTU3MTlaFw0yNzAy
|
|
4
|
+
MTQyMTU3MTlaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
|
|
5
|
+
PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
|
|
6
|
+
mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
|
|
7
|
+
eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
|
|
8
|
+
8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
|
|
9
|
+
SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
|
|
10
|
+
JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
|
|
11
|
+
eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
|
|
12
|
+
chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
|
|
13
|
+
9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
|
|
14
|
+
A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
|
|
15
|
+
7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAWuY62AlTOhipB443sEkhK0G09vjB3v0j
|
|
16
|
+
9A2HlHXMOcgilbfbMR7ejT+/ynwdqMkrYCQCvoQH06NgIzFi2u6cKKmb2rWXMAF1
|
|
17
|
+
g0NLTs1h/KFsfwuX7IOQ9LxkMl9jlYWdFptFi9oQhlfgmFAFLiZJzNA0+QZMgW6A
|
|
18
|
+
e3usJh0/pT8E0hLWnJdomEF7pNsFyfKjbp5KWRd585z3dePi0iPcpzdByCnJsO36
|
|
19
|
+
Hyl/JsJZyHwpR6LlgfpXmYFwxeFZvpJg2S9O7Yo+qlgiaIUbnkVxOqfEXhCRZm8d
|
|
20
|
+
vfBZ6NSBwcdh7tXk01Yeqap0OtIE7Ey6C/so7uc3vZE6lPZ8xumMYyZ1lJTk5WwS
|
|
21
|
+
qgNbJXZWC/Q9RqPbOZXj4Q2Rq0iFfGNPlkKVeDabXfAASAVtrUb1gByb2b53Kq6N
|
|
22
|
+
OZ/RmpA4/XcoJIE2pnoUq8j6WCeNJ9m11JS2NmgUvYtdMFgMJWoH/hiF71l8dH3v
|
|
23
|
+
76Q140MRgXCuR7RMxztucM6XZQbk1VSO
|
|
24
|
+
-----END CERTIFICATE-----
|
data/ext/errorcodes.def
CHANGED
|
@@ -87,6 +87,11 @@
|
|
|
87
87
|
VALUE klass = define_error_class( "StackedDiagnosticsAccessedWithoutActiveHandler", "0Z" );
|
|
88
88
|
register_error_class( "0Z002", klass );
|
|
89
89
|
}
|
|
90
|
+
{
|
|
91
|
+
VALUE klass = define_error_class( "InvalidArgumentForXquery", NULL );
|
|
92
|
+
register_error_class( "10608", klass );
|
|
93
|
+
register_error_class( "10", klass );
|
|
94
|
+
}
|
|
90
95
|
{
|
|
91
96
|
VALUE klass = define_error_class( "CaseNotFound", NULL );
|
|
92
97
|
register_error_class( "20000", klass );
|
|
@@ -889,6 +894,10 @@
|
|
|
889
894
|
VALUE klass = define_error_class( "DuplicateFile", "58" );
|
|
890
895
|
register_error_class( "58P02", klass );
|
|
891
896
|
}
|
|
897
|
+
{
|
|
898
|
+
VALUE klass = define_error_class( "FileNameTooLong", "58" );
|
|
899
|
+
register_error_class( "58P03", klass );
|
|
900
|
+
}
|
|
892
901
|
{
|
|
893
902
|
VALUE klass = define_error_class( "ConfigFileError", NULL );
|
|
894
903
|
register_error_class( "F0000", klass );
|
data/ext/errorcodes.rb
CHANGED
|
@@ -28,7 +28,7 @@ EOCODE
|
|
|
28
28
|
sqlstate, ews, errcode_macro_name = $1, $2, $3
|
|
29
29
|
next unless ews=='E'
|
|
30
30
|
|
|
31
|
-
is_sqlclass = sqlstate[2..-1] == '000'
|
|
31
|
+
is_sqlclass = sqlstate[2..-1] == '000' || sqlstate == '10608'
|
|
32
32
|
class_code = sqlstate[0,2]
|
|
33
33
|
baseclass_code = is_sqlclass ? 'NULL' : class_code.inspect
|
|
34
34
|
class_name = camelize(errcode_macro_name.sub('ERRCODE_', '').downcase)
|
data/ext/errorcodes.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# errcodes.txt
|
|
3
3
|
# PostgreSQL error codes
|
|
4
4
|
#
|
|
5
|
-
# Copyright (c) 2003-
|
|
5
|
+
# Copyright (c) 2003-2025, PostgreSQL Global Development Group
|
|
6
6
|
#
|
|
7
7
|
# This list serves as the basis for generating source files containing error
|
|
8
8
|
# codes. It is kept in a common format to make sure all these source files have
|
|
@@ -141,6 +141,12 @@ Section: Class 0Z - Diagnostics Exception
|
|
|
141
141
|
0Z000 E ERRCODE_DIAGNOSTICS_EXCEPTION diagnostics_exception
|
|
142
142
|
0Z002 E ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER stacked_diagnostics_accessed_without_active_handler
|
|
143
143
|
|
|
144
|
+
Section: Class 10 - XQuery Error
|
|
145
|
+
|
|
146
|
+
# recent SQL versions define quite a few codes in this class, but for now
|
|
147
|
+
# we are only using this generic one
|
|
148
|
+
10608 E ERRCODE_INVALID_ARGUMENT_FOR_XQUERY invalid_argument_for_xquery
|
|
149
|
+
|
|
144
150
|
Section: Class 20 - Case Not Found
|
|
145
151
|
|
|
146
152
|
20000 E ERRCODE_CASE_NOT_FOUND case_not_found
|
|
@@ -439,6 +445,7 @@ Section: Class 58 - System Error (errors external to PostgreSQL itself)
|
|
|
439
445
|
58030 E ERRCODE_IO_ERROR io_error
|
|
440
446
|
58P01 E ERRCODE_UNDEFINED_FILE undefined_file
|
|
441
447
|
58P02 E ERRCODE_DUPLICATE_FILE duplicate_file
|
|
448
|
+
58P03 E ERRCODE_FILE_NAME_TOO_LONG file_name_too_long
|
|
442
449
|
|
|
443
450
|
Section: Class F0 - Configuration File Error
|
|
444
451
|
|
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 <<
|
|
@@ -24,12 +23,179 @@ else
|
|
|
24
23
|
$stderr.puts "Calling libpq with GVL locked"
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
if
|
|
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.6.5'
|
|
31
|
+
OPENSSL_SOURCE_URI = "https://www.openssl.org/source/openssl-#{OPENSSL_VERSION}.tar.gz"
|
|
32
|
+
|
|
33
|
+
KRB5_VERSION = ENV['KRB5_VERSION'] || '1.22.2'
|
|
34
|
+
KRB5_SOURCE_URI = "https://kerberos.org/dist/krb5/#{KRB5_VERSION[/^(\d+\.\d+)/]}/krb5-#{KRB5_VERSION}.tar.gz"
|
|
35
|
+
|
|
36
|
+
POSTGRESQL_VERSION = ENV['POSTGRESQL_VERSION'] || '18.6'
|
|
37
|
+
POSTGRESQL_SOURCE_URI = "https://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
|
+
# Add "--prefix=/", to avoid our actual build install path compiled into the binary.
|
|
53
|
+
# Instead use DESTDIR variable of make to set our install path.
|
|
54
|
+
def configure_prefix
|
|
55
|
+
"--prefix="
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def cook_and_activate
|
|
59
|
+
checkpoint = File.join(self.target, "#{self.name}-#{self.version}-#{RUBY_PLATFORM}.installed")
|
|
60
|
+
unless File.exist?(checkpoint)
|
|
61
|
+
self.cook
|
|
62
|
+
FileUtils.touch checkpoint
|
|
63
|
+
end
|
|
64
|
+
self.activate
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Increase number of download retries; otherwise it fails often in CI
|
|
69
|
+
alias download_file_count_3 download_file
|
|
70
|
+
def download_file(url, full_path, count = 60)
|
|
71
|
+
download_file_count_3(url, full_path, count)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
openssl_platform = with_config("openssl-platform")
|
|
76
|
+
toolchain = with_config("toolchain")
|
|
77
|
+
|
|
78
|
+
openssl_recipe = BuildRecipe.new("openssl", OPENSSL_VERSION, [OPENSSL_SOURCE_URI]).tap do |recipe|
|
|
79
|
+
class << recipe
|
|
80
|
+
attr_accessor :openssl_platform
|
|
81
|
+
def configure
|
|
82
|
+
envs = []
|
|
83
|
+
envs << "CFLAGS=-DDSO_WIN32 -DOPENSSL_THREADS" if RUBY_PLATFORM =~ /mingw|mswin/
|
|
84
|
+
envs << "CFLAGS=-fPIC -DOPENSSL_THREADS" if RUBY_PLATFORM =~ /linux|darwin/
|
|
85
|
+
execute('configure', ['env', *envs, "./Configure", openssl_platform, "threads", "-static", "CROSS_COMPILE=#{host}-", "--prefix=/", "--libdir=lib"], altlog: "config.log")
|
|
86
|
+
end
|
|
87
|
+
def compile
|
|
88
|
+
execute('compile', "#{make_cmd} build_libs")
|
|
89
|
+
end
|
|
90
|
+
def install
|
|
91
|
+
execute('install', "#{make_cmd} install_dev DESTDIR=#{path}")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
recipe.openssl_platform = openssl_platform
|
|
96
|
+
recipe.host = toolchain
|
|
97
|
+
recipe.cook_and_activate
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if RUBY_PLATFORM =~ /linux|darwin/
|
|
101
|
+
BuildRecipe.new("krb5", KRB5_VERSION, [KRB5_SOURCE_URI]).tap do |recipe|
|
|
102
|
+
class << recipe
|
|
103
|
+
def work_path
|
|
104
|
+
File.join(super, "src")
|
|
105
|
+
end
|
|
106
|
+
def configure
|
|
107
|
+
if RUBY_PLATFORM=~/darwin/
|
|
108
|
+
ENV["CC"] = host[/^.*[^\.\d]/] + "-clang"
|
|
109
|
+
ENV["CXX"] = host[/^.*[^\.\d]/] + "-c++"
|
|
110
|
+
|
|
111
|
+
# Manually set the correct values for configure checks that libkrb5 won't be
|
|
112
|
+
# able to perform because we're cross-compiling.
|
|
113
|
+
ENV["krb5_cv_attr_constructor_destructor"] = "yes"
|
|
114
|
+
ENV["ac_cv_func_regcomp"] = "yes"
|
|
115
|
+
ENV["ac_cv_printf_positional"] = "yes"
|
|
116
|
+
end
|
|
117
|
+
super
|
|
118
|
+
end
|
|
119
|
+
def install
|
|
120
|
+
execute('install', "#{make_cmd} install DESTDIR=#{path}")
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
# We specify -fcommon to get around duplicate definition errors in recent gcc.
|
|
124
|
+
# See https://github.com/cockroachdb/cockroach/issues/49734
|
|
125
|
+
recipe.configure_options << "CFLAGS=-fcommon#{" -fPIC" if RUBY_PLATFORM =~ /linux/}"
|
|
126
|
+
recipe.configure_options << "LDFLAGS=-framework Kerberos" if RUBY_PLATFORM =~ /darwin/
|
|
127
|
+
recipe.configure_options << "--without-keyutils"
|
|
128
|
+
recipe.configure_options << "--disable-nls"
|
|
129
|
+
recipe.configure_options << "--disable-silent-rules"
|
|
130
|
+
recipe.configure_options << "--disable-rpath"
|
|
131
|
+
recipe.configure_options << "--without-system-verto"
|
|
132
|
+
recipe.configure_options << "krb5_cv_attr_constructor_destructor=yes"
|
|
133
|
+
recipe.configure_options << "ac_cv_func_regcomp=yes"
|
|
134
|
+
recipe.configure_options << "ac_cv_printf_positional=yes"
|
|
135
|
+
recipe.host = toolchain
|
|
136
|
+
recipe.cook_and_activate
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# We build a libpq library file which static links OpenSSL and krb5.
|
|
141
|
+
# Our builtin libpq is referenced in different ways depending on the OS:
|
|
142
|
+
# - Window: Add the ports directory at runtime per RubyInstaller::Runtime.add_dll_directory
|
|
143
|
+
# The file is called "libpq.dll"
|
|
144
|
+
# - Linux: Add a rpath to pg_ext.so which references the ports directory.
|
|
145
|
+
# The file is called "libpq-ruby-pg.so.1" to avoid loading of system libpq by accident.
|
|
146
|
+
# - Macos: Add a reference with relative path in pg_ext.so to the ports directory.
|
|
147
|
+
# The file is called "libpq-ruby-pg.1.dylib" to avoid loading of other libpq by accident.
|
|
148
|
+
libpq_orig, libpq_rubypg = case RUBY_PLATFORM
|
|
149
|
+
when /linux/ then ["libpq.so.5", "libpq-ruby-pg.so.1"]
|
|
150
|
+
when /darwin/ then ["libpq.5.dylib", "libpq-ruby-pg.1.dylib"]
|
|
151
|
+
# when /mingw/ then ["libpq.dll", "libpq.dll"] # renaming not needed
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
postgresql_recipe = BuildRecipe.new("postgresql", POSTGRESQL_VERSION, [POSTGRESQL_SOURCE_URI]).tap do |recipe|
|
|
155
|
+
class << recipe
|
|
156
|
+
def configure_defaults
|
|
157
|
+
[
|
|
158
|
+
"--target=#{host}",
|
|
159
|
+
"--host=#{host}",
|
|
160
|
+
'--with-openssl',
|
|
161
|
+
*(RUBY_PLATFORM=~/linux|darwin/ ? ['--with-gssapi'] : []),
|
|
162
|
+
'--without-zlib',
|
|
163
|
+
'--without-icu',
|
|
164
|
+
'--without-readline',
|
|
165
|
+
'--disable-rpath',
|
|
166
|
+
'ac_cv_search_gss_store_cred_into=',
|
|
167
|
+
]
|
|
168
|
+
end
|
|
169
|
+
def compile
|
|
170
|
+
execute 'compile include', "#{make_cmd} -C src/include install DESTDIR=#{path}"
|
|
171
|
+
execute 'compile interfaces', "#{make_cmd} -C src/interfaces install DESTDIR=#{path}"
|
|
172
|
+
end
|
|
173
|
+
def install
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
recipe.host = toolchain
|
|
178
|
+
recipe.configure_options << "CFLAGS=#{" -fPIC" if RUBY_PLATFORM =~ /linux|darwin/}"
|
|
179
|
+
recipe.configure_options << "LDFLAGS=-L#{openssl_recipe.path}/lib #{"-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/}"
|
|
180
|
+
recipe.configure_options << "LIBS=-lkrb5 -lcom_err -lk5crypto -lkrb5support -lresolv" if RUBY_PLATFORM =~ /linux/
|
|
181
|
+
recipe.configure_options << "LIBS=-lssl -lwsock32 -lgdi32 -lws2_32 -lcrypt32" if RUBY_PLATFORM =~ /mingw|mswin/
|
|
182
|
+
recipe.configure_options << "CPPFLAGS=-I#{openssl_recipe.path}/include"
|
|
183
|
+
recipe.cook_and_activate
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Use our own library name for libpq to avoid loading of system libpq by accident.
|
|
187
|
+
FileUtils.ln_sf File.join(postgresql_recipe.port_path, "lib/#{libpq_orig}"),
|
|
188
|
+
File.join(postgresql_recipe.port_path, "lib/#{libpq_rubypg}")
|
|
189
|
+
# Link to libpq_rubypg in our ports directory without adding it as rpath (like dir_config does)
|
|
190
|
+
$CFLAGS << " -I#{postgresql_recipe.path}/include"
|
|
191
|
+
$LDFLAGS << " -L#{postgresql_recipe.path}/lib"
|
|
28
192
|
# Avoid dependency to external libgcc.dll on x86-mingw32
|
|
29
|
-
$LDFLAGS << " -static-libgcc"
|
|
30
|
-
#
|
|
31
|
-
|
|
193
|
+
$LDFLAGS << " -static-libgcc" if RUBY_PLATFORM =~ /mingw|mswin/
|
|
194
|
+
# Find libpq in the ports directory coming from lib/3.x
|
|
195
|
+
# It is shared between all compiled ruby versions.
|
|
196
|
+
$LDFLAGS << " '-Wl,-rpath=$$ORIGIN/../../ports/#{gem_platform}/lib'" if RUBY_PLATFORM =~ /linux/
|
|
32
197
|
|
|
198
|
+
$defs.push( "-DPG_IS_BINARY_GEM")
|
|
33
199
|
else
|
|
34
200
|
# Native build
|
|
35
201
|
|
|
@@ -56,13 +222,6 @@ else
|
|
|
56
222
|
dlldir = libdir
|
|
57
223
|
end
|
|
58
224
|
|
|
59
|
-
# Try to use runtime path linker option, even if RbConfig doesn't know about it.
|
|
60
|
-
# The rpath option is usually set implicit by dir_config(), but so far not
|
|
61
|
-
# on MacOS-X.
|
|
62
|
-
if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
|
|
63
|
-
append_ldflags "-Wl,-rpath,#{dlldir.quote}"
|
|
64
|
-
end
|
|
65
|
-
|
|
66
225
|
if /mswin/ =~ RUBY_PLATFORM
|
|
67
226
|
$libs = append_library($libs, 'ws2_32')
|
|
68
227
|
end
|
|
@@ -79,7 +238,7 @@ $INSTALLFILES = {
|
|
|
79
238
|
"./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
|
|
80
239
|
}
|
|
81
240
|
|
|
82
|
-
if
|
|
241
|
+
if /solaris/ =~ RUBY_PLATFORM
|
|
83
242
|
append_cppflags( '-D__EXTENSIONS__' )
|
|
84
243
|
end
|
|
85
244
|
|
|
@@ -144,28 +303,16 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
|
|
144
303
|
end
|
|
145
304
|
end
|
|
146
305
|
|
|
147
|
-
have_func '
|
|
148
|
-
abort "Your PostgreSQL is too old.
|
|
149
|
-
|
|
306
|
+
have_func 'PQencryptPasswordConn', 'libpq-fe.h' or # since PostgreSQL-10
|
|
307
|
+
abort "Your PostgreSQL client library (libpq) is too old. " +
|
|
308
|
+
"Either install an older version of this gem " +
|
|
309
|
+
"or upgrade your database to at least PostgreSQL-10."
|
|
150
310
|
# optional headers/functions
|
|
151
|
-
have_func 'PQsslAttribute', 'libpq-fe.h' # since PostgreSQL-9.5
|
|
152
|
-
have_func 'PQresultVerboseErrorMessage', 'libpq-fe.h' # since PostgreSQL-9.6
|
|
153
|
-
have_func 'PQencryptPasswordConn', 'libpq-fe.h' # since PostgreSQL-10
|
|
154
311
|
have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
|
|
155
|
-
have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
|
|
156
|
-
# Ensure header files fit as well
|
|
157
|
-
src + " int con(){ return PGRES_PIPELINE_SYNC; }"
|
|
158
|
-
end
|
|
159
312
|
have_func 'timegm'
|
|
160
|
-
have_func '
|
|
161
|
-
have_func 'rb_gc_mark_movable' # since ruby-2.7
|
|
162
|
-
have_func 'rb_io_wait' # since ruby-3.0
|
|
163
|
-
have_func 'rb_io_descriptor' # since ruby-3.1
|
|
313
|
+
have_func 'rb_hash_new_capa' # since ruby-3.2
|
|
164
314
|
|
|
165
|
-
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
|
166
|
-
have_header 'unistd.h'
|
|
167
315
|
have_header 'inttypes.h'
|
|
168
|
-
have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
|
|
169
316
|
|
|
170
317
|
checking_for "C99 variable length arrays" do
|
|
171
318
|
$defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
|
|
@@ -174,3 +321,20 @@ end
|
|
|
174
321
|
create_header()
|
|
175
322
|
create_makefile( "pg_ext" )
|
|
176
323
|
|
|
324
|
+
if gem_platform
|
|
325
|
+
# exercise the strip command on native binary gems
|
|
326
|
+
# This approach borrowed from
|
|
327
|
+
# https://github.com/rake-compiler/rake-compiler-dock/blob/38066d479050f4fdb3956469255b35a05e5949ef/test/rcd_test/ext/mri/extconf.rb#L97C1-L110C42
|
|
328
|
+
strip_tool = RbConfig::CONFIG['STRIP']
|
|
329
|
+
strip_tool += ' -x' if RUBY_PLATFORM =~ /darwin/
|
|
330
|
+
File.open('Makefile.new', 'w') do |o|
|
|
331
|
+
o.puts 'hijack: all strip'
|
|
332
|
+
o.puts
|
|
333
|
+
o.write(File.read('Makefile'))
|
|
334
|
+
o.puts
|
|
335
|
+
o.puts 'strip: $(DLLIB)'
|
|
336
|
+
o.puts "\t$(ECHO) Stripping $(DLLIB)"
|
|
337
|
+
o.puts "\t$(Q) #{strip_tool} $(DLLIB)"
|
|
338
|
+
end
|
|
339
|
+
File.rename('Makefile.new', 'Makefile')
|
|
340
|
+
end
|
data/ext/gvl_wrappers.c
CHANGED
|
@@ -5,8 +5,19 @@
|
|
|
5
5
|
|
|
6
6
|
#include "pg.h"
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
#ifndef LIBPQ_HAS_CHUNK_MODE
|
|
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 LIBPQ_HAS_PIPELINING
|
|
20
|
+
int PQpipelineSync(PGconn *conn){return 0;}
|
|
10
21
|
#endif
|
|
11
22
|
|
|
12
23
|
#ifdef ENABLE_GVL_UNLOCK
|