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.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/BSDL +2 -2
  5. data/ChangeLog +0 -3022
  6. data/History.rdoc +370 -4
  7. data/Manifest.txt +39 -19
  8. data/README-Windows.rdoc +17 -28
  9. data/README.ja.rdoc +1 -2
  10. data/README.rdoc +113 -14
  11. data/Rakefile +97 -36
  12. data/Rakefile.cross +109 -83
  13. data/ext/errorcodes.def +1032 -0
  14. data/ext/errorcodes.rb +45 -0
  15. data/ext/errorcodes.txt +494 -0
  16. data/ext/extconf.rb +55 -52
  17. data/ext/gvl_wrappers.c +4 -0
  18. data/ext/gvl_wrappers.h +94 -38
  19. data/ext/pg.c +273 -121
  20. data/ext/pg.h +292 -50
  21. data/ext/pg_binary_decoder.c +229 -0
  22. data/ext/pg_binary_encoder.c +163 -0
  23. data/ext/pg_coder.c +561 -0
  24. data/ext/pg_connection.c +1811 -1051
  25. data/ext/pg_copy_coder.c +599 -0
  26. data/ext/pg_errors.c +95 -0
  27. data/ext/pg_record_coder.c +491 -0
  28. data/ext/pg_result.c +917 -203
  29. data/ext/pg_text_decoder.c +987 -0
  30. data/ext/pg_text_encoder.c +814 -0
  31. data/ext/pg_tuple.c +549 -0
  32. data/ext/pg_type_map.c +166 -0
  33. data/ext/pg_type_map_all_strings.c +116 -0
  34. data/ext/pg_type_map_by_class.c +244 -0
  35. data/ext/pg_type_map_by_column.c +313 -0
  36. data/ext/pg_type_map_by_mri_type.c +284 -0
  37. data/ext/pg_type_map_by_oid.c +356 -0
  38. data/ext/pg_type_map_in_ruby.c +299 -0
  39. data/ext/pg_util.c +149 -0
  40. data/ext/pg_util.h +65 -0
  41. data/lib/pg.rb +31 -9
  42. data/lib/pg/basic_type_mapping.rb +522 -0
  43. data/lib/pg/binary_decoder.rb +23 -0
  44. data/lib/pg/coder.rb +104 -0
  45. data/lib/pg/connection.rb +235 -30
  46. data/lib/pg/constants.rb +2 -1
  47. data/lib/pg/exceptions.rb +2 -1
  48. data/lib/pg/result.rb +33 -6
  49. data/lib/pg/text_decoder.rb +46 -0
  50. data/lib/pg/text_encoder.rb +59 -0
  51. data/lib/pg/tuple.rb +30 -0
  52. data/lib/pg/type_map_by_column.rb +16 -0
  53. data/spec/{lib/helpers.rb → helpers.rb} +154 -52
  54. data/spec/pg/basic_type_mapping_spec.rb +630 -0
  55. data/spec/pg/connection_spec.rb +1352 -426
  56. data/spec/pg/connection_sync_spec.rb +41 -0
  57. data/spec/pg/result_spec.rb +508 -105
  58. data/spec/pg/tuple_spec.rb +333 -0
  59. data/spec/pg/type_map_by_class_spec.rb +138 -0
  60. data/spec/pg/type_map_by_column_spec.rb +226 -0
  61. data/spec/pg/type_map_by_mri_type_spec.rb +136 -0
  62. data/spec/pg/type_map_by_oid_spec.rb +149 -0
  63. data/spec/pg/type_map_in_ruby_spec.rb +164 -0
  64. data/spec/pg/type_map_spec.rb +22 -0
  65. data/spec/pg/type_spec.rb +1123 -0
  66. data/spec/pg_spec.rb +35 -16
  67. metadata +163 -84
  68. metadata.gz.sig +0 -0
  69. data/sample/array_insert.rb +0 -20
  70. data/sample/async_api.rb +0 -106
  71. data/sample/async_copyto.rb +0 -39
  72. data/sample/async_mixed.rb +0 -56
  73. data/sample/check_conn.rb +0 -21
  74. data/sample/copyfrom.rb +0 -81
  75. data/sample/copyto.rb +0 -19
  76. data/sample/cursor.rb +0 -21
  77. data/sample/disk_usage_report.rb +0 -186
  78. data/sample/issue-119.rb +0 -94
  79. data/sample/losample.rb +0 -69
  80. data/sample/minimal-testcase.rb +0 -17
  81. data/sample/notify_wait.rb +0 -72
  82. data/sample/pg_statistics.rb +0 -294
  83. data/sample/replication_monitor.rb +0 -231
  84. data/sample/test_binary_values.rb +0 -33
  85. data/sample/wal_shipper.rb +0 -434
  86. 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 ENV['CROSS_COMPILING']
19
- $LDFLAGS << " -L#{CONFIG['libdir']}"
20
-
21
- # Link against all required libraries for static build, if they are available
22
- have_library( 'crypt32', 'CertOpenStore' ) && append_library( $libs, 'crypt32' )
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
- $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
40
- " --with-pg-config=/path/to/pg_config"
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 'PQconnectionUsedPassword' or
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 'PQisthreadsafe'
57
- have_func 'PQprepare'
58
- have_func 'PQexecParams'
59
- have_func 'PQescapeString'
60
- have_func 'PQescapeStringConn'
61
- have_func 'PQescapeLiteral'
62
- have_func 'PQescapeIdentifier'
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 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h 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
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
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
- #if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
57
- #define DEFINE_GVL_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
58
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
59
- struct gvl_wrapper_##name##_params params = { \
60
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
61
- }; \
62
- rb_thread_call_without_gvl(gvl_##name##_skeleton, &params, RUBY_UBF_IO, 0); \
63
- when_non_void( return params.retval; ) \
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, &params, 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
- #if defined(HAVE_RB_THREAD_CALL_WITH_GVL)
84
- #define DEFINE_GVLCB_STUB(name, when_non_void, rettype, lastparamtype, lastparamname) \
85
- rettype gvl_##name(FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST3) lastparamtype lastparamname){ \
86
- struct gvl_wrapper_##name##_params params = { \
87
- {FOR_EACH_PARAM_OF_##name(DEFINE_PARAM_LIST1) lastparamname}, when_non_void((rettype)0) \
88
- }; \
89
- rb_thread_call_with_gvl(gvl_##name##_skeleton, &params); \
90
- when_non_void( return params.retval; ) \
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, &params); \
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: pg.c,v d0c5d5f7f1e8 2012/12/26 21:09:28 kanis $
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-2012 by the authors.
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
- * http://www.ruby-lang.org/en/LICENSE.txt or the LICENSE file in the source
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
- #endif /* M17N_SUPPORTED */
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
- * PG::Error
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: connect() needed. */
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
- /* Terse error verbosity level (#set_error_verbosity) */
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
- /* Default error verbosity level (#set_error_verbosity) */
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
- /* Verbose error verbosity level (#set_error_verbosity) */
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
- #ifdef HAVE_PQPING
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: The string sent to the server was empty. */
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: Successful completion of a command returning no data. */
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
- /* #result_status constant: Successful completion of a command returning data
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: Copy Out (from server) data transfer started. */
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: Copy In (to server) data transfer started. */
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: The server’s response was not understood. */
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: A nonfatal error (a notice or warning) occurred. */
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: A fatal error occurred. */
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: Copy In/Out data transfer in progress. */
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
- #endif
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: The severity; the field contents
437
- * are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE,
438
- * DEBUG, INFO, or LOG (in a notice message), or a localized translation
439
- * of one of these. Always present.
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
- /* #result_error_field argument constant: The SQLSTATE code for the
444
- * error. The SQLSTATE code identies the type of error that has occurred;
445
- * it can be used by front-end applications to perform specic operations
446
- * (such as er- ror handling) in response to a particular database
447
- * error. For a list of the possible SQLSTATE codes, see Appendix A.
448
- * This eld is not localizable, and is always present.
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
- /* #result_error_field argument constant: The primary human-readable
453
- * error message (typically one line). Always present. */
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
- /* #result_error_field argument constant: Detail: an optional secondary
457
- * error message carrying more detail about the problem. Might run to
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
- /* #result_error_field argument constant: Hint: an optional suggestion
463
- * what to do about the problem. This is intended to differ from detail
464
- * in that it offers advice (potentially inappropriate) rather than
465
- * hard facts. Might run to multiple lines.
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: A string containing a decimal
470
- * integer indicating an error cursor position as an index into the
471
- * original statement string. The rst character has index 1, and
472
- * positions are measured in characters not bytes.
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: This is dened the same as
477
- * the PG_DIAG_STATEMENT_POSITION eld, but it is used when the cursor
478
- * position refers to an internally generated command rather than the
479
- * one submitted by the client. The PG_DIAG_INTERNAL_QUERY eld will
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: The text of a failed
485
- * internally-generated command. This could be, for example, a SQL
486
- * query issued by a PL/pgSQL function.
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: An indication of the context
491
- * in which the error occurred. Presently this includes a call stack
492
- * traceback of active procedural language functions and internally-generated
493
- * queries. The trace is one entry per line, most recent rst.
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: The le name of the source-code
498
- * location where the error was reported. */
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: The line number of the
502
- * source-code location where the error was reported. */
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: The name of the source-code
506
- * function reporting the error. */
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