pg 1.4.6 → 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/{History.md → CHANGELOG.md} +185 -3
- data/Gemfile +12 -3
- data/README-Windows.rdoc +1 -1
- data/README.ja.md +75 -41
- data/README.md +86 -31
- data/Rakefile +95 -14
- data/certs/kanis@comcard.de.pem +20 -0
- data/certs/larskanis-2024.pem +24 -0
- data/ext/errorcodes.def +4 -5
- data/ext/errorcodes.txt +2 -5
- data/ext/extconf.rb +165 -14
- data/ext/gvl_wrappers.c +13 -2
- data/ext/gvl_wrappers.h +33 -0
- data/ext/pg.c +28 -35
- data/ext/pg.h +18 -14
- data/ext/pg_binary_decoder.c +231 -0
- data/ext/pg_binary_encoder.c +427 -0
- data/ext/pg_cancel_connection.c +360 -0
- data/ext/pg_coder.c +70 -12
- data/ext/pg_connection.c +473 -208
- data/ext/pg_copy_coder.c +316 -23
- data/ext/pg_record_coder.c +12 -11
- data/ext/pg_result.c +102 -30
- data/ext/pg_text_decoder.c +31 -10
- data/ext/pg_text_encoder.c +58 -26
- data/ext/pg_tuple.c +36 -33
- data/ext/pg_type_map.c +4 -3
- data/ext/pg_type_map_all_strings.c +3 -3
- data/ext/pg_type_map_by_class.c +6 -4
- data/ext/pg_type_map_by_column.c +9 -4
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +10 -5
- data/ext/pg_type_map_in_ruby.c +6 -3
- data/lib/pg/basic_type_map_based_on_result.rb +21 -1
- data/lib/pg/basic_type_map_for_queries.rb +23 -10
- data/lib/pg/basic_type_map_for_results.rb +26 -3
- data/lib/pg/basic_type_registry.rb +46 -36
- 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 +387 -172
- data/lib/pg/exceptions.rb +6 -0
- 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 +1 -1
- data/lib/pg.rb +78 -17
- 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 +9 -5
- 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.tar.gz.sig +0 -0
- metadata +61 -49
- metadata.gz.sig +0 -0
- data/.appveyor.yml +0 -42
- data/.gems +0 -6
- data/.gemtest +0 -0
- data/.github/workflows/binary-gems.yml +0 -117
- data/.github/workflows/source-gem.yml +0 -137
- data/.gitignore +0 -19
- data/.hgsigs +0 -34
- data/.hgtags +0 -41
- data/.irbrc +0 -23
- data/.pryrc +0 -23
- data/.tm_properties +0 -21
- data/.travis.yml +0 -49
- data/Manifest.txt +0 -72
- data/Rakefile.cross +0 -298
- 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/translation/.po4a-version +0 -7
- data/translation/po/all.pot +0 -875
- data/translation/po/ja.po +0 -868
- data/translation/po4a.cfg +0 -9
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,6 +8,8 @@ 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' )
|
@@ -22,12 +23,163 @@ else
|
|
22
23
|
$stderr.puts "Calling libpq with GVL locked"
|
23
24
|
end
|
24
25
|
|
25
|
-
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.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}")
|
26
172
|
# Avoid dependency to external libgcc.dll on x86-mingw32
|
27
|
-
$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/
|
28
179
|
# Don't use pg_config for cross build, but --with-pg-* path options
|
29
|
-
dir_config
|
180
|
+
dir_config('pg', "#{postgresql_recipe.path}/include", "#{postgresql_recipe.path}/lib")
|
30
181
|
|
182
|
+
$defs.push( "-DPG_IS_BINARY_GEM")
|
31
183
|
else
|
32
184
|
# Native build
|
33
185
|
|
@@ -60,6 +212,10 @@ else
|
|
60
212
|
if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
|
61
213
|
append_ldflags "-Wl,-rpath,#{dlldir.quote}"
|
62
214
|
end
|
215
|
+
|
216
|
+
if /mswin/ =~ RUBY_PLATFORM
|
217
|
+
$libs = append_library($libs, 'ws2_32')
|
218
|
+
end
|
63
219
|
end
|
64
220
|
|
65
221
|
$stderr.puts "Using libpq from #{dlldir}"
|
@@ -73,7 +229,7 @@ $INSTALLFILES = {
|
|
73
229
|
"./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
|
74
230
|
}
|
75
231
|
|
76
|
-
if
|
232
|
+
if /solaris/ =~ RUBY_PLATFORM
|
77
233
|
append_cppflags( '-D__EXTENSIONS__' )
|
78
234
|
end
|
79
235
|
|
@@ -138,25 +294,20 @@ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
|
138
294
|
end
|
139
295
|
end
|
140
296
|
|
141
|
-
have_func '
|
297
|
+
have_func 'PQencryptPasswordConn', 'libpq-fe.h' or # since PostgreSQL-10
|
142
298
|
abort "Your PostgreSQL is too old. Either install an older version " +
|
143
|
-
"of this gem or upgrade your database to at least PostgreSQL-
|
299
|
+
"of this gem or upgrade your database to at least PostgreSQL-10."
|
144
300
|
# optional headers/functions
|
145
|
-
have_func 'PQsslAttribute', 'libpq-fe.h' # since PostgreSQL-9.5
|
146
|
-
have_func 'PQresultVerboseErrorMessage', 'libpq-fe.h' # since PostgreSQL-9.6
|
147
|
-
have_func 'PQencryptPasswordConn', 'libpq-fe.h' # since PostgreSQL-10
|
148
301
|
have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
|
149
302
|
have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
|
150
303
|
# Ensure header files fit as well
|
151
304
|
src + " int con(){ return PGRES_PIPELINE_SYNC; }"
|
152
305
|
end
|
306
|
+
have_func 'PQsetChunkedRowsMode', 'libpq-fe.h' # since PostgreSQL-17
|
153
307
|
have_func 'timegm'
|
154
|
-
have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
|
155
|
-
have_func 'rb_gc_mark_movable' # since ruby-2.7
|
156
308
|
have_func 'rb_io_wait' # since ruby-3.0
|
309
|
+
have_func 'rb_io_descriptor' # since ruby-3.1
|
157
310
|
|
158
|
-
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
159
|
-
have_header 'unistd.h'
|
160
311
|
have_header 'inttypes.h'
|
161
312
|
have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
|
162
313
|
|
data/ext/gvl_wrappers.c
CHANGED
@@ -5,8 +5,19 @@
|
|
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
|
|
12
23
|
#ifdef ENABLE_GVL_UNLOCK
|
data/ext/gvl_wrappers.h
CHANGED
@@ -21,6 +21,10 @@
|
|
21
21
|
# include RUBY_EXTCONF_H
|
22
22
|
#endif
|
23
23
|
|
24
|
+
#ifndef HAVE_PQSETCHUNKEDROWSMODE
|
25
|
+
typedef struct pg_cancel_conn PGcancelConn;
|
26
|
+
#endif
|
27
|
+
|
24
28
|
#define DEFINE_PARAM_LIST1(type, name) \
|
25
29
|
name,
|
26
30
|
|
@@ -149,6 +153,12 @@
|
|
149
153
|
#define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
|
150
154
|
param(PGconn *, conn)
|
151
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
|
+
|
152
162
|
#define FOR_EACH_PARAM_OF_PQgetResult(param)
|
153
163
|
|
154
164
|
#define FOR_EACH_PARAM_OF_PQputCopyData(param) \
|
@@ -196,11 +206,25 @@
|
|
196
206
|
#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
|
197
207
|
param(PGconn *, conn)
|
198
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
|
+
|
199
219
|
#define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
|
200
220
|
param(PGconn *, conn)
|
201
221
|
|
202
222
|
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
203
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
|
+
|
204
228
|
#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
|
205
229
|
param(PGconn *, conn) \
|
206
230
|
param(const char *, passwd) \
|
@@ -225,6 +249,8 @@
|
|
225
249
|
function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
|
226
250
|
function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
|
227
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) \
|
228
254
|
function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
|
229
255
|
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
|
230
256
|
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
@@ -236,8 +262,15 @@
|
|
236
262
|
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
237
263
|
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
238
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) \
|
239
269
|
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
|
240
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) \
|
241
274
|
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
|
242
275
|
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
243
276
|
|
data/ext/pg.c
CHANGED
@@ -33,7 +33,6 @@
|
|
33
33
|
*
|
34
34
|
* - PQfreemem -- unnecessary: copied to ruby object, then freed. Ruby object's
|
35
35
|
* memory is freed when it is garbage collected.
|
36
|
-
* - PQbinaryTuples -- better to use PQfformat
|
37
36
|
* - PQprint -- not very useful
|
38
37
|
* - PQsetdb -- not very useful
|
39
38
|
* - PQoidStatus -- deprecated, use PQoidValue
|
@@ -74,6 +73,7 @@ VALUE rb_mPGconstants;
|
|
74
73
|
* The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
|
75
74
|
*/
|
76
75
|
const char * const (pg_enc_pg2ruby_mapping[][2]) = {
|
76
|
+
{"UTF8", "UTF-8" },
|
77
77
|
{"BIG5", "Big5" },
|
78
78
|
{"EUC_CN", "GB2312" },
|
79
79
|
{"EUC_JP", "EUC-JP" },
|
@@ -105,7 +105,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
|
|
105
105
|
{"SHIFT_JIS_2004","Windows-31J" },
|
106
106
|
/* {"SQL_ASCII", NULL }, special case*/
|
107
107
|
{"UHC", "CP949" },
|
108
|
-
{"UTF8", "UTF-8" },
|
109
108
|
{"WIN866", "IBM866" },
|
110
109
|
{"WIN874", "Windows-874" },
|
111
110
|
{"WIN1250", "Windows-1250"},
|
@@ -120,36 +119,17 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
|
|
120
119
|
};
|
121
120
|
|
122
121
|
|
123
|
-
/*
|
124
|
-
* A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s.
|
125
|
-
*/
|
126
|
-
static struct st_table *enc_pg2ruby;
|
127
|
-
|
128
|
-
|
129
122
|
/*
|
130
123
|
* Return the given PostgreSQL encoding ID as an rb_encoding.
|
131
124
|
*
|
132
125
|
* - returns NULL if the client encoding is 'SQL_ASCII'.
|
133
126
|
* - returns ASCII-8BIT if the client encoding is unknown.
|
134
127
|
*/
|
135
|
-
rb_encoding *
|
128
|
+
static rb_encoding *
|
136
129
|
pg_get_pg_encoding_as_rb_encoding( int enc_id )
|
137
130
|
{
|
138
|
-
|
139
|
-
|
140
|
-
/* Use the cached value if it exists */
|
141
|
-
if ( st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc) ) {
|
142
|
-
return enc;
|
143
|
-
}
|
144
|
-
else {
|
145
|
-
const char *name = pg_encoding_to_char( enc_id );
|
146
|
-
|
147
|
-
enc = pg_get_pg_encname_as_rb_encoding( name );
|
148
|
-
st_insert( enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc );
|
149
|
-
|
150
|
-
return enc;
|
151
|
-
}
|
152
|
-
|
131
|
+
const char *name = pg_encoding_to_char( enc_id );
|
132
|
+
return pg_get_pg_encname_as_rb_encoding( name );
|
153
133
|
}
|
154
134
|
|
155
135
|
/*
|
@@ -354,6 +334,11 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
|
|
354
334
|
void
|
355
335
|
Init_pg_ext(void)
|
356
336
|
{
|
337
|
+
|
338
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
339
|
+
rb_ext_ractor_safe(PQisthreadsafe());
|
340
|
+
#endif
|
341
|
+
|
357
342
|
if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
|
358
343
|
/* Set all bits to disable all deprecation warnings. */
|
359
344
|
pg_skip_deprecation_warning = 0xFFFF;
|
@@ -372,8 +357,8 @@ Init_pg_ext(void)
|
|
372
357
|
SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
|
373
358
|
SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
|
374
359
|
|
375
|
-
|
376
|
-
|
360
|
+
rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
|
361
|
+
rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
|
377
362
|
|
378
363
|
|
379
364
|
/****** PG::Connection CLASS CONSTANTS: Connection Status ******/
|
@@ -419,6 +404,10 @@ Init_pg_ext(void)
|
|
419
404
|
/* Checking if server is in standby mode. Available since PostgreSQL-14. */
|
420
405
|
rb_define_const(rb_mPGconstants, "CONNECTION_CHECK_STANDBY", INT2FIX(CONNECTION_CHECK_STANDBY));
|
421
406
|
#endif
|
407
|
+
#if PG_MAJORVERSION_NUM >= 17
|
408
|
+
/* Waiting for connection attempt to be started. Available since PostgreSQL-17. */
|
409
|
+
rb_define_const(rb_mPGconstants, "CONNECTION_ALLOCATED", INT2FIX(CONNECTION_ALLOCATED));
|
410
|
+
#endif
|
422
411
|
|
423
412
|
/****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
|
424
413
|
|
@@ -466,14 +455,12 @@ Init_pg_ext(void)
|
|
466
455
|
rb_define_const(rb_mPGconstants, "PQERRORS_SQLSTATE", INT2FIX(PQERRORS_SQLSTATE));
|
467
456
|
#endif
|
468
457
|
|
469
|
-
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
470
458
|
/* See Connection#set_error_context_visibility */
|
471
459
|
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_NEVER", INT2FIX(PQSHOW_CONTEXT_NEVER));
|
472
460
|
/* See Connection#set_error_context_visibility */
|
473
461
|
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_ERRORS", INT2FIX(PQSHOW_CONTEXT_ERRORS));
|
474
462
|
/* See Connection#set_error_context_visibility */
|
475
463
|
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_ALWAYS", INT2FIX(PQSHOW_CONTEXT_ALWAYS));
|
476
|
-
#endif
|
477
464
|
|
478
465
|
/****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
|
479
466
|
|
@@ -521,6 +508,10 @@ Init_pg_ext(void)
|
|
521
508
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
|
522
509
|
/* Result#result_status constant - Single tuple from larger resultset. */
|
523
510
|
rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
|
511
|
+
#ifdef HAVE_PQSETCHUNKEDROWSMODE
|
512
|
+
/* Result#result_status constant - tuple chunk from larger resultset. */
|
513
|
+
rb_define_const(rb_mPGconstants, "PGRES_TUPLES_CHUNK", INT2FIX(PGRES_TUPLES_CHUNK));
|
514
|
+
#endif
|
524
515
|
|
525
516
|
#ifdef HAVE_PQENTERPIPELINEMODE
|
526
517
|
/* Result#result_status constant - The PG::Result represents a synchronization point in pipeline mode, requested by Connection#pipeline_sync.
|
@@ -545,20 +536,18 @@ Init_pg_ext(void)
|
|
545
536
|
*/
|
546
537
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY", INT2FIX(PG_DIAG_SEVERITY));
|
547
538
|
|
548
|
-
#ifdef PG_DIAG_SEVERITY_NONLOCALIZED
|
549
539
|
/* Result#result_error_field argument constant
|
550
540
|
*
|
551
541
|
* The severity; the field contents are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message).
|
552
542
|
* This is identical to the PG_DIAG_SEVERITY field except that the contents are never localized.
|
553
543
|
*
|
554
|
-
* Available since PostgreSQL-9.6
|
555
544
|
*/
|
556
545
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY_NONLOCALIZED", INT2FIX(PG_DIAG_SEVERITY_NONLOCALIZED));
|
557
|
-
|
546
|
+
|
558
547
|
/* Result#result_error_field argument constant
|
559
548
|
*
|
560
549
|
* The SQLSTATE code for the error.
|
561
|
-
* The SQLSTATE code
|
550
|
+
* The SQLSTATE code identifies the type of error that has occurred; it can be used by front-end applications to perform specific operations (such as error handling) in response to a particular database error.
|
562
551
|
* For a list of the possible SQLSTATE codes, see Appendix A.
|
563
552
|
* This field is not localizable, and is always present.
|
564
553
|
*/
|
@@ -682,11 +671,15 @@ Init_pg_ext(void)
|
|
682
671
|
/* PostgreSQL compiled in default port */
|
683
672
|
rb_define_const(rb_mPGconstants, "DEF_PGPORT", INT2FIX(DEF_PGPORT));
|
684
673
|
|
674
|
+
#ifdef PG_IS_BINARY_GEM
|
675
|
+
rb_define_const(rb_mPG, "IS_BINARY_GEM", Qtrue);
|
676
|
+
#else
|
677
|
+
rb_define_const(rb_mPG, "IS_BINARY_GEM", Qfalse);
|
678
|
+
#endif
|
679
|
+
|
685
680
|
/* Add the constants to the toplevel namespace */
|
686
681
|
rb_include_module( rb_mPG, rb_mPGconstants );
|
687
682
|
|
688
|
-
enc_pg2ruby = st_init_numtable();
|
689
|
-
|
690
683
|
/* Initialize the main extension classes */
|
691
684
|
init_pg_connection();
|
692
685
|
init_pg_result();
|
@@ -706,5 +699,5 @@ Init_pg_ext(void)
|
|
706
699
|
init_pg_copycoder();
|
707
700
|
init_pg_recordcoder();
|
708
701
|
init_pg_tuple();
|
702
|
+
init_pg_cancon();
|
709
703
|
}
|
710
|
-
|
data/ext/pg.h
CHANGED
@@ -76,19 +76,14 @@ typedef long suseconds_t;
|
|
76
76
|
#define PG_MAX_COLUMNS 4000
|
77
77
|
#endif
|
78
78
|
|
79
|
-
#ifndef RARRAY_AREF
|
80
|
-
#define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
|
81
|
-
#endif
|
82
|
-
|
83
|
-
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
84
|
-
#define pg_compact_callback(x) (x)
|
85
79
|
#define pg_gc_location(x) x = rb_gc_location(x)
|
80
|
+
|
81
|
+
/* For compatibility with ruby < 3.0 */
|
82
|
+
#ifndef RUBY_TYPED_FROZEN_SHAREABLE
|
83
|
+
#define PG_RUBY_TYPED_FROZEN_SHAREABLE 0
|
86
84
|
#else
|
87
|
-
#define
|
88
|
-
#define pg_compact_callback(x) {(x)}
|
89
|
-
#define pg_gc_location(x) UNUSED(x)
|
85
|
+
#define PG_RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
|
90
86
|
#endif
|
91
|
-
|
92
87
|
#define PG_ENC_IDX_BITS 28
|
93
88
|
|
94
89
|
/* The data behind each PG::Connection object */
|
@@ -97,6 +92,9 @@ typedef struct {
|
|
97
92
|
|
98
93
|
/* Cached IO object for the socket descriptor */
|
99
94
|
VALUE socket_io;
|
95
|
+
/* function pointers of the original libpq notice receivers */
|
96
|
+
PQnoticeReceiver default_notice_receiver;
|
97
|
+
PQnoticeProcessor default_notice_processor;
|
100
98
|
/* Proc object that receives notices as PG::Result objects */
|
101
99
|
VALUE notice_receiver;
|
102
100
|
/* Proc object that receives notices as String objects */
|
@@ -118,10 +116,8 @@ typedef struct {
|
|
118
116
|
/* enable automatic flushing of send data at the end of send_query calls */
|
119
117
|
unsigned int flush_data : 1;
|
120
118
|
|
121
|
-
#if defined(_WIN32)
|
122
119
|
/* File descriptor to be used for rb_w32_unwrap_io_handle() */
|
123
120
|
int ruby_sd;
|
124
|
-
#endif
|
125
121
|
} t_pg_connection;
|
126
122
|
|
127
123
|
typedef struct pg_coder t_pg_coder;
|
@@ -210,6 +206,7 @@ typedef struct {
|
|
210
206
|
t_pg_coder comp;
|
211
207
|
t_pg_coder *elem;
|
212
208
|
int needs_quotation;
|
209
|
+
int dimensions;
|
213
210
|
char delimiter;
|
214
211
|
} t_pg_composite_coder;
|
215
212
|
|
@@ -307,6 +304,7 @@ void init_pg_text_decoder _(( void ));
|
|
307
304
|
void init_pg_binary_encoder _(( void ));
|
308
305
|
void init_pg_binary_decoder _(( void ));
|
309
306
|
void init_pg_tuple _(( void ));
|
307
|
+
void init_pg_cancon _(( void ));
|
310
308
|
VALUE lookup_error_class _(( const char * ));
|
311
309
|
VALUE pg_bin_dec_bytea _(( t_pg_coder*, const char *, int, int, int, int ));
|
312
310
|
VALUE pg_text_dec_string _(( t_pg_coder*, const char *, int, int, int, int ));
|
@@ -314,7 +312,7 @@ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, c
|
|
314
312
|
int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
|
315
313
|
t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
|
316
314
|
t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
|
317
|
-
|
315
|
+
VALUE pg_define_coder _(( const char *, void *, VALUE, VALUE ));
|
318
316
|
VALUE pg_obj_to_i _(( VALUE ));
|
319
317
|
VALUE pg_tmbc_allocate _(( void ));
|
320
318
|
void pg_coder_init_encoder _(( VALUE ));
|
@@ -346,6 +344,13 @@ void pg_typemap_compact _(( void * ));
|
|
346
344
|
PGconn *pg_get_pgconn _(( VALUE ));
|
347
345
|
t_pg_connection *pg_get_connection _(( VALUE ));
|
348
346
|
VALUE pgconn_block _(( int, VALUE *, VALUE ));
|
347
|
+
#ifdef __GNUC__
|
348
|
+
__attribute__((format(printf, 3, 4)))
|
349
|
+
#endif
|
350
|
+
NORETURN(void pg_raise_conn_error _(( VALUE klass, VALUE self, const char *format, ...)));
|
351
|
+
VALUE pg_wrap_socket_io _(( int sd, VALUE self, VALUE *p_socket_io, int *p_ruby_sd ));
|
352
|
+
void pg_unwrap_socket_io _(( VALUE self, VALUE *p_socket_io, int ruby_sd ));
|
353
|
+
|
349
354
|
|
350
355
|
VALUE pg_new_result _(( PGresult *, VALUE ));
|
351
356
|
VALUE pg_new_result_autoclear _(( PGresult *, VALUE ));
|
@@ -364,7 +369,6 @@ pgresult_get_this( VALUE self )
|
|
364
369
|
}
|
365
370
|
|
366
371
|
|
367
|
-
rb_encoding * pg_get_pg_encoding_as_rb_encoding _(( int ));
|
368
372
|
rb_encoding * pg_get_pg_encname_as_rb_encoding _(( const char * ));
|
369
373
|
const char * pg_get_rb_encoding_as_pg_encoding _(( rb_encoding * ));
|
370
374
|
rb_encoding *pg_conn_enc_get _(( PGconn * ));
|