pg 0.15.1 → 1.2.3
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/BSDL +2 -2
- data/ChangeLog +0 -3022
- data/History.rdoc +370 -4
- data/Manifest.txt +39 -19
- data/README-Windows.rdoc +17 -28
- data/README.ja.rdoc +1 -2
- data/README.rdoc +113 -14
- data/Rakefile +97 -36
- data/Rakefile.cross +109 -83
- data/ext/errorcodes.def +1032 -0
- data/ext/errorcodes.rb +45 -0
- data/ext/errorcodes.txt +494 -0
- data/ext/extconf.rb +55 -52
- data/ext/gvl_wrappers.c +4 -0
- data/ext/gvl_wrappers.h +94 -38
- data/ext/pg.c +273 -121
- data/ext/pg.h +292 -50
- data/ext/pg_binary_decoder.c +229 -0
- data/ext/pg_binary_encoder.c +163 -0
- data/ext/pg_coder.c +561 -0
- data/ext/pg_connection.c +1811 -1051
- data/ext/pg_copy_coder.c +599 -0
- data/ext/pg_errors.c +95 -0
- data/ext/pg_record_coder.c +491 -0
- data/ext/pg_result.c +917 -203
- data/ext/pg_text_decoder.c +987 -0
- data/ext/pg_text_encoder.c +814 -0
- data/ext/pg_tuple.c +549 -0
- data/ext/pg_type_map.c +166 -0
- data/ext/pg_type_map_all_strings.c +116 -0
- data/ext/pg_type_map_by_class.c +244 -0
- data/ext/pg_type_map_by_column.c +313 -0
- data/ext/pg_type_map_by_mri_type.c +284 -0
- data/ext/pg_type_map_by_oid.c +356 -0
- data/ext/pg_type_map_in_ruby.c +299 -0
- data/ext/pg_util.c +149 -0
- data/ext/pg_util.h +65 -0
- data/lib/pg.rb +31 -9
- data/lib/pg/basic_type_mapping.rb +522 -0
- data/lib/pg/binary_decoder.rb +23 -0
- data/lib/pg/coder.rb +104 -0
- data/lib/pg/connection.rb +235 -30
- data/lib/pg/constants.rb +2 -1
- data/lib/pg/exceptions.rb +2 -1
- data/lib/pg/result.rb +33 -6
- data/lib/pg/text_decoder.rb +46 -0
- data/lib/pg/text_encoder.rb +59 -0
- data/lib/pg/tuple.rb +30 -0
- data/lib/pg/type_map_by_column.rb +16 -0
- data/spec/{lib/helpers.rb → helpers.rb} +154 -52
- data/spec/pg/basic_type_mapping_spec.rb +630 -0
- data/spec/pg/connection_spec.rb +1352 -426
- data/spec/pg/connection_sync_spec.rb +41 -0
- data/spec/pg/result_spec.rb +508 -105
- data/spec/pg/tuple_spec.rb +333 -0
- data/spec/pg/type_map_by_class_spec.rb +138 -0
- data/spec/pg/type_map_by_column_spec.rb +226 -0
- data/spec/pg/type_map_by_mri_type_spec.rb +136 -0
- data/spec/pg/type_map_by_oid_spec.rb +149 -0
- data/spec/pg/type_map_in_ruby_spec.rb +164 -0
- data/spec/pg/type_map_spec.rb +22 -0
- data/spec/pg/type_spec.rb +1123 -0
- data/spec/pg_spec.rb +35 -16
- metadata +163 -84
- metadata.gz.sig +0 -0
- data/sample/array_insert.rb +0 -20
- data/sample/async_api.rb +0 -106
- data/sample/async_copyto.rb +0 -39
- data/sample/async_mixed.rb +0 -56
- data/sample/check_conn.rb +0 -21
- data/sample/copyfrom.rb +0 -81
- data/sample/copyto.rb +0 -19
- data/sample/cursor.rb +0 -21
- data/sample/disk_usage_report.rb +0 -186
- data/sample/issue-119.rb +0 -94
- data/sample/losample.rb +0 -69
- data/sample/minimal-testcase.rb +0 -17
- data/sample/notify_wait.rb +0 -72
- data/sample/pg_statistics.rb +0 -294
- data/sample/replication_monitor.rb +0 -231
- data/sample/test_binary_values.rb +0 -33
- data/sample/wal_shipper.rb +0 -434
- data/sample/warehouse_partitions.rb +0 -320
data/ext/extconf.rb
CHANGED
@@ -15,29 +15,40 @@ if pgdir = with_config( 'pg' )
|
|
15
15
|
ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
|
16
16
|
end
|
17
17
|
|
18
|
-
if
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
|
23
|
-
have_library( 'gdi32', 'CreateDC' ) && append_library( $libs, 'gdi32' )
|
24
|
-
have_library( 'secur32' ) && append_library( $libs, 'secur32' )
|
25
|
-
have_library( 'ws2_32', 'WSASocket') && append_library( $libs, 'ws2_32' )
|
26
|
-
have_library( 'crypto', 'BIO_new' ) && append_library( $libs, 'crypto' )
|
27
|
-
have_library( 'ssl', 'SSL_new' ) && append_library( $libs, 'ssl' )
|
28
|
-
end
|
29
|
-
|
30
|
-
dir_config 'pg'
|
31
|
-
|
32
|
-
if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
|
33
|
-
$stderr.puts "Using config values from %s" % [ pgconfig ]
|
34
|
-
$CPPFLAGS << " -I%s" % [ `"#{pgconfig}" --includedir`.chomp ]
|
18
|
+
if enable_config("windows-cross")
|
19
|
+
# Avoid dependency to external libgcc.dll on x86-mingw32
|
20
|
+
$LDFLAGS << " -static-libgcc"
|
21
|
+
# Don't use pg_config for cross build, but --with-pg-* path options
|
22
|
+
dir_config 'pg'
|
35
23
|
|
36
|
-
libdir = `"#{pgconfig}" --libdir`.chomp
|
37
|
-
$LDFLAGS << " -L%s -Wl,-rpath,%s" % [ libdir, libdir ]
|
38
24
|
else
|
39
|
-
|
40
|
-
|
25
|
+
# Native build
|
26
|
+
|
27
|
+
pgconfig = with_config('pg-config') ||
|
28
|
+
with_config('pg_config') ||
|
29
|
+
find_executable('pg_config')
|
30
|
+
|
31
|
+
if pgconfig && pgconfig != 'ignore'
|
32
|
+
$stderr.puts "Using config values from %s" % [ pgconfig ]
|
33
|
+
incdir = `"#{pgconfig}" --includedir`.chomp
|
34
|
+
libdir = `"#{pgconfig}" --libdir`.chomp
|
35
|
+
dir_config 'pg', incdir, libdir
|
36
|
+
|
37
|
+
# Try to use runtime path linker option, even if RbConfig doesn't know about it.
|
38
|
+
# The rpath option is usually set implicit by dir_config(), but so far not
|
39
|
+
# on MacOS-X.
|
40
|
+
if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', " -Wl,-rpath,#{libdir}")
|
41
|
+
$LDFLAGS << " -Wl,-rpath,#{libdir}"
|
42
|
+
end
|
43
|
+
else
|
44
|
+
$stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
|
45
|
+
" --with-pg-config=/path/to/pg_config"
|
46
|
+
dir_config 'pg'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if RUBY_VERSION >= '2.3.0' && /solaris/ =~ RUBY_PLATFORM
|
51
|
+
append_cppflags( '-D__EXTENSIONS__' )
|
41
52
|
end
|
42
53
|
|
43
54
|
find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
|
@@ -49,42 +60,34 @@ abort "Can't find the PostgreSQL client library (libpq)" unless
|
|
49
60
|
have_library( 'libpq', 'PQconnectdb', ['libpq-fe.h'] ) ||
|
50
61
|
have_library( 'ms/libpq', 'PQconnectdb', ['libpq-fe.h'] )
|
51
62
|
|
63
|
+
if /mingw/ =~ RUBY_PLATFORM && RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
|
64
|
+
# Work around: https://sourceware.org/bugzilla/show_bug.cgi?id=22504
|
65
|
+
checking_for "workaround gcc version with link issue" do
|
66
|
+
`#{RbConfig::MAKEFILE_CONFIG['CC']} --version`.chomp =~ /\s(\d+)\.\d+\.\d+(\s|$)/ &&
|
67
|
+
$1.to_i >= 6 &&
|
68
|
+
have_library(':libpq.lib') # Prefer linking to libpq.lib over libpq.dll if available
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
52
72
|
# optional headers/functions
|
53
|
-
have_func '
|
73
|
+
have_func 'PQsetSingleRowMode' or
|
54
74
|
abort "Your PostgreSQL is too old. Either install an older version " +
|
55
|
-
"of this gem or upgrade your database."
|
56
|
-
have_func '
|
57
|
-
have_func '
|
58
|
-
have_func '
|
59
|
-
have_func '
|
60
|
-
have_func '
|
61
|
-
have_func '
|
62
|
-
have_func '
|
63
|
-
have_func 'PQgetCancel'
|
64
|
-
have_func 'lo_create'
|
65
|
-
have_func 'pg_encoding_to_char'
|
66
|
-
have_func 'pg_char_to_encoding'
|
67
|
-
have_func 'PQsetClientEncoding'
|
68
|
-
have_func 'PQlibVersion'
|
69
|
-
have_func 'PQping'
|
70
|
-
have_func 'PQsetSingleRowMode'
|
71
|
-
|
72
|
-
have_func 'rb_encdb_alias'
|
73
|
-
have_func 'rb_enc_alias'
|
74
|
-
have_func 'rb_thread_call_without_gvl'
|
75
|
-
have_func 'rb_thread_call_with_gvl'
|
76
|
-
have_func 'rb_thread_fd_select'
|
77
|
-
have_func 'rb_w32_wrap_io_handle'
|
78
|
-
|
79
|
-
have_const 'PGRES_COPY_BOTH', 'libpq-fe.h'
|
80
|
-
have_const 'PGRES_SINGLE_TUPLE', 'libpq-fe.h'
|
81
|
-
|
82
|
-
$defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
|
83
|
-
have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
|
75
|
+
"of this gem or upgrade your database to at least PostgreSQL-9.2."
|
76
|
+
have_func 'PQconninfo' # since PostgreSQL-9.3
|
77
|
+
have_func 'PQsslAttribute' # since PostgreSQL-9.5
|
78
|
+
have_func 'PQresultVerboseErrorMessage' # since PostgreSQL-9.6
|
79
|
+
have_func 'PQencryptPasswordConn' # since PostgreSQL-10
|
80
|
+
have_func 'PQresultMemorySize' # since PostgreSQL-12
|
81
|
+
have_func 'timegm'
|
82
|
+
have_func 'rb_gc_adjust_memory_usage' # since ruby-2.4
|
84
83
|
|
85
84
|
# unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
|
86
85
|
have_header 'unistd.h'
|
87
|
-
have_header '
|
86
|
+
have_header 'inttypes.h'
|
87
|
+
|
88
|
+
checking_for "C99 variable length arrays" do
|
89
|
+
$defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }')
|
90
|
+
end
|
88
91
|
|
89
92
|
create_header()
|
90
93
|
create_makefile( "pg_ext" )
|
data/ext/gvl_wrappers.c
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
|
6
6
|
#include "pg.h"
|
7
7
|
|
8
|
+
#ifndef HAVE_PQENCRYPTPASSWORDCONN
|
9
|
+
char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm){return NULL;}
|
10
|
+
#endif
|
11
|
+
|
8
12
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_WRAPPER_STRUCT );
|
9
13
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_SKELETON );
|
10
14
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB );
|
data/ext/gvl_wrappers.h
CHANGED
@@ -15,14 +15,7 @@
|
|
15
15
|
#ifndef __gvl_wrappers_h
|
16
16
|
#define __gvl_wrappers_h
|
17
17
|
|
18
|
-
#
|
19
|
-
extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
23
|
-
extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
24
|
-
rb_unblock_function_t *ubf, void *data2);
|
25
|
-
#endif
|
18
|
+
#include <ruby/thread.h>
|
26
19
|
|
27
20
|
#define DEFINE_PARAM_LIST1(type, name) \
|
28
21
|
name,
|
@@ -53,21 +46,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
53
46
|
return NULL; \
|
54
47
|
}
|
55
48
|
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
}
|
65
|
-
#else
|
66
|
-
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
67
|
-
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
68
|
-
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
69
|
-
}
|
70
|
-
#endif
|
49
|
+
#define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
50
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
51
|
+
struct gvl_wrapper_##name##_params params = { \
|
52
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
53
|
+
}; \
|
54
|
+
rb_thread_call_without_gvl(gvl_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \
|
55
|
+
when_non_void( return params.retval; ) \
|
56
|
+
}
|
71
57
|
|
72
58
|
#define DEFINE_GVL_STUB_DECL(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
73
59
|
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname);
|
@@ -80,21 +66,14 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
80
66
|
return NULL; \
|
81
67
|
}
|
82
68
|
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
#else
|
93
|
-
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
94
|
-
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
95
|
-
return name( FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname ); \
|
96
|
-
}
|
97
|
-
#endif
|
69
|
+
#define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
|
70
|
+
rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
|
71
|
+
struct gvl_wrapper_##name##_params params = { \
|
72
|
+
{FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
|
73
|
+
}; \
|
74
|
+
rb_thread_call_with_gvl(gvl_##name##_skeleton, ¶ms); \
|
75
|
+
when_non_void( return params.retval; ) \
|
76
|
+
}
|
98
77
|
|
99
78
|
#define GVL_TYPE_VOID(string)
|
100
79
|
#define GVL_TYPE_NONVOID(string) string
|
@@ -104,6 +83,18 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
104
83
|
* Definitions of blocking functions and their parameters
|
105
84
|
*/
|
106
85
|
|
86
|
+
#define FOR_EACH_PARAM_OF_PQconnectdb(param)
|
87
|
+
|
88
|
+
#define FOR_EACH_PARAM_OF_PQconnectStart(param)
|
89
|
+
|
90
|
+
#define FOR_EACH_PARAM_OF_PQconnectPoll(param)
|
91
|
+
|
92
|
+
#define FOR_EACH_PARAM_OF_PQreset(param)
|
93
|
+
|
94
|
+
#define FOR_EACH_PARAM_OF_PQresetStart(param)
|
95
|
+
|
96
|
+
#define FOR_EACH_PARAM_OF_PQresetPoll(param)
|
97
|
+
|
107
98
|
#define FOR_EACH_PARAM_OF_PQexec(param) \
|
108
99
|
param(PGconn *, conn)
|
109
100
|
|
@@ -149,8 +140,62 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
149
140
|
param(PGconn *, conn) \
|
150
141
|
param(char **, buffer)
|
151
142
|
|
143
|
+
#define FOR_EACH_PARAM_OF_PQnotifies(param)
|
144
|
+
|
145
|
+
#define FOR_EACH_PARAM_OF_PQsendQuery(param) \
|
146
|
+
param(PGconn *, conn)
|
147
|
+
|
148
|
+
#define FOR_EACH_PARAM_OF_PQsendQueryParams(param) \
|
149
|
+
param(PGconn *, conn) \
|
150
|
+
param(const char *, command) \
|
151
|
+
param(int, nParams) \
|
152
|
+
param(const Oid *, paramTypes) \
|
153
|
+
param(const char *const *, paramValues) \
|
154
|
+
param(const int *, paramLengths) \
|
155
|
+
param(const int *, paramFormats)
|
156
|
+
|
157
|
+
#define FOR_EACH_PARAM_OF_PQsendPrepare(param) \
|
158
|
+
param(PGconn *, conn) \
|
159
|
+
param(const char *, stmtName) \
|
160
|
+
param(const char *, query) \
|
161
|
+
param(int, nParams)
|
162
|
+
|
163
|
+
#define FOR_EACH_PARAM_OF_PQsendQueryPrepared(param) \
|
164
|
+
param(PGconn *, conn) \
|
165
|
+
param(const char *, stmtName) \
|
166
|
+
param(int, nParams) \
|
167
|
+
param(const char *const *, paramValues) \
|
168
|
+
param(const int *, paramLengths) \
|
169
|
+
param(const int *, paramFormats)
|
170
|
+
|
171
|
+
#define FOR_EACH_PARAM_OF_PQsendDescribePrepared(param) \
|
172
|
+
param(PGconn *, conn)
|
173
|
+
|
174
|
+
#define FOR_EACH_PARAM_OF_PQsendDescribePortal(param) \
|
175
|
+
param(PGconn *, conn)
|
176
|
+
|
177
|
+
#define FOR_EACH_PARAM_OF_PQsetClientEncoding(param) \
|
178
|
+
param(PGconn *, conn)
|
179
|
+
|
180
|
+
#define FOR_EACH_PARAM_OF_PQisBusy(param)
|
181
|
+
|
182
|
+
#define FOR_EACH_PARAM_OF_PQencryptPasswordConn(param) \
|
183
|
+
param(PGconn *, conn) \
|
184
|
+
param(const char *, passwd) \
|
185
|
+
param(const char *, user)
|
186
|
+
|
187
|
+
#define FOR_EACH_PARAM_OF_PQcancel(param) \
|
188
|
+
param(PGcancel *, cancel) \
|
189
|
+
param(char *, errbuf)
|
190
|
+
|
152
191
|
/* function( name, void_or_nonvoid, returntype, lastparamtype, lastparamname ) */
|
153
192
|
#define FOR_EACH_BLOCKING_FUNCTION(function) \
|
193
|
+
function(PQconnectdb, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
194
|
+
function(PQconnectStart, GVL_TYPE_NONVOID, PGconn *, const char *, conninfo) \
|
195
|
+
function(PQconnectPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
196
|
+
function(PQreset, GVL_TYPE_VOID, void, PGconn *, conn) \
|
197
|
+
function(PQresetStart, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
198
|
+
function(PQresetPoll, GVL_TYPE_NONVOID, PostgresPollingStatusType, PGconn *, conn) \
|
154
199
|
function(PQexec, GVL_TYPE_NONVOID, PGresult *, const char *, command) \
|
155
200
|
function(PQexecParams, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
156
201
|
function(PQexecPrepared, GVL_TYPE_NONVOID, PGresult *, int, resultFormat) \
|
@@ -161,6 +206,17 @@ extern void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
|
|
161
206
|
function(PQputCopyData, GVL_TYPE_NONVOID, int, int, nbytes) \
|
162
207
|
function(PQputCopyEnd, GVL_TYPE_NONVOID, int, const char *, errormsg) \
|
163
208
|
function(PQgetCopyData, GVL_TYPE_NONVOID, int, int, async) \
|
209
|
+
function(PQnotifies, GVL_TYPE_NONVOID, PGnotify *, PGconn *, conn) \
|
210
|
+
function(PQsendQuery, GVL_TYPE_NONVOID, int, const char *, query) \
|
211
|
+
function(PQsendQueryParams, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
212
|
+
function(PQsendPrepare, GVL_TYPE_NONVOID, int, const Oid *, paramTypes) \
|
213
|
+
function(PQsendQueryPrepared, GVL_TYPE_NONVOID, int, int, resultFormat) \
|
214
|
+
function(PQsendDescribePrepared, GVL_TYPE_NONVOID, int, const char *, stmt) \
|
215
|
+
function(PQsendDescribePortal, GVL_TYPE_NONVOID, int, const char *, portal) \
|
216
|
+
function(PQsetClientEncoding, GVL_TYPE_NONVOID, int, const char *, encoding) \
|
217
|
+
function(PQisBusy, GVL_TYPE_NONVOID, int, PGconn *, conn) \
|
218
|
+
function(PQencryptPasswordConn, GVL_TYPE_NONVOID, char *, const char *, algorithm) \
|
219
|
+
function(PQcancel, GVL_TYPE_NONVOID, int, int, errbufsize);
|
164
220
|
|
165
221
|
FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL );
|
166
222
|
|
data/ext/pg.c
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
/*
|
2
2
|
* pg.c - Toplevel extension
|
3
|
-
* $Id
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
* Author/s:
|
6
6
|
*
|
7
7
|
* - Jeff Davis <ruby-pg@j-davis.com>
|
8
8
|
* - Guy Decoux (ts) <decoux@moulon.inra.fr>
|
9
9
|
* - Michael Granger <ged@FaerieMUD.org>
|
10
|
+
* - Lars Kanis <lars@greiz-reinsdorf.de>
|
10
11
|
* - Dave Lee
|
11
12
|
* - Eiji Matsumoto <usagi@ruby.club.or.jp>
|
12
13
|
* - Yukihiro Matsumoto <matz@ruby-lang.org>
|
@@ -15,10 +16,10 @@
|
|
15
16
|
* See Contributors.rdoc for the many additional fine people that have contributed
|
16
17
|
* to this library over the years.
|
17
18
|
*
|
18
|
-
* Copyright (c) 1997-
|
19
|
+
* Copyright (c) 1997-2019 by the authors.
|
19
20
|
*
|
20
21
|
* You may redistribute this software under the same terms as Ruby itself; see
|
21
|
-
*
|
22
|
+
* https://www.ruby-lang.org/en/about/license.txt or the BSDL file in the source
|
22
23
|
* for details.
|
23
24
|
*
|
24
25
|
* Portions of the code are from the PostgreSQL project, and are distributed
|
@@ -47,8 +48,8 @@
|
|
47
48
|
|
48
49
|
#include "pg.h"
|
49
50
|
|
51
|
+
int pg_skip_deprecation_warning;
|
50
52
|
VALUE rb_mPG;
|
51
|
-
VALUE rb_ePGerror;
|
52
53
|
VALUE rb_mPGconstants;
|
53
54
|
|
54
55
|
|
@@ -69,7 +70,6 @@ VALUE rb_mPGconstants;
|
|
69
70
|
* M17n functions
|
70
71
|
*/
|
71
72
|
|
72
|
-
#ifdef M17N_SUPPORTED
|
73
73
|
/**
|
74
74
|
* The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
|
75
75
|
*/
|
@@ -124,24 +124,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
|
|
124
124
|
* A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s.
|
125
125
|
*/
|
126
126
|
static struct st_table *enc_pg2ruby;
|
127
|
-
static ID s_id_index;
|
128
|
-
|
129
|
-
|
130
|
-
/*
|
131
|
-
* Get the index of encoding +val+.
|
132
|
-
* :FIXME: Look into replacing this with rb_enc_get_index() since 1.9.1 isn't really
|
133
|
-
* used anymore.
|
134
|
-
*/
|
135
|
-
int
|
136
|
-
pg_enc_get_index(VALUE val)
|
137
|
-
{
|
138
|
-
int i = ENCODING_GET_INLINED(val);
|
139
|
-
if (i == ENCODING_INLINE_MAX) {
|
140
|
-
VALUE iv = rb_ivar_get(val, s_id_index);
|
141
|
-
i = NUM2INT(iv);
|
142
|
-
}
|
143
|
-
return i;
|
144
|
-
}
|
145
127
|
|
146
128
|
|
147
129
|
/*
|
@@ -161,9 +143,6 @@ pg_find_or_create_johab(void)
|
|
161
143
|
}
|
162
144
|
|
163
145
|
enc_index = rb_define_dummy_encoding(aliases[0]);
|
164
|
-
for (i = 1; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
|
165
|
-
ENC_ALIAS(aliases[i], aliases[0]);
|
166
|
-
}
|
167
146
|
return rb_enc_from_index(enc_index);
|
168
147
|
}
|
169
148
|
|
@@ -247,14 +226,55 @@ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
|
|
247
226
|
return encname;
|
248
227
|
}
|
249
228
|
|
250
|
-
|
229
|
+
|
230
|
+
/*
|
231
|
+
* Ensures that the given string has enough capacity to take expand_len
|
232
|
+
* more data bytes. The new data part of the String is not initialized.
|
233
|
+
*
|
234
|
+
* current_out must be a pointer within the data part of the String object.
|
235
|
+
* This pointer is returned and possibly adjusted, because the location of the data
|
236
|
+
* part of the String can change through this function.
|
237
|
+
*
|
238
|
+
* PG_RB_STR_ENSURE_CAPA can be used to do fast inline checks of the remaining capacity.
|
239
|
+
* end_capa it is then set to the first byte after the currently reserved memory,
|
240
|
+
* if not NULL.
|
241
|
+
*
|
242
|
+
* Before the String can be used with other string functions or returned to Ruby space,
|
243
|
+
* the string length has to be set with rb_str_set_len().
|
244
|
+
*
|
245
|
+
* Usage example:
|
246
|
+
*
|
247
|
+
* VALUE string;
|
248
|
+
* char *current_out, *end_capa;
|
249
|
+
* PG_RB_STR_NEW( string, current_out, end_capa );
|
250
|
+
* while( data_is_going_to_be_processed ){
|
251
|
+
* PG_RB_STR_ENSURE_CAPA( string, 2, current_out, end_capa );
|
252
|
+
* *current_out++ = databyte1;
|
253
|
+
* *current_out++ = databyte2;
|
254
|
+
* }
|
255
|
+
* rb_str_set_len( string, current_out - RSTRING_PTR(string) );
|
256
|
+
*
|
257
|
+
*/
|
258
|
+
char *
|
259
|
+
pg_rb_str_ensure_capa( VALUE str, long expand_len, char *curr_ptr, char **end_ptr )
|
260
|
+
{
|
261
|
+
long curr_len = curr_ptr - RSTRING_PTR(str);
|
262
|
+
long curr_capa = rb_str_capacity( str );
|
263
|
+
if( curr_capa < curr_len + expand_len ){
|
264
|
+
rb_str_set_len( str, curr_len );
|
265
|
+
rb_str_modify_expand( str, (curr_len + expand_len) * 2 - curr_capa );
|
266
|
+
curr_ptr = RSTRING_PTR(str) + curr_len;
|
267
|
+
}
|
268
|
+
if( end_ptr )
|
269
|
+
*end_ptr = RSTRING_PTR(str) + rb_str_capacity( str );
|
270
|
+
return curr_ptr;
|
271
|
+
}
|
251
272
|
|
252
273
|
|
253
274
|
/**************************************************************************
|
254
275
|
* Module Methods
|
255
276
|
**************************************************************************/
|
256
277
|
|
257
|
-
#ifdef HAVE_PQLIBVERSION
|
258
278
|
/*
|
259
279
|
* call-seq:
|
260
280
|
* PG.library_version -> Integer
|
@@ -272,7 +292,6 @@ pg_s_library_version(VALUE self)
|
|
272
292
|
UNUSED( self );
|
273
293
|
return INT2NUM(PQlibVersion());
|
274
294
|
}
|
275
|
-
#endif
|
276
295
|
|
277
296
|
|
278
297
|
/*
|
@@ -290,6 +309,66 @@ pg_s_threadsafe_p(VALUE self)
|
|
290
309
|
return PQisthreadsafe() ? Qtrue : Qfalse;
|
291
310
|
}
|
292
311
|
|
312
|
+
static int
|
313
|
+
pg_to_bool_int(VALUE value)
|
314
|
+
{
|
315
|
+
switch( TYPE(value) ){
|
316
|
+
case T_FALSE:
|
317
|
+
return 0;
|
318
|
+
case T_TRUE:
|
319
|
+
return 1;
|
320
|
+
default:
|
321
|
+
return NUM2INT(value);
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
325
|
+
/*
|
326
|
+
* call-seq:
|
327
|
+
* PG.init_openssl(do_ssl, do_crypto) -> nil
|
328
|
+
*
|
329
|
+
* Allows applications to select which security libraries to initialize.
|
330
|
+
*
|
331
|
+
* If your application initializes libssl and/or libcrypto libraries and libpq is
|
332
|
+
* built with SSL support, you should call PG.init_openssl() to tell libpq that the
|
333
|
+
* libssl and/or libcrypto libraries have been initialized by your application,
|
334
|
+
* so that libpq will not also initialize those libraries.
|
335
|
+
*
|
336
|
+
* When do_ssl is +true+, libpq will initialize the OpenSSL library before first
|
337
|
+
* opening a database connection. When do_crypto is +true+, the libcrypto library
|
338
|
+
* will be initialized. By default (if PG.init_openssl() is not called), both libraries
|
339
|
+
* are initialized. When SSL support is not compiled in, this function is present but does nothing.
|
340
|
+
*
|
341
|
+
* If your application uses and initializes either OpenSSL or its underlying libcrypto library,
|
342
|
+
* you must call this function with +false+ for the appropriate parameter(s) before first opening
|
343
|
+
* a database connection. Also be sure that you have done that initialization before opening a
|
344
|
+
* database connection.
|
345
|
+
*
|
346
|
+
*/
|
347
|
+
static VALUE
|
348
|
+
pg_s_init_openssl(VALUE self, VALUE do_ssl, VALUE do_crypto)
|
349
|
+
{
|
350
|
+
UNUSED( self );
|
351
|
+
PQinitOpenSSL(pg_to_bool_int(do_ssl), pg_to_bool_int(do_crypto));
|
352
|
+
return Qnil;
|
353
|
+
}
|
354
|
+
|
355
|
+
|
356
|
+
/*
|
357
|
+
* call-seq:
|
358
|
+
* PG.init_ssl(do_ssl) -> nil
|
359
|
+
*
|
360
|
+
* Allows applications to select which security libraries to initialize.
|
361
|
+
*
|
362
|
+
* This function is equivalent to <tt>PG.init_openssl(do_ssl, do_ssl)</tt> . It is sufficient for
|
363
|
+
* applications that initialize both or neither of OpenSSL and libcrypto.
|
364
|
+
*/
|
365
|
+
static VALUE
|
366
|
+
pg_s_init_ssl(VALUE self, VALUE do_ssl)
|
367
|
+
{
|
368
|
+
UNUSED( self );
|
369
|
+
PQinitSSL(pg_to_bool_int(do_ssl));
|
370
|
+
return Qnil;
|
371
|
+
}
|
293
372
|
|
294
373
|
|
295
374
|
/**************************************************************************
|
@@ -299,26 +378,27 @@ pg_s_threadsafe_p(VALUE self)
|
|
299
378
|
void
|
300
379
|
Init_pg_ext()
|
301
380
|
{
|
381
|
+
if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
|
382
|
+
/* Set all bits to disable all deprecation warnings. */
|
383
|
+
pg_skip_deprecation_warning = 0xFFFF;
|
384
|
+
} else {
|
385
|
+
pg_skip_deprecation_warning = 0;
|
386
|
+
}
|
387
|
+
|
302
388
|
rb_mPG = rb_define_module( "PG" );
|
303
|
-
rb_ePGerror = rb_define_class_under( rb_mPG, "Error", rb_eStandardError );
|
304
389
|
rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
|
305
390
|
|
306
391
|
/*************************
|
307
392
|
* PG module methods
|
308
393
|
*************************/
|
309
|
-
#ifdef HAVE_PQLIBVERSION
|
310
394
|
rb_define_singleton_method( rb_mPG, "library_version", pg_s_library_version, 0 );
|
311
|
-
#endif
|
312
395
|
rb_define_singleton_method( rb_mPG, "isthreadsafe", pg_s_threadsafe_p, 0 );
|
313
396
|
SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
|
314
397
|
SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
|
315
398
|
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
rb_define_alias( rb_ePGerror, "error", "message" );
|
320
|
-
rb_define_attr( rb_ePGerror, "connection", 1, 0 );
|
321
|
-
rb_define_attr( rb_ePGerror, "result", 1, 0 );
|
399
|
+
rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
|
400
|
+
rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
|
401
|
+
|
322
402
|
|
323
403
|
/****** PG::Connection CLASS CONSTANTS: Connection Status ******/
|
324
404
|
|
@@ -341,7 +421,7 @@ Init_pg_ext()
|
|
341
421
|
rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
|
342
422
|
/* Negotiating environment-driven parameter settings. */
|
343
423
|
rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
|
344
|
-
/* Internal state
|
424
|
+
/* Internal state - PG.connect() needed. */
|
345
425
|
rb_define_const(rb_mPGconstants, "CONNECTION_NEEDED", INT2FIX(CONNECTION_NEEDED));
|
346
426
|
|
347
427
|
/****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
|
@@ -357,27 +437,48 @@ Init_pg_ext()
|
|
357
437
|
|
358
438
|
/****** PG::Connection CLASS CONSTANTS: Transaction Status ******/
|
359
439
|
|
360
|
-
/* Transaction is currently idle (#transaction_status) */
|
440
|
+
/* Transaction is currently idle ( Connection#transaction_status ) */
|
361
441
|
rb_define_const(rb_mPGconstants, "PQTRANS_IDLE", INT2FIX(PQTRANS_IDLE));
|
362
|
-
/* Transaction is currently active; query has been sent to the server, but not yet completed. (#transaction_status) */
|
442
|
+
/* Transaction is currently active; query has been sent to the server, but not yet completed. ( Connection#transaction_status ) */
|
363
443
|
rb_define_const(rb_mPGconstants, "PQTRANS_ACTIVE", INT2FIX(PQTRANS_ACTIVE));
|
364
|
-
/* Transaction is currently idle, in a valid transaction block (#transaction_status) */
|
444
|
+
/* Transaction is currently idle, in a valid transaction block ( Connection#transaction_status ) */
|
365
445
|
rb_define_const(rb_mPGconstants, "PQTRANS_INTRANS", INT2FIX(PQTRANS_INTRANS));
|
366
|
-
/* Transaction is currently idle, in a failed transaction block (#transaction_status) */
|
446
|
+
/* Transaction is currently idle, in a failed transaction block ( Connection#transaction_status ) */
|
367
447
|
rb_define_const(rb_mPGconstants, "PQTRANS_INERROR", INT2FIX(PQTRANS_INERROR));
|
368
|
-
/* Transaction's connection is bad (#transaction_status) */
|
448
|
+
/* Transaction's connection is bad ( Connection#transaction_status ) */
|
369
449
|
rb_define_const(rb_mPGconstants, "PQTRANS_UNKNOWN", INT2FIX(PQTRANS_UNKNOWN));
|
370
450
|
|
371
451
|
/****** PG::Connection CLASS CONSTANTS: Error Verbosity ******/
|
372
452
|
|
373
|
-
/*
|
453
|
+
/* Error verbosity level ( Connection#set_error_verbosity ).
|
454
|
+
* In TERSE mode, returned messages include severity, primary text, and position only; this will normally fit on a single line. */
|
374
455
|
rb_define_const(rb_mPGconstants, "PQERRORS_TERSE", INT2FIX(PQERRORS_TERSE));
|
375
|
-
/*
|
456
|
+
/* Error verbosity level ( Connection#set_error_verbosity ).
|
457
|
+
* The DEFAULT mode produces messages that include the above plus any detail, hint, or context fields (these might span multiple lines). */
|
376
458
|
rb_define_const(rb_mPGconstants, "PQERRORS_DEFAULT", INT2FIX(PQERRORS_DEFAULT));
|
377
|
-
/*
|
459
|
+
/* Error verbosity level ( Connection#set_error_verbosity ).
|
460
|
+
* The VERBOSE mode includes all available fields. */
|
378
461
|
rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
|
379
462
|
|
380
|
-
|
463
|
+
/* PQERRORS_SQLSTATE was introduced in PG-12 together with PQresultMemorySize() */
|
464
|
+
#ifdef HAVE_PQRESULTMEMORYSIZE
|
465
|
+
/* Error verbosity level ( Connection#set_error_verbosity ).
|
466
|
+
* The SQLSTATE mode includes only the error severity and the SQLSTATE error code, if one is available (if not, the output is like TERSE mode).
|
467
|
+
*
|
468
|
+
* Available since PostgreSQL-12.
|
469
|
+
*/
|
470
|
+
rb_define_const(rb_mPGconstants, "PQERRORS_SQLSTATE", INT2FIX(PQERRORS_SQLSTATE));
|
471
|
+
#endif
|
472
|
+
|
473
|
+
#ifdef HAVE_PQRESULTVERBOSEERRORMESSAGE
|
474
|
+
/* See Connection#set_error_context_visibility */
|
475
|
+
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_NEVER", INT2FIX(PQSHOW_CONTEXT_NEVER));
|
476
|
+
/* See Connection#set_error_context_visibility */
|
477
|
+
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_ERRORS", INT2FIX(PQSHOW_CONTEXT_ERRORS));
|
478
|
+
/* See Connection#set_error_context_visibility */
|
479
|
+
rb_define_const(rb_mPGconstants, "PQSHOW_CONTEXT_ALWAYS", INT2FIX(PQSHOW_CONTEXT_ALWAYS));
|
480
|
+
#endif
|
481
|
+
|
381
482
|
/****** PG::Connection CLASS CONSTANTS: Check Server Status ******/
|
382
483
|
|
383
484
|
/* Server is accepting connections. */
|
@@ -388,124 +489,162 @@ Init_pg_ext()
|
|
388
489
|
rb_define_const(rb_mPGconstants, "PQPING_NO_RESPONSE", INT2FIX(PQPING_NO_RESPONSE));
|
389
490
|
/* Connection not attempted (bad params). */
|
390
491
|
rb_define_const(rb_mPGconstants, "PQPING_NO_ATTEMPT", INT2FIX(PQPING_NO_ATTEMPT));
|
391
|
-
#endif
|
392
492
|
|
393
493
|
/****** PG::Connection CLASS CONSTANTS: Large Objects ******/
|
394
494
|
|
395
|
-
/* Flag for #lo_creat, #lo_open -- open for writing */
|
495
|
+
/* Flag for Connection#lo_creat, Connection#lo_open -- open for writing */
|
396
496
|
rb_define_const(rb_mPGconstants, "INV_WRITE", INT2FIX(INV_WRITE));
|
397
|
-
/* Flag for #lo_creat, #lo_open -- open for reading */
|
497
|
+
/* Flag for Connection#lo_creat, Connection#lo_open -- open for reading */
|
398
498
|
rb_define_const(rb_mPGconstants, "INV_READ", INT2FIX(INV_READ));
|
399
|
-
/* Flag for #lo_lseek -- seek from object start */
|
499
|
+
/* Flag for Connection#lo_lseek -- seek from object start */
|
400
500
|
rb_define_const(rb_mPGconstants, "SEEK_SET", INT2FIX(SEEK_SET));
|
401
|
-
/* Flag for #lo_lseek -- seek from current position */
|
501
|
+
/* Flag for Connection#lo_lseek -- seek from current position */
|
402
502
|
rb_define_const(rb_mPGconstants, "SEEK_CUR", INT2FIX(SEEK_CUR));
|
403
|
-
/* Flag for #lo_lseek -- seek from object end */
|
503
|
+
/* Flag for Connection#lo_lseek -- seek from object end */
|
404
504
|
rb_define_const(rb_mPGconstants, "SEEK_END", INT2FIX(SEEK_END));
|
405
505
|
|
406
506
|
/****** PG::Result CONSTANTS: result status ******/
|
407
507
|
|
408
|
-
/* #result_status constant
|
508
|
+
/* Result#result_status constant - The string sent to the server was empty. */
|
409
509
|
rb_define_const(rb_mPGconstants, "PGRES_EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY));
|
410
|
-
/* #result_status constant
|
510
|
+
/* Result#result_status constant - Successful completion of a command returning no data. */
|
411
511
|
rb_define_const(rb_mPGconstants, "PGRES_COMMAND_OK", INT2FIX(PGRES_COMMAND_OK));
|
412
|
-
|
413
|
-
(such as a SELECT or SHOW). */
|
512
|
+
/* Result#result_status constant - Successful completion of a command returning data (such as a SELECT or SHOW). */
|
414
513
|
rb_define_const(rb_mPGconstants, "PGRES_TUPLES_OK", INT2FIX(PGRES_TUPLES_OK));
|
415
|
-
/* #result_status constant
|
514
|
+
/* Result#result_status constant - Copy Out (from server) data transfer started. */
|
416
515
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_OUT", INT2FIX(PGRES_COPY_OUT));
|
417
|
-
/* #result_status constant
|
516
|
+
/* Result#result_status constant - Copy In (to server) data transfer started. */
|
418
517
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_IN", INT2FIX(PGRES_COPY_IN));
|
419
|
-
/* #result_status constant
|
518
|
+
/* Result#result_status constant - The server’s response was not understood. */
|
420
519
|
rb_define_const(rb_mPGconstants, "PGRES_BAD_RESPONSE", INT2FIX(PGRES_BAD_RESPONSE));
|
421
|
-
/* #result_status constant
|
520
|
+
/* Result#result_status constant - A nonfatal error (a notice or warning) occurred. */
|
422
521
|
rb_define_const(rb_mPGconstants, "PGRES_NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR));
|
423
|
-
/* #result_status constant
|
522
|
+
/* Result#result_status constant - A fatal error occurred. */
|
424
523
|
rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
|
425
|
-
/* #result_status constant
|
426
|
-
#ifdef HAVE_CONST_PGRES_COPY_BOTH
|
524
|
+
/* Result#result_status constant - Copy In/Out data transfer in progress. */
|
427
525
|
rb_define_const(rb_mPGconstants, "PGRES_COPY_BOTH", INT2FIX(PGRES_COPY_BOTH));
|
428
|
-
#
|
429
|
-
/* #result_status constant: Single tuple from larger resultset. */
|
430
|
-
#ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
|
526
|
+
/* Result#result_status constant - Single tuple from larger resultset. */
|
431
527
|
rb_define_const(rb_mPGconstants, "PGRES_SINGLE_TUPLE", INT2FIX(PGRES_SINGLE_TUPLE));
|
432
|
-
#endif
|
433
528
|
|
434
529
|
/****** Result CONSTANTS: result error field codes ******/
|
435
530
|
|
436
|
-
/* #result_error_field argument constant
|
437
|
-
*
|
438
|
-
* DEBUG, INFO, or LOG (in a notice message), or a localized translation
|
439
|
-
* of one of these.
|
531
|
+
/* Result#result_error_field argument constant
|
532
|
+
*
|
533
|
+
* 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), or a localized translation
|
534
|
+
* of one of these.
|
535
|
+
* Always present.
|
440
536
|
*/
|
441
537
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY", INT2FIX(PG_DIAG_SEVERITY));
|
442
538
|
|
443
|
-
|
444
|
-
|
445
|
-
*
|
446
|
-
*
|
447
|
-
*
|
448
|
-
*
|
539
|
+
#ifdef PG_DIAG_SEVERITY_NONLOCALIZED
|
540
|
+
/* Result#result_error_field argument constant
|
541
|
+
*
|
542
|
+
* 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).
|
543
|
+
* This is identical to the PG_DIAG_SEVERITY field except that the contents are never localized.
|
544
|
+
*
|
545
|
+
* Available since PostgreSQL-9.6
|
546
|
+
*/
|
547
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY_NONLOCALIZED", INT2FIX(PG_DIAG_SEVERITY_NONLOCALIZED));
|
548
|
+
#endif
|
549
|
+
/* Result#result_error_field argument constant
|
550
|
+
*
|
551
|
+
* The SQLSTATE code for the error.
|
552
|
+
* The SQLSTATE code identies the type of error that has occurred; it can be used by front-end applications to perform specic operations (such as error handling) in response to a particular database error.
|
553
|
+
* For a list of the possible SQLSTATE codes, see Appendix A.
|
554
|
+
* This field is not localizable, and is always present.
|
449
555
|
*/
|
450
556
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SQLSTATE", INT2FIX(PG_DIAG_SQLSTATE));
|
451
|
-
|
452
|
-
|
453
|
-
* error message (typically one line).
|
557
|
+
/* Result#result_error_field argument constant
|
558
|
+
*
|
559
|
+
* The primary human-readable error message (typically one line).
|
560
|
+
* Always present. */
|
454
561
|
rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_PRIMARY", INT2FIX(PG_DIAG_MESSAGE_PRIMARY));
|
455
|
-
|
456
|
-
|
457
|
-
* error message carrying more detail about the problem.
|
458
|
-
* multiple lines.
|
562
|
+
/* Result#result_error_field argument constant
|
563
|
+
*
|
564
|
+
* Detail: an optional secondary error message carrying more detail about the problem.
|
565
|
+
* Might run to multiple lines.
|
459
566
|
*/
|
460
567
|
rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_DETAIL", INT2FIX(PG_DIAG_MESSAGE_DETAIL));
|
461
|
-
|
462
|
-
|
463
|
-
* what to do about the problem.
|
464
|
-
* in that it offers advice (potentially inappropriate) rather than
|
465
|
-
*
|
568
|
+
/* Result#result_error_field argument constant
|
569
|
+
*
|
570
|
+
* Hint: an optional suggestion what to do about the problem.
|
571
|
+
* This is intended to differ from detail in that it offers advice (potentially inappropriate) rather than hard facts.
|
572
|
+
* Might run to multiple lines.
|
466
573
|
*/
|
467
|
-
|
468
574
|
rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_HINT", INT2FIX(PG_DIAG_MESSAGE_HINT));
|
469
|
-
/* #result_error_field argument constant
|
470
|
-
*
|
471
|
-
*
|
472
|
-
*
|
575
|
+
/* Result#result_error_field argument constant
|
576
|
+
*
|
577
|
+
* A string containing a decimal integer indicating an error cursor position as an index into the original statement string.
|
578
|
+
*
|
579
|
+
* The first character has index 1, and positions are measured in characters not bytes.
|
473
580
|
*/
|
474
|
-
|
475
581
|
rb_define_const(rb_mPGconstants, "PG_DIAG_STATEMENT_POSITION", INT2FIX(PG_DIAG_STATEMENT_POSITION));
|
476
|
-
/* #result_error_field argument constant
|
477
|
-
*
|
478
|
-
* position refers to an internally generated command rather than the
|
479
|
-
*
|
480
|
-
* always appear when this eld appears.
|
582
|
+
/* Result#result_error_field argument constant
|
583
|
+
*
|
584
|
+
* This is defined the same as the PG_DIAG_STATEMENT_POSITION field, but it is used when the cursor position refers to an internally generated command rather than the one submitted by the client.
|
585
|
+
* The PG_DIAG_INTERNAL_QUERY field will always appear when this field appears.
|
481
586
|
*/
|
482
|
-
|
483
587
|
rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_POSITION", INT2FIX(PG_DIAG_INTERNAL_POSITION));
|
484
|
-
/* #result_error_field argument constant
|
485
|
-
*
|
486
|
-
*
|
588
|
+
/* Result#result_error_field argument constant
|
589
|
+
*
|
590
|
+
* The text of a failed internally-generated command.
|
591
|
+
* This could be, for example, a SQL query issued by a PL/pgSQL function.
|
487
592
|
*/
|
488
|
-
|
489
593
|
rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_QUERY", INT2FIX(PG_DIAG_INTERNAL_QUERY));
|
490
|
-
/* #result_error_field argument constant
|
491
|
-
*
|
492
|
-
*
|
493
|
-
*
|
594
|
+
/* Result#result_error_field argument constant
|
595
|
+
*
|
596
|
+
* An indication of the context in which the error occurred.
|
597
|
+
* Presently this includes a call stack traceback of active procedural language functions and internally-generated queries.
|
598
|
+
* The trace is one entry per line, most recent first.
|
494
599
|
*/
|
495
|
-
|
496
600
|
rb_define_const(rb_mPGconstants, "PG_DIAG_CONTEXT", INT2FIX(PG_DIAG_CONTEXT));
|
497
|
-
/* #result_error_field argument constant
|
498
|
-
*
|
601
|
+
/* Result#result_error_field argument constant
|
602
|
+
*
|
603
|
+
* The file name of the source-code location where the error was reported. */
|
499
604
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FILE", INT2FIX(PG_DIAG_SOURCE_FILE));
|
500
605
|
|
501
|
-
/* #result_error_field argument constant
|
502
|
-
*
|
606
|
+
/* Result#result_error_field argument constant
|
607
|
+
*
|
608
|
+
* The line number of the source-code location where the error was reported. */
|
503
609
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_LINE", INT2FIX(PG_DIAG_SOURCE_LINE));
|
504
610
|
|
505
|
-
/* #result_error_field argument constant
|
506
|
-
*
|
611
|
+
/* Result#result_error_field argument constant
|
612
|
+
*
|
613
|
+
* The name of the source-code function reporting the error. */
|
507
614
|
rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FUNCTION", INT2FIX(PG_DIAG_SOURCE_FUNCTION));
|
508
615
|
|
616
|
+
#ifdef PG_DIAG_TABLE_NAME
|
617
|
+
/* Result#result_error_field argument constant
|
618
|
+
*
|
619
|
+
* If the error was associated with a specific database object, the name of the schema containing that object, if any. */
|
620
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_SCHEMA_NAME", INT2FIX(PG_DIAG_SCHEMA_NAME));
|
621
|
+
|
622
|
+
/* Result#result_error_field argument constant
|
623
|
+
*
|
624
|
+
* If the error was associated with a specific table, the name of the table.
|
625
|
+
* (When this field is present, the schema name field provides the name of the table's schema.) */
|
626
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_TABLE_NAME", INT2FIX(PG_DIAG_TABLE_NAME));
|
627
|
+
|
628
|
+
/* Result#result_error_field argument constant
|
629
|
+
*
|
630
|
+
* If the error was associated with a specific table column, the name of the column.
|
631
|
+
* (When this field is present, the schema and table name fields identify the table.) */
|
632
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_COLUMN_NAME", INT2FIX(PG_DIAG_COLUMN_NAME));
|
633
|
+
|
634
|
+
/* Result#result_error_field argument constant
|
635
|
+
*
|
636
|
+
* If the error was associated with a specific datatype, the name of the datatype.
|
637
|
+
* (When this field is present, the schema name field provides the name of the datatype's schema.) */
|
638
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_DATATYPE_NAME", INT2FIX(PG_DIAG_DATATYPE_NAME));
|
639
|
+
|
640
|
+
/* Result#result_error_field argument constant
|
641
|
+
*
|
642
|
+
* If the error was associated with a specific constraint, the name of the constraint.
|
643
|
+
* The table or domain that the constraint belongs to is reported using the fields listed above.
|
644
|
+
* (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) */
|
645
|
+
rb_define_const(rb_mPGconstants, "PG_DIAG_CONSTRAINT_NAME", INT2FIX(PG_DIAG_CONSTRAINT_NAME));
|
646
|
+
#endif
|
647
|
+
|
509
648
|
/* Invalid OID constant */
|
510
649
|
rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
|
511
650
|
rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid));
|
@@ -513,13 +652,26 @@ Init_pg_ext()
|
|
513
652
|
/* Add the constants to the toplevel namespace */
|
514
653
|
rb_include_module( rb_mPG, rb_mPGconstants );
|
515
654
|
|
516
|
-
#ifdef M17N_SUPPORTED
|
517
655
|
enc_pg2ruby = st_init_numtable();
|
518
|
-
s_id_index = rb_intern("@encoding");
|
519
|
-
#endif
|
520
656
|
|
521
657
|
/* Initialize the main extension classes */
|
522
658
|
init_pg_connection();
|
523
659
|
init_pg_result();
|
660
|
+
init_pg_errors();
|
661
|
+
init_pg_type_map();
|
662
|
+
init_pg_type_map_all_strings();
|
663
|
+
init_pg_type_map_by_class();
|
664
|
+
init_pg_type_map_by_column();
|
665
|
+
init_pg_type_map_by_mri_type();
|
666
|
+
init_pg_type_map_by_oid();
|
667
|
+
init_pg_type_map_in_ruby();
|
668
|
+
init_pg_coder();
|
669
|
+
init_pg_text_encoder();
|
670
|
+
init_pg_text_decoder();
|
671
|
+
init_pg_binary_encoder();
|
672
|
+
init_pg_binary_decoder();
|
673
|
+
init_pg_copycoder();
|
674
|
+
init_pg_recordcoder();
|
675
|
+
init_pg_tuple();
|
524
676
|
}
|
525
677
|
|