pg 1.6.0.rc1-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +4 -0
  3. data/BSDL +22 -0
  4. data/Contributors.rdoc +46 -0
  5. data/Gemfile +23 -0
  6. data/History.md +958 -0
  7. data/LICENSE +56 -0
  8. data/Manifest.txt +72 -0
  9. data/POSTGRES +23 -0
  10. data/README-OS_X.rdoc +68 -0
  11. data/README-Windows.rdoc +56 -0
  12. data/README.ja.md +300 -0
  13. data/README.md +286 -0
  14. data/Rakefile +161 -0
  15. data/certs/ged.pem +24 -0
  16. data/certs/kanis@comcard.de.pem +20 -0
  17. data/certs/larskanis-2022.pem +26 -0
  18. data/certs/larskanis-2023.pem +24 -0
  19. data/certs/larskanis-2024.pem +24 -0
  20. data/ext/errorcodes.def +1043 -0
  21. data/ext/errorcodes.rb +45 -0
  22. data/ext/errorcodes.txt +494 -0
  23. data/ext/extconf.rb +282 -0
  24. data/ext/gvl_wrappers.c +32 -0
  25. data/ext/gvl_wrappers.h +297 -0
  26. data/ext/pg.c +703 -0
  27. data/ext/pg.h +390 -0
  28. data/ext/pg_binary_decoder.c +460 -0
  29. data/ext/pg_binary_encoder.c +583 -0
  30. data/ext/pg_cancel_connection.c +360 -0
  31. data/ext/pg_coder.c +622 -0
  32. data/ext/pg_connection.c +4869 -0
  33. data/ext/pg_copy_coder.c +921 -0
  34. data/ext/pg_errors.c +95 -0
  35. data/ext/pg_record_coder.c +522 -0
  36. data/ext/pg_result.c +1764 -0
  37. data/ext/pg_text_decoder.c +1008 -0
  38. data/ext/pg_text_encoder.c +833 -0
  39. data/ext/pg_tuple.c +572 -0
  40. data/ext/pg_type_map.c +200 -0
  41. data/ext/pg_type_map_all_strings.c +130 -0
  42. data/ext/pg_type_map_by_class.c +271 -0
  43. data/ext/pg_type_map_by_column.c +355 -0
  44. data/ext/pg_type_map_by_mri_type.c +313 -0
  45. data/ext/pg_type_map_by_oid.c +388 -0
  46. data/ext/pg_type_map_in_ruby.c +333 -0
  47. data/ext/pg_util.c +149 -0
  48. data/ext/pg_util.h +65 -0
  49. data/ext/vc/pg.sln +26 -0
  50. data/ext/vc/pg_18/pg.vcproj +216 -0
  51. data/ext/vc/pg_19/pg_19.vcproj +209 -0
  52. data/lib/2.7/pg_ext.so +0 -0
  53. data/lib/3.0/pg_ext.so +0 -0
  54. data/lib/3.1/pg_ext.so +0 -0
  55. data/lib/3.2/pg_ext.so +0 -0
  56. data/lib/3.3/pg_ext.so +0 -0
  57. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  58. data/lib/pg/basic_type_map_for_queries.rb +202 -0
  59. data/lib/pg/basic_type_map_for_results.rb +104 -0
  60. data/lib/pg/basic_type_registry.rb +311 -0
  61. data/lib/pg/binary_decoder/date.rb +9 -0
  62. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  63. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  64. data/lib/pg/cancel_connection.rb +30 -0
  65. data/lib/pg/coder.rb +106 -0
  66. data/lib/pg/connection.rb +1027 -0
  67. data/lib/pg/exceptions.rb +31 -0
  68. data/lib/pg/result.rb +43 -0
  69. data/lib/pg/text_decoder/date.rb +21 -0
  70. data/lib/pg/text_decoder/inet.rb +9 -0
  71. data/lib/pg/text_decoder/json.rb +17 -0
  72. data/lib/pg/text_decoder/numeric.rb +9 -0
  73. data/lib/pg/text_decoder/timestamp.rb +30 -0
  74. data/lib/pg/text_encoder/date.rb +13 -0
  75. data/lib/pg/text_encoder/inet.rb +31 -0
  76. data/lib/pg/text_encoder/json.rb +17 -0
  77. data/lib/pg/text_encoder/numeric.rb +9 -0
  78. data/lib/pg/text_encoder/timestamp.rb +24 -0
  79. data/lib/pg/tuple.rb +30 -0
  80. data/lib/pg/type_map_by_column.rb +16 -0
  81. data/lib/pg/version.rb +4 -0
  82. data/lib/pg.rb +144 -0
  83. data/misc/openssl-pg-segfault.rb +31 -0
  84. data/misc/postgres/History.txt +9 -0
  85. data/misc/postgres/Manifest.txt +5 -0
  86. data/misc/postgres/README.txt +21 -0
  87. data/misc/postgres/Rakefile +21 -0
  88. data/misc/postgres/lib/postgres.rb +16 -0
  89. data/misc/ruby-pg/History.txt +9 -0
  90. data/misc/ruby-pg/Manifest.txt +5 -0
  91. data/misc/ruby-pg/README.txt +21 -0
  92. data/misc/ruby-pg/Rakefile +21 -0
  93. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  94. data/pg.gemspec +36 -0
  95. data/ports/x86_64-linux/lib/libpq-ruby-pg.so.1 +0 -0
  96. data/rakelib/task_extension.rb +46 -0
  97. data/sample/array_insert.rb +20 -0
  98. data/sample/async_api.rb +102 -0
  99. data/sample/async_copyto.rb +39 -0
  100. data/sample/async_mixed.rb +56 -0
  101. data/sample/check_conn.rb +21 -0
  102. data/sample/copydata.rb +71 -0
  103. data/sample/copyfrom.rb +81 -0
  104. data/sample/copyto.rb +19 -0
  105. data/sample/cursor.rb +21 -0
  106. data/sample/disk_usage_report.rb +177 -0
  107. data/sample/issue-119.rb +94 -0
  108. data/sample/losample.rb +69 -0
  109. data/sample/minimal-testcase.rb +17 -0
  110. data/sample/notify_wait.rb +72 -0
  111. data/sample/pg_statistics.rb +285 -0
  112. data/sample/replication_monitor.rb +222 -0
  113. data/sample/test_binary_values.rb +33 -0
  114. data/sample/wal_shipper.rb +434 -0
  115. data/sample/warehouse_partitions.rb +311 -0
  116. data.tar.gz.sig +0 -0
  117. metadata +252 -0
  118. metadata.gz.sig +0 -0
data/ext/extconf.rb ADDED
@@ -0,0 +1,282 @@
1
+ require 'pp'
2
+ require 'mkmf'
3
+
4
+ if ENV['MAINTAINER_MODE']
5
+ $stderr.puts "Maintainer mode enabled."
6
+ $CFLAGS <<
7
+ ' -Wall' <<
8
+ ' -ggdb' <<
9
+ ' -DDEBUG' <<
10
+ ' -pedantic'
11
+ $LDFLAGS <<
12
+ ' -ggdb'
13
+ end
14
+
15
+ if pgdir = with_config( 'pg' )
16
+ ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
17
+ end
18
+
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.4.0'
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.2'
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/
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/
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
+ end
95
+ # We specify -fcommon to get around duplicate definition errors in recent gcc.
96
+ # See https://github.com/cockroachdb/cockroach/issues/49734
97
+ recipe.configure_options << "CFLAGS=-fcommon#{" -fPIC" if RUBY_PLATFORM =~ /linux/}"
98
+ recipe.configure_options << "--without-keyutils"
99
+ recipe.host = toolchain
100
+ recipe.cook_and_activate
101
+ end
102
+ end
103
+
104
+ postgresql_recipe = BuildRecipe.new("postgresql", POSTGRESQL_VERSION, [POSTGRESQL_SOURCE_URI]).tap do |recipe|
105
+ class << recipe
106
+ def configure_defaults
107
+ [
108
+ "--target=#{host}",
109
+ "--host=#{host}",
110
+ '--with-openssl',
111
+ *(RUBY_PLATFORM=~/linux/ ? ['--with-gssapi'] : []),
112
+ '--without-zlib',
113
+ '--without-icu',
114
+ ]
115
+ end
116
+ def compile
117
+ execute 'compile include', "#{make_cmd} -C src/include install"
118
+ execute 'compile interfaces', "#{make_cmd} -C src/interfaces install"
119
+ end
120
+ def install
121
+ end
122
+ end
123
+
124
+ recipe.configure_options << "CFLAGS=#{" -fPIC" if RUBY_PLATFORM =~ /linux/}"
125
+ recipe.configure_options << "LDFLAGS=-L#{openssl_recipe.path}/lib -L#{openssl_recipe.path}/lib64 #{"-Wl,-soname,libpq-ruby-pg.so.1 -lgssapi_krb5 -lkrb5 -lk5crypto -lkrb5support" if RUBY_PLATFORM =~ /linux/}"
126
+ recipe.configure_options << "LIBS=-lkrb5 -lcom_err -lk5crypto -lkrb5support -lresolv" if RUBY_PLATFORM =~ /linux/
127
+ recipe.configure_options << "LIBS=-lssl -lwsock32 -lgdi32 -lws2_32 -lcrypt32" if RUBY_PLATFORM =~ /mingw|mswin/
128
+ recipe.configure_options << "CPPFLAGS=-I#{openssl_recipe.path}/include"
129
+ recipe.host = toolchain
130
+ recipe.cook_and_activate
131
+ end
132
+
133
+ # Use our own library name for libpq to avoid loading of system libpq by accident.
134
+ FileUtils.ln_sf File.join(postgresql_recipe.port_path, "lib/libpq.so.5"),
135
+ File.join(postgresql_recipe.port_path, "lib/libpq-ruby-pg.so.1")
136
+ # Avoid dependency to external libgcc.dll on x86-mingw32
137
+ $LDFLAGS << " -static-libgcc"
138
+ # Find libpq in the ports directory coming from lib/3.3
139
+ # It is shared between all compiled ruby versions.
140
+ $LDFLAGS << " '-Wl,-rpath=$$ORIGIN/../../ports/#{gem_platform}/lib'"
141
+ # Don't use pg_config for cross build, but --with-pg-* path options
142
+ dir_config('pg', "#{postgresql_recipe.path}/include", "#{postgresql_recipe.path}/lib")
143
+
144
+ $defs.push( "-DPG_IS_BINARY_GEM")
145
+ else
146
+ # Native build
147
+
148
+ pgconfig = with_config('pg-config') ||
149
+ with_config('pg_config') ||
150
+ find_executable('pg_config')
151
+
152
+ if pgconfig && pgconfig != 'ignore'
153
+ $stderr.puts "Using config values from %s" % [ pgconfig ]
154
+ incdir = IO.popen([pgconfig, "--includedir"], &:read).chomp
155
+ libdir = IO.popen([pgconfig, "--libdir"], &:read).chomp
156
+ dir_config 'pg', incdir, libdir
157
+
158
+ # Windows traditionally stores DLLs beside executables, not in libdir
159
+ dlldir = RUBY_PLATFORM=~/mingw|mswin/ ? IO.popen([pgconfig, "--bindir"], &:read).chomp : libdir
160
+
161
+ elsif checking_for "libpq per pkg-config" do
162
+ _cflags, ldflags, _libs = pkg_config("libpq")
163
+ dlldir = ldflags && ldflags[/-L([^ ]+)/] && $1
164
+ end
165
+
166
+ else
167
+ incdir, libdir = dir_config 'pg'
168
+ dlldir = libdir
169
+ end
170
+
171
+ # Try to use runtime path linker option, even if RbConfig doesn't know about it.
172
+ # The rpath option is usually set implicit by dir_config(), but so far not
173
+ # on MacOS-X.
174
+ if dlldir && RbConfig::CONFIG["RPATHFLAG"].to_s.empty?
175
+ append_ldflags "-Wl,-rpath,#{dlldir.quote}"
176
+ end
177
+
178
+ if /mswin/ =~ RUBY_PLATFORM
179
+ $libs = append_library($libs, 'ws2_32')
180
+ end
181
+ end
182
+
183
+ $stderr.puts "Using libpq from #{dlldir}"
184
+
185
+ File.write("postgresql_lib_path.rb", <<-EOT)
186
+ module PG
187
+ POSTGRESQL_LIB_PATH = #{dlldir.inspect}
188
+ end
189
+ EOT
190
+ $INSTALLFILES = {
191
+ "./postgresql_lib_path.rb" => "$(RUBYLIBDIR)/pg/"
192
+ }
193
+
194
+ if /solaris/ =~ RUBY_PLATFORM
195
+ append_cppflags( '-D__EXTENSIONS__' )
196
+ end
197
+
198
+ begin
199
+ find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
200
+ find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
201
+ find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
202
+
203
+ abort "Can't find the PostgreSQL client library (libpq)" unless
204
+ have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
205
+ have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
206
+ have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
207
+
208
+ rescue SystemExit
209
+ install_text = case RUBY_PLATFORM
210
+ when /linux/
211
+ <<-EOT
212
+ Please install libpq or postgresql client package like so:
213
+ sudo apt install libpq-dev
214
+ sudo yum install postgresql-devel
215
+ sudo zypper in postgresql-devel
216
+ sudo pacman -S postgresql-libs
217
+ EOT
218
+ when /darwin/
219
+ <<-EOT
220
+ Please install libpq or postgresql client package like so:
221
+ brew install libpq
222
+ EOT
223
+ when /mingw/
224
+ <<-EOT
225
+ Please install libpq or postgresql client package like so:
226
+ ridk exec sh -c "pacman -S ${MINGW_PACKAGE_PREFIX}-postgresql"
227
+ EOT
228
+ else
229
+ <<-EOT
230
+ Please install libpq or postgresql client package.
231
+ EOT
232
+ end
233
+
234
+ $stderr.puts <<-EOT
235
+ *****************************************************************************
236
+
237
+ Unable to find PostgreSQL client library.
238
+
239
+ #{install_text}
240
+ or try again with:
241
+ gem install pg -- --with-pg-config=/path/to/pg_config
242
+
243
+ or set library paths manually with:
244
+ gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/
245
+
246
+ EOT
247
+ raise
248
+ end
249
+
250
+ if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
251
+ # Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
252
+ checking_for "workaround gcc version with link issue" do
253
+ `#{RbConfig::MAKEFILE_CONFIG['CC']} --version`.chomp =~ /\s(\d+)\.\d+\.\d+(\s|$)/ &&
254
+ $1.to_i >= 6 &&
255
+ have_library(':libpq.lib') # Prefer linking to libpq.lib over libpq.dll if available
256
+ end
257
+ end
258
+
259
+ have_func 'PQencryptPasswordConn', 'libpq-fe.h' or # since PostgreSQL-10
260
+ abort "Your PostgreSQL is too old. Either install an older version " +
261
+ "of this gem or upgrade your database to at least PostgreSQL-10."
262
+ # optional headers/functions
263
+ have_func 'PQresultMemorySize', 'libpq-fe.h' # since PostgreSQL-12
264
+ have_func 'PQenterPipelineMode', 'libpq-fe.h' do |src| # since PostgreSQL-14
265
+ # Ensure header files fit as well
266
+ src + " int con(){ return PGRES_PIPELINE_SYNC; }"
267
+ end
268
+ have_func 'PQsetChunkedRowsMode', 'libpq-fe.h' # since PostgreSQL-17
269
+ have_func 'timegm'
270
+ have_func 'rb_io_wait' # since ruby-3.0
271
+ have_func 'rb_io_descriptor' # since ruby-3.1
272
+
273
+ have_header 'inttypes.h'
274
+ have_header('ruby/fiber/scheduler.h') if RUBY_PLATFORM=~/mingw|mswin/
275
+
276
+ checking_for "C99 variable length arrays" do
277
+ $defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
278
+ end
279
+
280
+ create_header()
281
+ create_makefile( "pg_ext" )
282
+
@@ -0,0 +1,32 @@
1
+ /*
2
+ * gvl_wrappers.c - Wrapper functions for locking/unlocking the Ruby GVL
3
+ *
4
+ */
5
+
6
+ #include "pg.h"
7
+
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;}
21
+ #endif
22
+
23
+ #ifdef ENABLE_GVL_UNLOCK
24
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
25
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
26
+ #endif
27
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
28
+ #ifdef ENABLE_GVL_UNLOCK
29
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
30
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_SKELETON );
31
+ #endif
32
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB );
@@ -0,0 +1,297 @@
1
+ /*
2
+ * gvl_wrappers.h - Wrapper functions for locking/unlocking the Ruby GVL
3
+ *
4
+ * These are some obscure preprocessor directives that allow to generate
5
+ * drop-in replacement wrapper functions in a declarative manner.
6
+ * These wrapper functions ensure that ruby's GVL is released on each
7
+ * function call and reacquired at the end of the call or in callbacks.
8
+ * This way blocking functions calls don't block concurrent ruby threads.
9
+ *
10
+ * The wrapper of each function is prefixed by "gvl_".
11
+ *
12
+ * Use "gcc -E" to retrieve the generated code.
13
+ */
14
+
15
+ #ifndef __gvl_wrappers_h
16
+ #define __gvl_wrappers_h
17
+
18
+ #include <ruby/thread.h>
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
+
28
+ #define DEFINE_PARAM_LIST1(type, name) \
29
+ name,
30
+
31
+ #define DEFINE_PARAM_LIST2(type, name) \
32
+ p->params.name,
33
+
34
+ #define DEFINE_PARAM_LIST3(type, name) \
35
+ type name,
36
+
37
+ #define DEFINE_PARAM_DECL(type, name) \
38
+ type name;
39
+
40
+ #define DEFINE_GVL_WRAPPER_STRUCT(name, when_non_void, rettype, lastparamtype, lastparamname) \
41
+ struct gvl_wrapper_##name##_params { \
42
+ struct { \
43
+ FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_DECL) \
44
+ lastparamtype lastparamname; \
45
+ } params; \
46
+ when_non_void( rettype retval; ) \
47
+ };
48
+
49
+ #define DEFINE_GVL_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
50
+ static void * gvl_##name##_skeleton( void *data ){ \
51
+ struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
52
+ when_non_void( p->retval = ) \
53
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \
54
+ return NULL; \
55
+ }
56
+
57
+ #ifdef ENABLE_GVL_UNLOCK
58
+ #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
59
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
60
+ struct gvl_wrapper_##name##_params params = { \
61
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
62
+ }; \
63
+ rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
64
+ when_non_void( return params.retval; ) \
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
73
+
74
+ #define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
75
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
76
+
77
+ #define DEFINE_GVLCB_SKELETON(name, when_non_void, rettype, lastparamtype, lastparamname) \
78
+ static void * gvl_##name##_skeleton( void *data ){ \
79
+ struct gvl_wrapper_##name##_params *p = (struct gvl_wrapper_##name##_params*)data; \
80
+ when_non_void( p->retval = ) \
81
+ name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST2) p->params.lastparamname ); \
82
+ return NULL; \
83
+ }
84
+
85
+ #ifdef ENABLE_GVL_UNLOCK
86
+ #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
87
+ rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
88
+ struct gvl_wrapper_##name##_params params = { \
89
+ {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
90
+ }; \
91
+ rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
92
+ when_non_void( return params.retval; ) \
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
101
+
102
+ #define GVL_TYPE_VOID(string)
103
+ #define GVL_TYPE_NONVOID(string) string
104
+
105
+
106
+ /*
107
+ * Definitions of blocking functions and their parameters
108
+ */
109
+
110
+ #define FOR_EACH_PARAM_OF_PQconnectdb(param)
111
+
112
+ #define FOR_EACH_PARAM_OF_PQconnectStart(param)
113
+
114
+ #define FOR_EACH_PARAM_OF_PQconnectPoll(param)
115
+
116
+ #define FOR_EACH_PARAM_OF_PQreset(param)
117
+
118
+ #define FOR_EACH_PARAM_OF_PQresetStart(param)
119
+
120
+ #define FOR_EACH_PARAM_OF_PQresetPoll(param)
121
+
122
+ #define FOR_EACH_PARAM_OF_PQping(param)
123
+
124
+ #define FOR_EACH_PARAM_OF_PQexec(param) \
125
+ param(PGconn *, conn)
126
+
127
+ #define FOR_EACH_PARAM_OF_PQexecParams(param) \
128
+ param(PGconn *, conn) \
129
+ param(const char *, command) \
130
+ param(int, nParams) \
131
+ param(const Oid *, paramTypes) \
132
+ param(const char * const *, paramValues) \
133
+ param(const int *, paramLengths) \
134
+ param(const int *, paramFormats)
135
+
136
+ #define FOR_EACH_PARAM_OF_PQexecPrepared(param) \
137
+ param(PGconn *, conn) \
138
+ param(const char *, stmtName) \
139
+ param(int, nParams) \
140
+ param(const char * const *, paramValues) \
141
+ param(const int *, paramLengths) \
142
+ param(const int *, paramFormats)
143
+
144
+ #define FOR_EACH_PARAM_OF_PQprepare(param) \
145
+ param(PGconn *, conn) \
146
+ param(const char *, stmtName) \
147
+ param(const char *, query) \
148
+ param(int, nParams)
149
+
150
+ #define FOR_EACH_PARAM_OF_PQdescribePrepared(param) \
151
+ param(PGconn *, conn)
152
+
153
+ #define FOR_EACH_PARAM_OF_PQdescribePortal(param) \
154
+ param(PGconn *, conn)
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
+
162
+ #define FOR_EACH_PARAM_OF_PQgetResult(param)
163
+
164
+ #define FOR_EACH_PARAM_OF_PQputCopyData(param) \
165
+ param(PGconn *, conn) \
166
+ param(const char *, buffer)
167
+
168
+ #define FOR_EACH_PARAM_OF_PQputCopyEnd(param) \
169
+ param(PGconn *, conn)
170
+
171
+ #define FOR_EACH_PARAM_OF_PQgetCopyData(param) \
172
+ param(PGconn *, conn) \
173
+ param(char **, buffer)
174
+
175
+ #define FOR_EACH_PARAM_OF_PQnotifies(param)
176
+
177
+ #define FOR_EACH_PARAM_OF_PQsendQuery(param) \
178
+ param(PGconn *, conn)
179
+
180
+ #define FOR_EACH_PARAM_OF_PQsendQueryParams(param) \
181
+ param(PGconn *, conn) \
182
+ param(const char *, command) \
183
+ param(int, nParams) \
184
+ param(const Oid *, paramTypes) \
185
+ param(const char *const *, paramValues) \
186
+ param(const int *, paramLengths) \
187
+ param(const int *, paramFormats)
188
+
189
+ #define FOR_EACH_PARAM_OF_PQsendPrepare(param) \
190
+ param(PGconn *, conn) \
191
+ param(const char *, stmtName) \
192
+ param(const char *, query) \
193
+ param(int, nParams)
194
+
195
+ #define FOR_EACH_PARAM_OF_PQsendQueryPrepared(param) \
196
+ param(PGconn *, conn) \
197
+ param(const char *, stmtName) \
198
+ param(int, nParams) \
199
+ param(const char *const *, paramValues) \
200
+ param(const int *, paramLengths) \
201
+ param(const int *, paramFormats)
202
+
203
+ #define FOR_EACH_PARAM_OF_PQsendDescribePrepared(param) \
204
+ param(PGconn *, conn)
205
+
206
+ #define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
207
+ param(PGconn *, conn)
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
+
219
+ #define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
220
+ param(PGconn *, conn)
221
+
222
+ #define FOR_EACH_PARAM_OF_PQisBusy(param)
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
+
228
+ #define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
229
+ param(PGconn *, conn) \
230
+ param(const char *, passwd) \
231
+ param(const char *, user)
232
+
233
+ #define FOR_EACH_PARAM_OF_PQcancel(param) \
234
+ param(PGcancel *, cancel) \
235
+ param(char *, errbuf)
236
+
237
+ /* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
238
+ #define FOR_EACH_BLOCKING_FUNCTION(function) \
239
+ function(PQconnectdb, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
240
+ function(PQconnectStart, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
241
+ function(PQconnectPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
242
+ function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
243
+ function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
244
+ function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
245
+ function(PQping, GVL_TYPE_NONVOID, PGPing, const char *, conninfo) \
246
+ function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
247
+ function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
248
+ function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
249
+ function(PQprepare, GVL_TYPE_NONVOID, PGresult *, const Oid *, paramTypes) \
250
+ function(PQdescribePrepared, GVL_TYPE_NONVOID, PGresult *, const char *, stmtName) \
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) \
254
+ function(PQgetResult, GVL_TYPE_NONVOID, PGresult *, PGconn *, conn) \
255
+ function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
256
+ function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
257
+ function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
258
+ function(PQnotifies, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
259
+ function(PQsendQuery, GVL_TYPE_NONVOID, int, const char *, query) \
260
+ function(PQsendQueryParams, GVL_TYPE_NONVOID, int, int, resultFormat) \
261
+ function(PQsendPrepare, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
262
+ function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
263
+ function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
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) \
269
+ function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
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) \
274
+ function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
275
+ function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
276
+
277
+ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
278
+
279
+
280
+ /*
281
+ * Definitions of callback functions and their parameters
282
+ */
283
+
284
+ #define FOR_EACH_PARAM_OF_notice_processor_proxy(param) \
285
+ param(void *, arg)
286
+
287
+ #define FOR_EACH_PARAM_OF_notice_receiver_proxy(param) \
288
+ param(void *, arg)
289
+
290
+ /* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
291
+ #define FOR_EACH_CALLBACK_FUNCTION(function) \
292
+ function(notice_processor_proxy, GVL_TYPE_VOID, void, const char *, message) \
293
+ function(notice_receiver_proxy, GVL_TYPE_VOID, void, const PGresult *, result) \
294
+
295
+ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVL_STUB_DECL );
296
+
297
+ #endif /* end __gvl_wrappers_h */