pg 0.12.2-x86-mingw32 → 0.13.0-x86-mingw32

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 (50) hide show
  1. data/.hoerc +2 -0
  2. data/.tm_properties +12 -0
  3. data/ChangeLog +166 -59
  4. data/Contributors.rdoc +7 -0
  5. data/History.rdoc +29 -0
  6. data/LICENSE +12 -14
  7. data/Manifest.txt +15 -14
  8. data/{BSD → POSTGRES} +0 -0
  9. data/{README.OS_X.rdoc → README-OS_X.rdoc} +0 -0
  10. data/{README.windows.rdoc → README-Windows.rdoc} +0 -0
  11. data/README.ja.rdoc +1 -1
  12. data/README.rdoc +39 -27
  13. data/Rakefile +1 -5
  14. data/Rakefile.cross +2 -2
  15. data/ext/extconf.rb +8 -2
  16. data/ext/pg.c +232 -4297
  17. data/ext/pg.h +88 -23
  18. data/ext/pg_connection.c +3288 -0
  19. data/ext/pg_result.c +905 -0
  20. data/lib/1.8/pg_ext.so +0 -0
  21. data/lib/1.9/pg_ext.so +0 -0
  22. data/lib/pg.rb +26 -43
  23. data/lib/pg/connection.rb +58 -0
  24. data/lib/pg/constants.rb +11 -0
  25. data/lib/pg/exceptions.rb +11 -0
  26. data/lib/pg/result.rb +11 -0
  27. data/misc/openssl-pg-segfault.rb +1 -1
  28. data/sample/async_api.rb +16 -21
  29. data/sample/async_copyto.rb +1 -1
  30. data/sample/async_mixed.rb +56 -0
  31. data/sample/copyfrom.rb +1 -1
  32. data/sample/copyto.rb +1 -1
  33. data/sample/cursor.rb +1 -1
  34. data/sample/losample.rb +6 -6
  35. data/sample/notify_wait.rb +51 -22
  36. data/sample/test_binary_values.rb +4 -6
  37. data/spec/lib/helpers.rb +14 -10
  38. data/spec/{pgconn_spec.rb → pg/connection_spec.rb} +228 -60
  39. data/spec/{pgresult_spec.rb → pg/result_spec.rb} +31 -35
  40. data/spec/pg_spec.rb +22 -0
  41. metadata +52 -41
  42. data/GPL +0 -340
  43. data/ext/compat.c +0 -541
  44. data/ext/compat.h +0 -184
  45. data/sample/psql.rb +0 -1181
  46. data/sample/psqlHelp.rb +0 -158
  47. data/sample/test1.rb +0 -60
  48. data/sample/test2.rb +0 -44
  49. data/sample/test4.rb +0 -71
  50. data/spec/m17n_spec.rb +0 -170
File without changes
File without changes
@@ -2,6 +2,6 @@
2
2
 
3
3
  * https://bitbucket.org/ged/ruby-pg
4
4
 
5
- This file needs translation. Anyone who is willing to volunteer, please
5
+ This file needs translation. Anyone who is willing to volunteer, please
6
6
  mail <ged@FaerieMUD.org>.
7
7
 
@@ -6,20 +6,31 @@
6
6
 
7
7
  Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/].
8
8
 
9
- It works with PostgreSQL 8.2 and later.
9
+ It works with {PostgreSQL 8.3 and later}[http://bit.ly/6AfPhm].
10
10
 
11
- This will be the last minor version to support 8.2 -- 0.13 will support 8.3
12
- and later, following the
13
- {PostgreSQL Release Support Policy}[http://bit.ly/6AfPhm].
11
+ A small example usage:
14
12
 
13
+ #!/usr/bin/env ruby
14
+
15
+ require 'pg'
16
+
17
+ # Output a table of current connections to the DB
18
+ conn = PG.connect( dbname: 'sales' )
19
+ conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
20
+ puts " PID | User | Query"
21
+ result.each do |row|
22
+ puts " %7d | %-16s | %s " %
23
+ row.values_at('procpid', 'usename', 'current_query')
24
+ end
25
+ end
15
26
 
16
27
 
17
28
  == Requirements
18
29
 
19
- * Ruby 1.8.7-p249 or later.
20
- * PostgreSQL 8.2.x or later installed.
30
+ * Ruby 1.8.7-p249 or 1.9.3-p0.
31
+ * PostgreSQL 8.3.x (with headers, -dev packages, etc).
21
32
 
22
- It may work with earlier versions as well, but those are not regularly tested.
33
+ It may work with earlier versions of Ruby as well, but those are not regularly tested.
23
34
 
24
35
 
25
36
  == How To Install
@@ -33,8 +44,12 @@ Postgres:
33
44
 
34
45
  gem install pg -- --with-pg-config=<path to pg_config>
35
46
 
36
- See README.OS_X.rdoc for more information about installing under MacOS X, and
37
- README.windows.rdoc for Windows build/installation instructions.
47
+ See README-OS_X.rdoc for more information about installing under MacOS X, and
48
+ README-Windows.rdoc for Windows build/installation instructions.
49
+
50
+ There's also {a Google+ group}[http://goo.gl/TFy1U] and a
51
+ {mailing list}[http://groups.google.com/group/ruby-pg] if you get stuck, or just
52
+ want to chat about something.
38
53
 
39
54
 
40
55
  == Contributing
@@ -50,39 +65,36 @@ After checking out the source, run:
50
65
  This task will install any missing dependencies, run the tests/specs, and
51
66
  generate the API documentation.
52
67
 
68
+ The current maintainer is Michael Granger <ged@FaerieMUD.org>.
53
69
 
54
- == Copying
55
70
 
56
- This library is copyrighted by the authors.
71
+ == Copying
57
72
 
58
- Authors:
73
+ Copyright (c) 1997-2012 by the authors.
59
74
 
60
- * Yukihiro Matsumoto <matz@ruby-lang.org> - Author of Ruby.
61
- * Eiji Matsumoto <usagi@ruby.club.or.jp> - One of users who loves Ruby.
62
75
  * Jeff Davis <ruby-pg@j-davis.com>
63
-
64
- Thanks to:
65
-
66
- * Noboru Saitou <noborus@netlab.jp> - Past maintainer.
67
- * Dave Lee - Past maintainer.
68
- * Guy Decoux (ts) <decoux@moulon.inra.fr>
69
-
70
- Maintainers:
71
-
76
+ * Guy Decoux (ts) <decoux@moulon.inra.fr>
72
77
  * Michael Granger <ged@FaerieMUD.org>
78
+ * Dave Lee
79
+ * Eiji Matsumoto <usagi@ruby.club.or.jp>
80
+ * Yukihiro Matsumoto <matz@ruby-lang.org>
81
+ * Noboru Saitou <noborus@netlab.jp>
73
82
 
74
- You may redistribute this software under the terms of the Ruby license,
75
- included in the file "LICENSE". The Ruby license also allows distribution
76
- under the terms of the GPL, included in the file "GPL".
83
+ You may redistribute this software under the same terms as Ruby itself; see
84
+ http://www.ruby-lang.org/en/LICENSE.txt or the LICENSE file in the source
85
+ for details.
77
86
 
78
87
  Portions of the code are from the PostgreSQL project, and are distributed
79
- under the terms of the BSD license, included in the file "BSD".
88
+ under the terms of the PostgreSQL license, included in the file POSTGRES.
80
89
 
81
90
  Portions copyright LAIKA, Inc.
82
91
 
83
92
 
84
93
  == Acknowledgments
85
94
 
95
+ See Contributors.rdoc for the many additional fine people that have contributed
96
+ to this library over the years.
97
+
86
98
  We are thankful to the people at the ruby-list and ruby-dev mailing lists.
87
99
  And to the people who developed PostgreSQL.
88
100
 
data/Rakefile CHANGED
@@ -49,10 +49,9 @@ $hoespec = Hoe.spec 'pg' do
49
49
  self.readme_file = 'README.rdoc'
50
50
  self.history_file = 'History.rdoc'
51
51
  self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
52
- self.extra_rdoc_files.include( 'BSD', 'GPL', 'LICENSE' )
52
+ self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' )
53
53
  self.extra_rdoc_files.include( 'ext/*.c' )
54
54
 
55
- self.developer 'Jeff Davis', 'ruby-pg@j-davis.com'
56
55
  self.developer 'Michael Granger', 'ged@FaerieMUD.org'
57
56
 
58
57
  self.dependency 'rake-compiler', '~> 0.7', :developer
@@ -97,8 +96,6 @@ task :maint do
97
96
  ENV['MAINTAINER_MODE'] = 'yes'
98
97
  end
99
98
 
100
- ENV['RUBY_CC_VERSION'] = '1.8.7:1.9.2'
101
-
102
99
  # Rake-compiler task
103
100
  Rake::ExtensionTask.new do |ext|
104
101
  ext.name = 'pg_ext'
@@ -115,7 +112,6 @@ Rake::ExtensionTask.new do |ext|
115
112
  "--with-opt-include=#{STATIC_POSTGRESQL_INCDIR}",
116
113
  "--with-pg-lib=#{STATIC_POSTGRESQL_LIBDIR}",
117
114
  "--with-opt-lib=#{STATIC_OPENSSL_BUILDDIR}",
118
- "--enable-static-build",
119
115
  ]
120
116
  end
121
117
 
@@ -41,8 +41,8 @@ OPENSSL_PATCHES = Rake::FileList[ MISCDIR + "openssl-#{OPENSSL_VERSIO
41
41
  # Static PostgreSQL build vars
42
42
  STATIC_POSTGRESQL_BUILDDIR = STATIC_BUILDDIR + "postgresql-#{POSTGRESQL_VERSION}"
43
43
  POSTGRESQL_SOURCE_URI = begin
44
- uristring = "http://ftp9.us.postgresql.org/pub/mirrors/postgresql/source/" +
45
- "v%s/postgresql-%s.tar.bz2" % [ POSTGRESQL_VERSION, POSTGRESQL_VERSION ]
44
+ uristring = "http://ftp.postgresql.org/pub/source/v%s/postgresql-%s.tar.bz2" %
45
+ [ POSTGRESQL_VERSION, POSTGRESQL_VERSION ]
46
46
  URI( uristring )
47
47
  end
48
48
  POSTGRESQL_TARBALL = STATIC_SOURCESDIR + File.basename( POSTGRESQL_SOURCE_URI.path )
@@ -4,7 +4,11 @@ require 'mkmf'
4
4
 
5
5
  if ENV['MAINTAINER_MODE']
6
6
  $stderr.puts "Maintainer mode enabled."
7
- $CFLAGS << ' -Wall' << ' -ggdb' << ' -DDEBUG'
7
+ $CFLAGS <<
8
+ ' -Wall' <<
9
+ ' -ggdb' <<
10
+ ' -DDEBUG' <<
11
+ ' -pedantic'
8
12
  end
9
13
 
10
14
  if pgdir = with_config( 'pg' )
@@ -35,6 +39,7 @@ end
35
39
 
36
40
  find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
37
41
  find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
42
+ find_header( 'pg_config_manual.h' ) or abort "Can't find the 'pg_config_manual.h' header"
38
43
 
39
44
  abort "Can't find the PostgreSQL client library (libpq)" unless
40
45
  have_library( 'pq', 'PQconnectdb', ['libpq-fe.h'] ) ||
@@ -51,6 +56,7 @@ have_func 'PQescapeStringConn'
51
56
  have_func 'PQgetCancel'
52
57
  have_func 'lo_create'
53
58
  have_func 'pg_encoding_to_char'
59
+ have_func 'pg_char_to_encoding'
54
60
  have_func 'PQsetClientEncoding'
55
61
 
56
62
  have_func 'rb_encdb_alias'
@@ -60,7 +66,7 @@ $defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
60
66
  have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
61
67
 
62
68
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
63
- have_header 'unistd.h' unless enable_config("static-build")
69
+ have_header 'unistd.h'
64
70
  have_header 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h header"
65
71
 
66
72
  create_header()
data/ext/pg.c CHANGED
@@ -1,3908 +1,122 @@
1
- /************************************************
2
-
3
- pg.c -
4
-
5
- Author: matz
6
- created at: Tue May 13 20:07:35 JST 1997
7
-
8
- Author: ematsu
9
- modified at: Wed Jan 20 16:41:51 1999
10
-
11
- $Author$
12
- $Date$
13
- ************************************************/
14
-
15
- #include "pg.h"
16
- #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
17
- # define M17N_SUPPORTED
18
- #endif
19
-
20
- #ifdef _WIN32
21
- // for O_RDWR and O_BINARY
22
- #include <fcntl.h>
23
- #endif
24
-
25
- #define rb_define_singleton_alias(klass,new,old) rb_define_alias(rb_singleton_class(klass),new,old)
26
-
27
- static VALUE rb_cPGconn;
28
- static VALUE rb_cPGresult;
29
- static VALUE rb_ePGError;
30
-
31
- static const char *VERSION = "0.12.2";
32
-
33
-
34
- /* The following functions are part of libpq, but not
35
- * available from ruby-pg, because they are deprecated,
36
- * obsolete, or generally not useful:
37
- *
38
- * * PQfreemem -- unnecessary: copied to ruby object, then
39
- * freed. Ruby object's memory is freed when
40
- * it is garbage collected.
41
- * * PQbinaryTuples -- better to use PQfformat
42
- * * PQprint -- not very useful
43
- * * PQsetdb -- not very useful
44
- * * PQoidStatus -- deprecated, use PQoidValue
45
- * * PQrequestCancel -- deprecated, use PQcancel
46
- * * PQfn -- use a prepared statement instead
47
- * * PQgetline -- deprecated, use PQgetCopyData
48
- * * PQgetlineAsync -- deprecated, use PQgetCopyData
49
- * * PQputline -- deprecated, use PQputCopyData
50
- * * PQputnbytes -- deprecated, use PQputCopyData
51
- * * PQendcopy -- deprecated, use PQputCopyEnd
52
- */
53
-
54
- /***************************************************************************
55
- * UTILITY FUNCTIONS
56
- **************************************************************************/
57
-
58
- static void free_pgconn( PGconn * );
59
- static void pgresult_check( VALUE, VALUE );
60
-
61
- static PGconn *get_pgconn( VALUE );
62
- static VALUE pgconn_finish( VALUE );
63
- static VALUE pgresult_clear( VALUE );
64
- static VALUE pgresult_aref( VALUE, VALUE );
65
- static VALUE make_column_result_array( VALUE, int );
66
-
67
- #ifdef M17N_SUPPORTED
68
- # define ASSOCIATE_INDEX( obj, index_holder ) rb_enc_associate_index((obj), enc_get_index((index_holder)))
69
- static rb_encoding * pgconn_get_client_encoding_as_rb_encoding( PGconn * );
70
- static const char * pgconn_get_rb_encoding_as_pg_encname( rb_encoding * );
71
- static int enc_get_index( VALUE );
72
- #else
73
- # define ASSOCIATE_INDEX( obj, index_holder ) /* nothing */
74
- #endif
75
-
76
- static PQnoticeReceiver default_notice_receiver = NULL;
77
- static PQnoticeProcessor default_notice_processor = NULL;
78
-
79
-
80
- static void
81
- free_pgconn(PGconn *conn)
82
- {
83
- if(conn != NULL)
84
- PQfinish(conn);
85
- }
86
-
87
- static void
88
- free_pgresult(PGresult *result)
89
- {
90
- if(result != NULL)
91
- PQclear(result);
92
- }
93
-
94
- static PGconn*
95
- get_pgconn(VALUE self)
96
- {
97
- PGconn *conn;
98
- Data_Get_Struct(self, PGconn, conn);
99
- if (conn == NULL) rb_raise(rb_ePGError, "not connected");
100
- return conn;
101
- }
102
-
103
- static PGresult*
104
- get_pgresult(VALUE self)
105
- {
106
- PGresult *result;
107
- Data_Get_Struct(self, PGresult, result);
108
- if (result == NULL) rb_raise(rb_ePGError, "result has been cleared");
109
- return result;
110
- }
111
-
112
- #ifdef M17N_SUPPORTED
113
- static VALUE
114
- new_pgresult(PGresult *result, PGconn *conn)
115
- {
116
- VALUE val = Data_Wrap_Struct(rb_cPGresult, NULL, free_pgresult, result);
117
- rb_encoding *enc = pgconn_get_client_encoding_as_rb_encoding(conn);
118
- rb_enc_set_index(val, rb_enc_to_index(enc));
119
- return val;
120
- }
121
- #else
122
- static VALUE
123
- new_pgresult(PGresult *result)
124
- {
125
- return Data_Wrap_Struct(rb_cPGresult, NULL, free_pgresult, result);
126
- }
127
- # define new_pgresult(result, conn) new_pgresult((result))
128
- #endif
129
-
130
- /*
131
- * Raises appropriate exception if PGresult is
132
- * in a bad state.
133
- */
134
- static void
135
- pgresult_check(VALUE rb_pgconn, VALUE rb_pgresult)
136
- {
137
- VALUE error, exception;
138
- PGconn *conn = get_pgconn(rb_pgconn);
139
- PGresult *result;
140
- Data_Get_Struct(rb_pgresult, PGresult, result);
141
- #ifdef M17N_SUPPORTED
142
- rb_encoding *enc = pgconn_get_client_encoding_as_rb_encoding(conn);
143
- #endif
144
-
145
- if(result == NULL)
146
- {
147
- error = rb_str_new2( PQerrorMessage(conn) );
148
- }
149
- else
150
- {
151
- switch (PQresultStatus(result))
152
- {
153
- case PGRES_TUPLES_OK:
154
- case PGRES_COPY_OUT:
155
- case PGRES_COPY_IN:
156
- case PGRES_EMPTY_QUERY:
157
- case PGRES_COMMAND_OK:
158
- return;
159
- case PGRES_BAD_RESPONSE:
160
- case PGRES_FATAL_ERROR:
161
- case PGRES_NONFATAL_ERROR:
162
- error = rb_str_new2( PQresultErrorMessage(result) );
163
- break;
164
- default:
165
- error = rb_str_new2( "internal error : unknown result status." );
166
- }
167
- }
168
-
169
- #ifdef M17N_SUPPORTED
170
- rb_enc_set_index( error, rb_enc_to_index(enc) );
171
- #endif
172
- exception = rb_exc_new3( rb_ePGError, error );
173
- rb_iv_set( exception, "@connection", rb_pgconn );
174
- rb_iv_set( exception, "@result", rb_pgresult );
175
- rb_exc_raise( exception );
176
-
177
- return;
178
- }
179
-
180
- static void
181
- notice_receiver_proxy(void *arg, const PGresult *result)
182
- {
183
- VALUE proc;
184
- VALUE self = (VALUE)arg;
185
-
186
- if ((proc = rb_iv_get(self, "@notice_receiver")) != Qnil) {
187
- rb_funcall(proc, rb_intern("call"), 1,
188
- Data_Wrap_Struct(rb_cPGresult, NULL, NULL, (PGresult*)result));
189
- }
190
- return;
191
- }
192
-
193
- static void
194
- notice_processor_proxy(void *arg, const char *message)
195
- {
196
- VALUE proc;
197
- VALUE self = (VALUE)arg;
198
-
199
- if ((proc = rb_iv_get(self, "@notice_processor")) != Qnil) {
200
- rb_funcall(proc, rb_intern("call"), 1, rb_tainted_str_new2(message));
201
- }
202
- return;
203
- }
204
-
205
-
206
- /********************************************************************
207
- *
208
- * Document-class: PGError
209
- *
210
- * This is the exception class raised when an error is returned from
211
- * a libpq API call.
212
- *
213
- * The attributes +connection+ and +result+ are set to the connection
214
- * object and result set object, respectively.
215
- *
216
- * If the connection object or result set object is not available from
217
- * the context in which the error was encountered, it is +nil+.
218
- */
219
-
220
- /********************************************************************
221
- *
222
- * Document-class: PGconn
223
- *
224
- * The class to access PostgreSQL RDBMS, based on the libpq interface,
225
- * provides convenient OO methods to interact with PostgreSQL.
226
- *
227
- * For example, to send query to the database on the localhost:
228
- * require 'pg'
229
- * conn = PGconn.open(:dbname => 'test')
230
- * res = conn.exec('SELECT $1 AS a, $2 AS b, $3 AS c',[1, 2, nil])
231
- * # Equivalent to:
232
- * # res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
233
- *
234
- * See the PGresult class for information on working with the results of a query.
235
- *
236
- */
237
-
238
- static VALUE
239
- pgconn_alloc(VALUE klass)
240
- {
241
- return Data_Wrap_Struct(klass, NULL, free_pgconn, NULL);
242
- }
243
-
244
- /**************************************************************************
245
- * PGconn SINGLETON METHODS
246
- **************************************************************************/
247
-
248
- /*
249
- * Document-method: new
250
- *
251
- * call-seq:
252
- * PGconn.new -> PGconn
253
- * PGconn.new(connection_hash) -> PGconn
254
- * PGconn.new(connection_string) -> PGconn
255
- * PGconn.new(host, port, options, tty, dbname, user, password) -> PGconn
256
- *
257
- * Create a connection to the specified server.
258
- *
259
- * [+host+]
260
- * server hostname
261
- * [+hostaddr+]
262
- * server address (avoids hostname lookup, overrides +host+)
263
- * [+port+]
264
- * server port number
265
- * [+dbname+]
266
- * connecting database name
267
- * [+user+]
268
- * login user name
269
- * [+password+]
270
- * login password
271
- * [+connect_timeout+]
272
- * maximum time to wait for connection to succeed
273
- * [+options+]
274
- * backend options
275
- * [+tty+]
276
- * (ignored in newer versions of PostgreSQL)
277
- * [+sslmode+]
278
- * (disable|allow|prefer|require)
279
- * [+krbsrvname+]
280
- * kerberos service name
281
- * [+gsslib+]
282
- * GSS library to use for GSSAPI authentication
283
- * [+service+]
284
- * service name to use for additional parameters
285
- *
286
- * Examples:
287
- *
288
- * # Connect using all defaults
289
- * PGconn.connect
290
- *
291
- * # As a Hash
292
- * PGconn.connect( :dbname => 'test', :port => 5432 )
293
- *
294
- * # As a String
295
- * PGconn.connect( "dbname=test port=5432" )
296
- *
297
- * # As an Array
298
- * PGconn.connect( nil, 5432, nil, nil, 'test', nil, nil )
299
- *
300
- * If the Ruby default internal encoding is set (i.e., Encoding.default_internal != nil), the
301
- * connection will have its +client_encoding+ set accordingly.
302
- *
303
- * Raises a PGError if the connection fails.
304
- */
305
- static VALUE
306
- pgconn_init(int argc, VALUE *argv, VALUE self)
307
- {
308
- PGconn *conn = NULL;
309
- VALUE conninfo;
310
- VALUE error;
311
- #ifdef M17N_SUPPORTED
312
- rb_encoding *enc;
313
- const char *encname;
314
- #endif
315
-
316
- conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
317
- conn = PQconnectdb(StringValuePtr(conninfo));
318
-
319
- if(conn == NULL)
320
- rb_raise(rb_ePGError, "PQconnectStart() unable to allocate structure");
321
-
322
- Check_Type(self, T_DATA);
323
- DATA_PTR(self) = conn;
324
-
325
- if (PQstatus(conn) == CONNECTION_BAD) {
326
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
327
- rb_iv_set(error, "@connection", self);
328
- rb_exc_raise(error);
329
- }
330
-
331
- #ifdef M17N_SUPPORTED
332
- /* If Ruby has its Encoding.default_internal set, set PostgreSQL's client_encoding
333
- * to match */
334
- if (( enc = rb_default_internal_encoding() )) {
335
- encname = pgconn_get_rb_encoding_as_pg_encname( enc );
336
- if ( PQsetClientEncoding(conn, encname) != 0 )
337
- rb_warn( "Failed to set the default_internal encoding to %s: '%s'",
338
- encname, PQerrorMessage(conn) );
339
- }
340
- #endif
341
-
342
- if (rb_block_given_p()) {
343
- return rb_ensure(rb_yield, self, pgconn_finish, self);
344
- }
345
- return self;
346
- }
347
-
348
- /*
349
- * call-seq:
350
- * PGconn.connect_start(connection_hash) -> PGconn
351
- * PGconn.connect_start(connection_string) -> PGconn
352
- * PGconn.connect_start(host, port, options, tty, dbname, login, password) -> PGconn
353
- *
354
- * This is an asynchronous version of PGconn.connect().
355
- *
356
- * Use PGconn#connect_poll to poll the status of the connection.
357
- *
358
- * NOTE: this does *not* set the connection's +client_encoding+ for you if
359
- * Encoding.default_internal is set. To set it after the connection is established,
360
- * call PGconn#internal_encoding=. You can also set it automatically by setting
361
- * ENV['PGCLIENTENCODING'], or include the 'options' connection parameter.
362
- *
363
- */
364
- static VALUE
365
- pgconn_s_connect_start(int argc, VALUE *argv, VALUE self)
366
- {
367
- PGconn *conn = NULL;
368
- VALUE rb_conn;
369
- VALUE conninfo;
370
- VALUE error;
371
-
372
- /*
373
- * PGconn.connect_start must act as both alloc() and initialize()
374
- * because it is not invoked by calling new().
375
- */
376
- rb_conn = pgconn_alloc(rb_cPGconn);
377
-
378
- conninfo = rb_funcall2( rb_cPGconn, rb_intern("parse_connect_args"), argc, argv );
379
- conn = PQconnectStart(StringValuePtr(conninfo));
380
-
381
- if(conn == NULL)
382
- rb_raise(rb_ePGError, "PQconnectStart() unable to allocate structure");
383
- if (PQstatus(conn) == CONNECTION_BAD) {
384
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
385
- rb_iv_set(error, "@connection", self);
386
- rb_exc_raise(error);
387
- }
388
-
389
- Check_Type(rb_conn, T_DATA);
390
- DATA_PTR(rb_conn) = conn;
391
-
392
- if (rb_block_given_p()) {
393
- return rb_ensure(rb_yield, self, pgconn_finish, self);
394
- }
395
- return rb_conn;
396
- }
397
-
398
- /*
399
- * call-seq:
400
- * PGconn.conndefaults() -> Array
401
- *
402
- * Returns an array of hashes. Each hash has the keys:
403
- * [+:keyword+]
404
- * the name of the option
405
- * [+:envvar+]
406
- * the environment variable to fall back to
407
- * [+:compiled+]
408
- * the compiled in option as a secondary fallback
409
- * [+:val+]
410
- * the option's current value, or +nil+ if not known
411
- * [+:label+]
412
- * the label for the field
413
- * [+:dispchar+]
414
- * "" for normal, "D" for debug, and "*" for password
415
- * [+:dispsize+]
416
- * field size
417
- */
418
- static VALUE
419
- pgconn_s_conndefaults(VALUE self)
420
- {
421
- PQconninfoOption *options = PQconndefaults();
422
- VALUE ary = rb_ary_new();
423
- VALUE hash;
424
- int i = 0;
425
-
426
- for(i = 0; options[i].keyword != NULL; i++) {
427
- hash = rb_hash_new();
428
- if(options[i].keyword)
429
- rb_hash_aset(hash, ID2SYM(rb_intern("keyword")),
430
- rb_str_new2(options[i].keyword));
431
- if(options[i].envvar)
432
- rb_hash_aset(hash, ID2SYM(rb_intern("envvar")),
433
- rb_str_new2(options[i].envvar));
434
- if(options[i].compiled)
435
- rb_hash_aset(hash, ID2SYM(rb_intern("compiled")),
436
- rb_str_new2(options[i].compiled));
437
- if(options[i].val)
438
- rb_hash_aset(hash, ID2SYM(rb_intern("val")),
439
- rb_str_new2(options[i].val));
440
- if(options[i].label)
441
- rb_hash_aset(hash, ID2SYM(rb_intern("label")),
442
- rb_str_new2(options[i].label));
443
- if(options[i].dispchar)
444
- rb_hash_aset(hash, ID2SYM(rb_intern("dispchar")),
445
- rb_str_new2(options[i].dispchar));
446
- rb_hash_aset(hash, ID2SYM(rb_intern("dispsize")),
447
- INT2NUM(options[i].dispsize));
448
- rb_ary_push(ary, hash);
449
- }
450
- PQconninfoFree(options);
451
- return ary;
452
- }
453
-
454
-
455
- /*
456
- * call-seq:
457
- * PGconn.encrypt_password( password, username ) -> String
458
- *
459
- * This function is intended to be used by client applications that
460
- * send commands like: +ALTER USER joe PASSWORD 'pwd'+.
461
- * The arguments are the cleartext password, and the SQL name
462
- * of the user it is for.
463
- *
464
- * Return value is the encrypted password.
465
- */
466
- static VALUE
467
- pgconn_s_encrypt_password(VALUE self, VALUE password, VALUE username)
468
- {
469
- char *encrypted = NULL;
470
- VALUE rval = Qnil;
471
-
472
- Check_Type(password, T_STRING);
473
- Check_Type(username, T_STRING);
474
-
475
- encrypted = PQencryptPassword(StringValuePtr(password), StringValuePtr(username));
476
- rval = rb_str_new2( encrypted );
477
- PQfreemem( encrypted );
478
-
479
- OBJ_INFECT( rval, password );
480
- OBJ_INFECT( rval, username );
481
-
482
- return rval;
483
- }
484
-
485
-
486
- /*
487
- * call-seq:
488
- * PGconn.isthreadsafe() -> Boolean
489
- *
490
- * Returns +true+ if libpq is thread safe, +false+ otherwise.
491
- */
492
- static VALUE
493
- pgconn_s_isthreadsafe(VALUE self)
494
- {
495
- return PQisthreadsafe() ? Qtrue : Qfalse;
496
- }
497
-
498
- /**************************************************************************
499
- * PGconn INSTANCE METHODS
500
- **************************************************************************/
501
-
502
- /*
503
- * call-seq:
504
- * conn.connect_poll() -> Fixnum
505
- *
506
- * Returns one of:
507
- * [+PGRES_POLLING_READING+]
508
- * wait until the socket is ready to read
509
- * [+PGRES_POLLING_WRITING+]
510
- * wait until the socket is ready to write
511
- * [+PGRES_POLLING_FAILED+]
512
- * the asynchronous connection has failed
513
- * [+PGRES_POLLING_OK+]
514
- * the asynchronous connection is ready
515
- *
516
- * Example:
517
- * conn = PGconn.connect_start("dbname=mydatabase")
518
- * socket = IO.for_fd(conn.socket)
519
- * status = conn.connect_poll
520
- * while(status != PGconn::PGRES_POLLING_OK) do
521
- * # do some work while waiting for the connection to complete
522
- * if(status == PGconn::PGRES_POLLING_READING)
523
- * if(not select([socket], [], [], 10.0))
524
- * raise "Asynchronous connection timed out!"
525
- * end
526
- * elsif(status == PGconn::PGRES_POLLING_WRITING)
527
- * if(not select([], [socket], [], 10.0))
528
- * raise "Asynchronous connection timed out!"
529
- * end
530
- * end
531
- * status = conn.connect_poll
532
- * end
533
- * # now conn.status == CONNECTION_OK, and connection
534
- * # is ready.
535
- */
536
- static VALUE
537
- pgconn_connect_poll(VALUE self)
538
- {
539
- PostgresPollingStatusType status;
540
- status = PQconnectPoll(get_pgconn(self));
541
- return INT2FIX((int)status);
542
- }
543
-
544
- /*
545
- * call-seq:
546
- * conn.finish()
547
- *
548
- * Closes the backend connection.
549
- */
550
- static VALUE
551
- pgconn_finish(VALUE self)
552
- {
553
- PQfinish(get_pgconn(self));
554
- DATA_PTR(self) = NULL;
555
- return Qnil;
556
- }
557
-
558
- /*
559
- * call-seq:
560
- * conn.reset()
561
- *
562
- * Resets the backend connection. This method closes the
563
- * backend connection and tries to re-connect.
564
- */
565
- static VALUE
566
- pgconn_reset(VALUE self)
567
- {
568
- PQreset(get_pgconn(self));
569
- return self;
570
- }
571
-
572
- /*
573
- * call-seq:
574
- * conn.reset_start() -> nil
575
- *
576
- * Initiate a connection reset in a nonblocking manner.
577
- * This will close the current connection and attempt to
578
- * reconnect using the same connection parameters.
579
- * Use PGconn#reset_poll to check the status of the
580
- * connection reset.
581
- */
582
- static VALUE
583
- pgconn_reset_start(VALUE self)
584
- {
585
- if(PQresetStart(get_pgconn(self)) == 0)
586
- rb_raise(rb_ePGError, "reset has failed");
587
- return Qnil;
588
- }
589
-
590
- /*
591
- * call-seq:
592
- * conn.reset_poll -> Fixnum
593
- *
594
- * Checks the status of a connection reset operation.
595
- * See PGconn#connect_start and PGconn#connect_poll for
596
- * usage information and return values.
597
- */
598
- static VALUE
599
- pgconn_reset_poll(VALUE self)
600
- {
601
- PostgresPollingStatusType status;
602
- status = PQresetPoll(get_pgconn(self));
603
- return INT2FIX((int)status);
604
- }
605
-
606
- /*
607
- * call-seq:
608
- * conn.db()
609
- *
610
- * Returns the connected database name.
611
- */
612
- static VALUE
613
- pgconn_db(VALUE self)
614
- {
615
- char *db = PQdb(get_pgconn(self));
616
- if (!db) return Qnil;
617
- return rb_tainted_str_new2(db);
618
- }
619
-
620
- /*
621
- * call-seq:
622
- * conn.user()
623
- *
624
- * Returns the authenticated user name.
625
- */
626
- static VALUE
627
- pgconn_user(VALUE self)
628
- {
629
- char *user = PQuser(get_pgconn(self));
630
- if (!user) return Qnil;
631
- return rb_tainted_str_new2(user);
632
- }
633
-
634
- /*
635
- * call-seq:
636
- * conn.pass()
637
- *
638
- * Returns the authenticated user name.
639
- */
640
- static VALUE
641
- pgconn_pass(VALUE self)
642
- {
643
- char *user = PQpass(get_pgconn(self));
644
- if (!user) return Qnil;
645
- return rb_tainted_str_new2(user);
646
- }
647
-
648
- /*
649
- * call-seq:
650
- * conn.host()
651
- *
652
- * Returns the connected server name.
653
- */
654
- static VALUE
655
- pgconn_host(VALUE self)
656
- {
657
- char *host = PQhost(get_pgconn(self));
658
- if (!host) return Qnil;
659
- return rb_tainted_str_new2(host);
660
- }
661
-
662
- /*
663
- * call-seq:
664
- * conn.port()
665
- *
666
- * Returns the connected server port number.
667
- */
668
- static VALUE
669
- pgconn_port(VALUE self)
670
- {
671
- char* port = PQport(get_pgconn(self));
672
- return INT2NUM(atol(port));
673
- }
674
-
675
- /*
676
- * call-seq:
677
- * conn.tty()
678
- *
679
- * Returns the connected pgtty. (Obsolete)
680
- */
681
- static VALUE
682
- pgconn_tty(VALUE self)
683
- {
684
- char *tty = PQtty(get_pgconn(self));
685
- if (!tty) return Qnil;
686
- return rb_tainted_str_new2(tty);
687
- }
688
-
689
- /*
690
- * call-seq:
691
- * conn.options()
692
- *
693
- * Returns backend option string.
694
- */
695
- static VALUE
696
- pgconn_options(VALUE self)
697
- {
698
- char *options = PQoptions(get_pgconn(self));
699
- if (!options) return Qnil;
700
- return rb_tainted_str_new2(options);
701
- }
702
-
703
- /*
704
- * call-seq:
705
- * conn.status()
706
- *
707
- * Returns status of connection : CONNECTION_OK or CONNECTION_BAD
708
- */
709
- static VALUE
710
- pgconn_status(VALUE self)
711
- {
712
- return INT2NUM(PQstatus(get_pgconn(self)));
713
- }
714
-
715
- /*
716
- * call-seq:
717
- * conn.transaction_status()
718
- *
719
- * returns one of the following statuses:
720
- * PQTRANS_IDLE = 0 (connection idle)
721
- * PQTRANS_ACTIVE = 1 (command in progress)
722
- * PQTRANS_INTRANS = 2 (idle, within transaction block)
723
- * PQTRANS_INERROR = 3 (idle, within failed transaction)
724
- * PQTRANS_UNKNOWN = 4 (cannot determine status)
725
- */
726
- static VALUE
727
- pgconn_transaction_status(VALUE self)
728
- {
729
- return INT2NUM(PQtransactionStatus(get_pgconn(self)));
730
- }
731
-
732
- /*
733
- * call-seq:
734
- * conn.parameter_status( param_name ) -> String
735
- *
736
- * Returns the setting of parameter _param_name_, where
737
- * _param_name_ is one of
738
- * * +server_version+
739
- * * +server_encoding+
740
- * * +client_encoding+
741
- * * +is_superuser+
742
- * * +session_authorization+
743
- * * +DateStyle+
744
- * * +TimeZone+
745
- * * +integer_datetimes+
746
- * * +standard_conforming_strings+
747
- *
748
- * Returns nil if the value of the parameter is not known.
749
- */
750
- static VALUE
751
- pgconn_parameter_status(VALUE self, VALUE param_name)
752
- {
753
- const char *ret = PQparameterStatus(get_pgconn(self),
754
- StringValuePtr(param_name));
755
- if(ret == NULL)
756
- return Qnil;
757
- else
758
- return rb_tainted_str_new2(ret);
759
- }
760
-
761
- /*
762
- * call-seq:
763
- * conn.protocol_version -> Integer
764
- *
765
- * The 3.0 protocol will normally be used when communicating with PostgreSQL 7.4
766
- * or later servers; pre-7.4 servers support only protocol 2.0. (Protocol 1.0 is
767
- * obsolete and not supported by libpq.)
768
- */
769
- static VALUE
770
- pgconn_protocol_version(VALUE self)
771
- {
772
- return INT2NUM(PQprotocolVersion(get_pgconn(self)));
773
- }
774
-
775
- /*
776
- * call-seq:
777
- * conn.server_version -> Integer
778
- *
779
- * The number is formed by converting the major, minor, and revision
780
- * numbers into two-decimal-digit numbers and appending them together.
781
- * For example, version 7.4.2 will be returned as 70402, and version
782
- * 8.1 will be returned as 80100 (leading zeroes are not shown). Zero
783
- * is returned if the connection is bad.
784
- *
785
- */
786
- static VALUE
787
- pgconn_server_version(VALUE self)
788
- {
789
- return INT2NUM(PQserverVersion(get_pgconn(self)));
790
- }
791
-
792
- /*
793
- * call-seq:
794
- * conn.error_message -> String
795
- *
796
- * Returns the error message about connection.
797
- */
798
- static VALUE
799
- pgconn_error_message(VALUE self)
800
- {
801
- char *error = PQerrorMessage(get_pgconn(self));
802
- if (!error) return Qnil;
803
- return rb_tainted_str_new2(error);
804
- }
805
-
806
- /*
807
- * call-seq:
808
- * conn.socket() -> Fixnum
809
- *
810
- * Returns the socket's file descriptor for this connection.
811
- */
812
- static VALUE
813
- pgconn_socket(VALUE self)
814
- {
815
- int sd;
816
- if( (sd = PQsocket(get_pgconn(self))) < 0)
817
- rb_raise(rb_ePGError, "Can't get socket descriptor");
818
- return INT2NUM(sd);
819
- }
820
-
821
-
822
- /*
823
- * call-seq:
824
- * conn.backend_pid() -> Fixnum
825
- *
826
- * Returns the process ID of the backend server
827
- * process for this connection.
828
- * Note that this is a PID on database server host.
829
- */
830
- static VALUE
831
- pgconn_backend_pid(VALUE self)
832
- {
833
- return INT2NUM(PQbackendPID(get_pgconn(self)));
834
- }
835
-
836
- /*
837
- * call-seq:
838
- * conn.connection_needs_password() -> Boolean
839
- *
840
- * Returns +true+ if the authentication method required a
841
- * password, but none was available. +false+ otherwise.
842
- */
843
- static VALUE
844
- pgconn_connection_needs_password(VALUE self)
845
- {
846
- return PQconnectionNeedsPassword(get_pgconn(self)) ? Qtrue : Qfalse;
847
- }
848
-
849
- /*
850
- * call-seq:
851
- * conn.connection_used_password() -> Boolean
852
- *
853
- * Returns +true+ if the authentication method used
854
- * a caller-supplied password, +false+ otherwise.
855
- */
856
- static VALUE
857
- pgconn_connection_used_password(VALUE self)
858
- {
859
- return PQconnectionUsedPassword(get_pgconn(self)) ? Qtrue : Qfalse;
860
- }
861
-
862
-
863
- //TODO get_ssl
864
-
865
-
866
- /*
867
- * call-seq:
868
- * conn.exec(sql [, params, result_format ] ) -> PGresult
869
- * conn.exec(sql [, params, result_format ] ) {|pg_result| block }
870
- *
871
- * Sends SQL query request specified by _sql_ to PostgreSQL.
872
- * Returns a PGresult instance on success.
873
- * On failure, it raises a PGError exception.
874
- *
875
- * +params+ is an optional array of the bind parameters for the SQL query.
876
- * Each element of the +params+ array may be either:
877
- * a hash of the form:
878
- * {:value => String (value of bind parameter)
879
- * :type => Fixnum (oid of type of bind parameter)
880
- * :format => Fixnum (0 for text, 1 for binary)
881
- * }
882
- * or, it may be a String. If it is a string, that is equivalent to the hash:
883
- * { :value => <string value>, :type => 0, :format => 0 }
884
- *
885
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
886
- * inside the SQL query. The 0th element of the +params+ array is bound
887
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
888
- *
889
- * If the types are not specified, they will be inferred by PostgreSQL.
890
- * Instead of specifying type oids, it's recommended to simply add
891
- * explicit casts in the query to ensure that the right type is used.
892
- *
893
- * For example: "SELECT $1::int"
894
- *
895
- * The optional +result_format+ should be 0 for text results, 1
896
- * for binary.
897
- *
898
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
899
- * and the PGresult object will automatically be cleared when the block terminates.
900
- * In this instance, <code>conn.exec</code> returns the value of the block.
901
- */
902
- static VALUE
903
- pgconn_exec(int argc, VALUE *argv, VALUE self)
904
- {
905
- PGconn *conn = get_pgconn(self);
906
- PGresult *result = NULL;
907
- VALUE rb_pgresult;
908
- VALUE command, params, in_res_fmt;
909
- VALUE param, param_type, param_value, param_format;
910
- VALUE param_value_tmp;
911
- VALUE sym_type, sym_value, sym_format;
912
- VALUE gc_array;
913
- int i=0;
914
- int nParams;
915
- Oid *paramTypes;
916
- char ** paramValues;
917
- int *paramLengths;
918
- int *paramFormats;
919
- int resultFormat;
920
-
921
- rb_scan_args(argc, argv, "12", &command, &params, &in_res_fmt);
922
-
923
- Check_Type(command, T_STRING);
924
-
925
- /* If called with no parameters, use PQexec */
926
- if(NIL_P(params)) {
927
- result = PQexec(conn, StringValuePtr(command));
928
- rb_pgresult = new_pgresult(result, conn);
929
- pgresult_check(self, rb_pgresult);
930
- if (rb_block_given_p()) {
931
- return rb_ensure(rb_yield, rb_pgresult,
932
- pgresult_clear, rb_pgresult);
933
- }
934
- return rb_pgresult;
935
- }
936
-
937
- /* If called with parameters, and optionally result_format,
938
- * use PQexecParams
939
- */
940
- Check_Type(params, T_ARRAY);
941
-
942
- if(NIL_P(in_res_fmt)) {
943
- resultFormat = 0;
944
- }
945
- else {
946
- resultFormat = NUM2INT(in_res_fmt);
947
- }
948
-
949
- gc_array = rb_ary_new();
950
- rb_gc_register_address(&gc_array);
951
- sym_type = ID2SYM(rb_intern("type"));
952
- sym_value = ID2SYM(rb_intern("value"));
953
- sym_format = ID2SYM(rb_intern("format"));
954
- nParams = RARRAY_LEN(params);
955
- paramTypes = ALLOC_N(Oid, nParams);
956
- paramValues = ALLOC_N(char *, nParams);
957
- paramLengths = ALLOC_N(int, nParams);
958
- paramFormats = ALLOC_N(int, nParams);
959
- for(i = 0; i < nParams; i++) {
960
- param = rb_ary_entry(params, i);
961
- if (TYPE(param) == T_HASH) {
962
- param_type = rb_hash_aref(param, sym_type);
963
- param_value_tmp = rb_hash_aref(param, sym_value);
964
- if(param_value_tmp == Qnil)
965
- param_value = param_value_tmp;
966
- else
967
- param_value = rb_obj_as_string(param_value_tmp);
968
- param_format = rb_hash_aref(param, sym_format);
969
- }
970
- else {
971
- param_type = Qnil;
972
- if(param == Qnil)
973
- param_value = param;
974
- else
975
- param_value = rb_obj_as_string(param);
976
- param_format = Qnil;
977
- }
978
-
979
- if(param_type == Qnil)
980
- paramTypes[i] = 0;
981
- else
982
- paramTypes[i] = NUM2INT(param_type);
983
-
984
- if(param_value == Qnil) {
985
- paramValues[i] = NULL;
986
- paramLengths[i] = 0;
987
- }
988
- else {
989
- Check_Type(param_value, T_STRING);
990
- /* make sure param_value doesn't get freed by the GC */
991
- rb_ary_push(gc_array, param_value);
992
- paramValues[i] = StringValuePtr(param_value);
993
- paramLengths[i] = RSTRING_LEN(param_value);
994
- }
995
-
996
- if(param_format == Qnil)
997
- paramFormats[i] = 0;
998
- else
999
- paramFormats[i] = NUM2INT(param_format);
1000
- }
1001
-
1002
- result = PQexecParams(conn, StringValuePtr(command), nParams, paramTypes,
1003
- (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
1004
-
1005
- rb_gc_unregister_address(&gc_array);
1006
-
1007
- xfree(paramTypes);
1008
- xfree(paramValues);
1009
- xfree(paramLengths);
1010
- xfree(paramFormats);
1011
-
1012
- rb_pgresult = new_pgresult(result, conn);
1013
- pgresult_check(self, rb_pgresult);
1014
- if (rb_block_given_p()) {
1015
- return rb_ensure(rb_yield, rb_pgresult,
1016
- pgresult_clear, rb_pgresult);
1017
- }
1018
- return rb_pgresult;
1019
- }
1020
-
1021
- /*
1022
- * call-seq:
1023
- * conn.prepare(stmt_name, sql [, param_types ] ) -> PGresult
1024
- *
1025
- * Prepares statement _sql_ with name _name_ to be executed later.
1026
- * Returns a PGresult instance on success.
1027
- * On failure, it raises a PGError exception.
1028
- *
1029
- * +param_types+ is an optional parameter to specify the Oids of the
1030
- * types of the parameters.
1031
- *
1032
- * If the types are not specified, they will be inferred by PostgreSQL.
1033
- * Instead of specifying type oids, it's recommended to simply add
1034
- * explicit casts in the query to ensure that the right type is used.
1035
- *
1036
- * For example: "SELECT $1::int"
1037
- *
1038
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1039
- * inside the SQL query.
1040
- */
1041
- static VALUE
1042
- pgconn_prepare(int argc, VALUE *argv, VALUE self)
1043
- {
1044
- PGconn *conn = get_pgconn(self);
1045
- PGresult *result = NULL;
1046
- VALUE rb_pgresult;
1047
- VALUE name, command, in_paramtypes;
1048
- VALUE param;
1049
- int i = 0;
1050
- int nParams = 0;
1051
- Oid *paramTypes = NULL;
1052
-
1053
- rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1054
- Check_Type(name, T_STRING);
1055
- Check_Type(command, T_STRING);
1056
-
1057
- if(! NIL_P(in_paramtypes)) {
1058
- Check_Type(in_paramtypes, T_ARRAY);
1059
- nParams = RARRAY_LEN(in_paramtypes);
1060
- paramTypes = ALLOC_N(Oid, nParams);
1061
- for(i = 0; i < nParams; i++) {
1062
- param = rb_ary_entry(in_paramtypes, i);
1063
- Check_Type(param, T_FIXNUM);
1064
- if(param == Qnil)
1065
- paramTypes[i] = 0;
1066
- else
1067
- paramTypes[i] = NUM2INT(param);
1068
- }
1069
- }
1070
- result = PQprepare(conn, StringValuePtr(name), StringValuePtr(command),
1071
- nParams, paramTypes);
1072
-
1073
- xfree(paramTypes);
1074
-
1075
- rb_pgresult = new_pgresult(result, conn);
1076
- pgresult_check(self, rb_pgresult);
1077
- return rb_pgresult;
1078
- }
1079
-
1080
- /*
1081
- * call-seq:
1082
- * conn.exec_prepared(statement_name [, params, result_format ] ) -> PGresult
1083
- * conn.exec_prepared(statement_name [, params, result_format ] ) {|pg_result| block }
1084
- *
1085
- * Execute prepared named statement specified by _statement_name_.
1086
- * Returns a PGresult instance on success.
1087
- * On failure, it raises a PGError exception.
1088
- *
1089
- * +params+ is an array of the optional bind parameters for the
1090
- * SQL query. Each element of the +params+ array may be either:
1091
- * a hash of the form:
1092
- * {:value => String (value of bind parameter)
1093
- * :format => Fixnum (0 for text, 1 for binary)
1094
- * }
1095
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1096
- * { :value => <string value>, :format => 0 }
1097
- *
1098
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1099
- * inside the SQL query. The 0th element of the +params+ array is bound
1100
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1101
- *
1102
- * The optional +result_format+ should be 0 for text results, 1
1103
- * for binary.
1104
- *
1105
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1106
- * and the PGresult object will automatically be cleared when the block terminates.
1107
- * In this instance, <code>conn.exec_prepared</code> returns the value of the block.
1108
- */
1109
- static VALUE
1110
- pgconn_exec_prepared(int argc, VALUE *argv, VALUE self)
1111
- {
1112
- PGconn *conn = get_pgconn(self);
1113
- PGresult *result = NULL;
1114
- VALUE rb_pgresult;
1115
- VALUE name, params, in_res_fmt;
1116
- VALUE param, param_value, param_format;
1117
- VALUE param_value_tmp;
1118
- VALUE sym_value, sym_format;
1119
- VALUE gc_array;
1120
- int i = 0;
1121
- int nParams;
1122
- char ** paramValues;
1123
- int *paramLengths;
1124
- int *paramFormats;
1125
- int resultFormat;
1126
-
1127
-
1128
- rb_scan_args(argc, argv, "12", &name, &params, &in_res_fmt);
1129
- Check_Type(name, T_STRING);
1130
-
1131
- if(NIL_P(params)) {
1132
- params = rb_ary_new2(0);
1133
- resultFormat = 0;
1134
- }
1135
- else {
1136
- Check_Type(params, T_ARRAY);
1137
- }
1138
-
1139
- if(NIL_P(in_res_fmt)) {
1140
- resultFormat = 0;
1141
- }
1142
- else {
1143
- resultFormat = NUM2INT(in_res_fmt);
1144
- }
1145
-
1146
- gc_array = rb_ary_new();
1147
- rb_gc_register_address(&gc_array);
1148
- sym_value = ID2SYM(rb_intern("value"));
1149
- sym_format = ID2SYM(rb_intern("format"));
1150
- nParams = RARRAY_LEN(params);
1151
- paramValues = ALLOC_N(char *, nParams);
1152
- paramLengths = ALLOC_N(int, nParams);
1153
- paramFormats = ALLOC_N(int, nParams);
1154
- for(i = 0; i < nParams; i++) {
1155
- param = rb_ary_entry(params, i);
1156
- if (TYPE(param) == T_HASH) {
1157
- param_value_tmp = rb_hash_aref(param, sym_value);
1158
- if(param_value_tmp == Qnil)
1159
- param_value = param_value_tmp;
1160
- else
1161
- param_value = rb_obj_as_string(param_value_tmp);
1162
- param_format = rb_hash_aref(param, sym_format);
1163
- }
1164
- else {
1165
- if(param == Qnil)
1166
- param_value = param;
1167
- else
1168
- param_value = rb_obj_as_string(param);
1169
- param_format = INT2NUM(0);
1170
- }
1171
- if(param_value == Qnil) {
1172
- paramValues[i] = NULL;
1173
- paramLengths[i] = 0;
1174
- }
1175
- else {
1176
- Check_Type(param_value, T_STRING);
1177
- /* make sure param_value doesn't get freed by the GC */
1178
- rb_ary_push(gc_array, param_value);
1179
- paramValues[i] = StringValuePtr(param_value);
1180
- paramLengths[i] = RSTRING_LEN(param_value);
1181
- }
1182
-
1183
- if(param_format == Qnil)
1184
- paramFormats[i] = 0;
1185
- else
1186
- paramFormats[i] = NUM2INT(param_format);
1187
- }
1188
-
1189
- result = PQexecPrepared(conn, StringValuePtr(name), nParams,
1190
- (const char * const *)paramValues, paramLengths, paramFormats,
1191
- resultFormat);
1192
-
1193
- rb_gc_unregister_address(&gc_array);
1194
-
1195
- xfree(paramValues);
1196
- xfree(paramLengths);
1197
- xfree(paramFormats);
1198
-
1199
- rb_pgresult = new_pgresult(result, conn);
1200
- pgresult_check(self, rb_pgresult);
1201
- if (rb_block_given_p()) {
1202
- return rb_ensure(rb_yield, rb_pgresult,
1203
- pgresult_clear, rb_pgresult);
1204
- }
1205
- return rb_pgresult;
1206
- }
1207
-
1208
- /*
1209
- * call-seq:
1210
- * conn.describe_prepared( statement_name ) -> PGresult
1211
- *
1212
- * Retrieve information about the prepared statement
1213
- * _statement_name_.
1214
- */
1215
- static VALUE
1216
- pgconn_describe_prepared(VALUE self, VALUE stmt_name)
1217
- {
1218
- PGresult *result;
1219
- VALUE rb_pgresult;
1220
- PGconn *conn = get_pgconn(self);
1221
- char *stmt;
1222
- if(stmt_name == Qnil) {
1223
- stmt = NULL;
1224
- }
1225
- else {
1226
- Check_Type(stmt_name, T_STRING);
1227
- stmt = StringValuePtr(stmt_name);
1228
- }
1229
- result = PQdescribePrepared(conn, stmt);
1230
- rb_pgresult = new_pgresult(result, conn);
1231
- pgresult_check(self, rb_pgresult);
1232
- return rb_pgresult;
1233
- }
1234
-
1235
-
1236
- /*
1237
- * call-seq:
1238
- * conn.describe_portal( portal_name ) -> PGresult
1239
- *
1240
- * Retrieve information about the portal _portal_name_.
1241
- */
1242
- static VALUE
1243
- pgconn_describe_portal(self, stmt_name)
1244
- VALUE self, stmt_name;
1245
- {
1246
- PGresult *result;
1247
- VALUE rb_pgresult;
1248
- PGconn *conn = get_pgconn(self);
1249
- char *stmt;
1250
- if(stmt_name == Qnil) {
1251
- stmt = NULL;
1252
- }
1253
- else {
1254
- Check_Type(stmt_name, T_STRING);
1255
- stmt = StringValuePtr(stmt_name);
1256
- }
1257
- result = PQdescribePortal(conn, stmt);
1258
- rb_pgresult = new_pgresult(result, conn);
1259
- pgresult_check(self, rb_pgresult);
1260
- return rb_pgresult;
1261
- }
1262
-
1263
-
1264
- /*
1265
- * call-seq:
1266
- * conn.make_empty_pgresult( status ) -> PGresult
1267
- *
1268
- * Constructs and empty PGresult with status _status_.
1269
- * _status_ may be one of:
1270
- * * +PGRES_EMPTY_QUERY+
1271
- * * +PGRES_COMMAND_OK+
1272
- * * +PGRES_TUPLES_OK+
1273
- * * +PGRES_COPY_OUT+
1274
- * * +PGRES_COPY_IN+
1275
- * * +PGRES_BAD_RESPONSE+
1276
- * * +PGRES_NONFATAL_ERROR+
1277
- * * +PGRES_FATAL_ERROR+
1278
- */
1279
- static VALUE
1280
- pgconn_make_empty_pgresult(VALUE self, VALUE status)
1281
- {
1282
- PGresult *result;
1283
- VALUE rb_pgresult;
1284
- PGconn *conn = get_pgconn(self);
1285
- result = PQmakeEmptyPGresult(conn, NUM2INT(status));
1286
- rb_pgresult = new_pgresult(result, conn);
1287
- pgresult_check(self, rb_pgresult);
1288
- return rb_pgresult;
1289
- }
1290
-
1291
-
1292
- /*
1293
- * call-seq:
1294
- * conn.escape_string( str ) -> String
1295
- *
1296
- * Connection instance method for versions of 8.1 and higher of libpq
1297
- * uses PQescapeStringConn, which is safer. Avoid calling as a class method,
1298
- * the class method uses the deprecated PQescapeString() API function.
1299
- *
1300
- * Returns a SQL-safe version of the String _str_.
1301
- * This is the preferred way to make strings safe for inclusion in
1302
- * SQL queries.
1303
- *
1304
- * Consider using exec_params, which avoids the need for passing values
1305
- * inside of SQL commands.
1306
- *
1307
- * Encoding of escaped string will be equal to client encoding of connection.
1308
- */
1309
- static VALUE
1310
- pgconn_s_escape(VALUE self, VALUE string)
1311
- {
1312
- char *escaped;
1313
- int size,error;
1314
- VALUE result;
1315
- #ifdef M17N_SUPPORTED
1316
- rb_encoding* enc;
1317
- #endif
1318
-
1319
- Check_Type(string, T_STRING);
1320
-
1321
- escaped = ALLOC_N(char, RSTRING_LEN(string) * 2 + 1);
1322
- if(rb_obj_class(self) == rb_cPGconn) {
1323
- size = PQescapeStringConn(get_pgconn(self), escaped,
1324
- RSTRING_PTR(string), RSTRING_LEN(string), &error);
1325
- if(error) {
1326
- xfree(escaped);
1327
- rb_raise(rb_ePGError, "%s", PQerrorMessage(get_pgconn(self)));
1328
- }
1329
- } else {
1330
- size = PQescapeString(escaped, RSTRING_PTR(string),
1331
- RSTRING_LEN(string));
1332
- }
1333
- result = rb_str_new(escaped, size);
1334
- xfree(escaped);
1335
- OBJ_INFECT(result, string);
1336
-
1337
- #ifdef M17N_SUPPORTED
1338
- if(rb_obj_class(self) == rb_cPGconn) {
1339
- enc = pgconn_get_client_encoding_as_rb_encoding(get_pgconn(self));
1340
- } else {
1341
- enc = rb_enc_get(string);
1342
- }
1343
- rb_enc_associate(result, enc);
1344
- #endif
1345
-
1346
- return result;
1347
- }
1348
-
1349
- /*
1350
- * call-seq:
1351
- * conn.escape_bytea( string ) -> String
1352
- *
1353
- * Connection instance method for versions of 8.1 and higher of libpq
1354
- * uses PQescapeByteaConn, which is safer. Avoid calling as a class method,
1355
- * the class method uses the deprecated PQescapeBytea() API function.
1356
- *
1357
- * Use the instance method version of this function, it is safer than the
1358
- * class method.
1359
- *
1360
- * Escapes binary data for use within an SQL command with the type +bytea+.
1361
- *
1362
- * Certain byte values must be escaped (but all byte values may be escaped)
1363
- * when used as part of a +bytea+ literal in an SQL statement. In general, to
1364
- * escape a byte, it is converted into the three digit octal number equal to
1365
- * the octet value, and preceded by two backslashes. The single quote (') and
1366
- * backslash (\) characters have special alternative escape sequences.
1367
- * #escape_bytea performs this operation, escaping only the minimally required
1368
- * bytes.
1369
- *
1370
- * Consider using exec_params, which avoids the need for passing values inside of
1371
- * SQL commands.
1372
- */
1373
- static VALUE
1374
- pgconn_s_escape_bytea(VALUE self, VALUE str)
1375
- {
1376
- unsigned char *from, *to;
1377
- size_t from_len, to_len;
1378
- VALUE ret;
1379
-
1380
- Check_Type(str, T_STRING);
1381
- from = (unsigned char*)RSTRING_PTR(str);
1382
- from_len = RSTRING_LEN(str);
1383
-
1384
- if(rb_obj_class(self) == rb_cPGconn) {
1385
- to = PQescapeByteaConn(get_pgconn(self), from, from_len, &to_len);
1386
- } else {
1387
- to = PQescapeBytea( from, from_len, &to_len);
1388
- }
1389
-
1390
- ret = rb_str_new((char*)to, to_len - 1);
1391
- OBJ_INFECT(ret, str);
1392
- PQfreemem(to);
1393
- return ret;
1394
- }
1395
-
1396
-
1397
- /*
1398
- * call-seq:
1399
- * PGconn.unescape_bytea( string )
1400
- *
1401
- * Converts an escaped string representation of binary data into binary data --- the
1402
- * reverse of #escape_bytea. This is needed when retrieving +bytea+ data in text format,
1403
- * but not when retrieving it in binary format.
1404
- *
1405
- */
1406
- static VALUE
1407
- pgconn_s_unescape_bytea(VALUE self, VALUE str)
1408
- {
1409
- unsigned char *from, *to;
1410
- size_t to_len;
1411
- VALUE ret;
1412
-
1413
- Check_Type(str, T_STRING);
1414
- from = (unsigned char*)StringValuePtr(str);
1415
-
1416
- to = PQunescapeBytea(from, &to_len);
1417
-
1418
- ret = rb_str_new((char*)to, to_len);
1419
- OBJ_INFECT(ret, str);
1420
- PQfreemem(to);
1421
- return ret;
1422
- }
1423
-
1424
- /*
1425
- * call-seq:
1426
- * conn.send_query(sql [, params, result_format ] ) -> nil
1427
- *
1428
- * Sends SQL query request specified by _sql_ to PostgreSQL for
1429
- * asynchronous processing, and immediately returns.
1430
- * On failure, it raises a PGError exception.
1431
- *
1432
- * +params+ is an optional array of the bind parameters for the SQL query.
1433
- * Each element of the +params+ array may be either:
1434
- * a hash of the form:
1435
- * {:value => String (value of bind parameter)
1436
- * :type => Fixnum (oid of type of bind parameter)
1437
- * :format => Fixnum (0 for text, 1 for binary)
1438
- * }
1439
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1440
- * { :value => <string value>, :type => 0, :format => 0 }
1441
- *
1442
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1443
- * inside the SQL query. The 0th element of the +params+ array is bound
1444
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1445
- *
1446
- * If the types are not specified, they will be inferred by PostgreSQL.
1447
- * Instead of specifying type oids, it's recommended to simply add
1448
- * explicit casts in the query to ensure that the right type is used.
1449
- *
1450
- * For example: "SELECT $1::int"
1451
- *
1452
- * The optional +result_format+ should be 0 for text results, 1
1453
- * for binary.
1454
- */
1455
- static VALUE
1456
- pgconn_send_query(int argc, VALUE *argv, VALUE self)
1457
- {
1458
- PGconn *conn = get_pgconn(self);
1459
- int result;
1460
- VALUE command, params, in_res_fmt;
1461
- VALUE param, param_type, param_value, param_format;
1462
- VALUE param_value_tmp;
1463
- VALUE sym_type, sym_value, sym_format;
1464
- VALUE gc_array;
1465
- VALUE error;
1466
- int i=0;
1467
- int nParams;
1468
- Oid *paramTypes;
1469
- char ** paramValues;
1470
- int *paramLengths;
1471
- int *paramFormats;
1472
- int resultFormat;
1473
-
1474
- rb_scan_args(argc, argv, "12", &command, &params, &in_res_fmt);
1475
- Check_Type(command, T_STRING);
1476
-
1477
- /* If called with no parameters, use PQsendQuery */
1478
- if(NIL_P(params)) {
1479
- if(PQsendQuery(conn,StringValuePtr(command)) == 0) {
1480
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1481
- rb_iv_set(error, "@connection", self);
1482
- rb_exc_raise(error);
1483
- }
1484
- return Qnil;
1485
- }
1486
-
1487
- /* If called with parameters, and optionally result_format,
1488
- * use PQsendQueryParams
1489
- */
1490
- Check_Type(params, T_ARRAY);
1491
-
1492
- if(NIL_P(in_res_fmt)) {
1493
- resultFormat = 0;
1494
- }
1495
- else {
1496
- resultFormat = NUM2INT(in_res_fmt);
1497
- }
1498
-
1499
- gc_array = rb_ary_new();
1500
- rb_gc_register_address(&gc_array);
1501
- sym_type = ID2SYM(rb_intern("type"));
1502
- sym_value = ID2SYM(rb_intern("value"));
1503
- sym_format = ID2SYM(rb_intern("format"));
1504
- nParams = RARRAY_LEN(params);
1505
- paramTypes = ALLOC_N(Oid, nParams);
1506
- paramValues = ALLOC_N(char *, nParams);
1507
- paramLengths = ALLOC_N(int, nParams);
1508
- paramFormats = ALLOC_N(int, nParams);
1509
- for(i = 0; i < nParams; i++) {
1510
- param = rb_ary_entry(params, i);
1511
- if (TYPE(param) == T_HASH) {
1512
- param_type = rb_hash_aref(param, sym_type);
1513
- param_value_tmp = rb_hash_aref(param, sym_value);
1514
- if(param_value_tmp == Qnil)
1515
- param_value = param_value_tmp;
1516
- else
1517
- param_value = rb_obj_as_string(param_value_tmp);
1518
- param_format = rb_hash_aref(param, sym_format);
1519
- }
1520
- else {
1521
- param_type = INT2NUM(0);
1522
- if(param == Qnil)
1523
- param_value = param;
1524
- else
1525
- param_value = rb_obj_as_string(param);
1526
- param_format = INT2NUM(0);
1527
- }
1528
-
1529
- if(param_type == Qnil)
1530
- paramTypes[i] = 0;
1531
- else
1532
- paramTypes[i] = NUM2INT(param_type);
1533
-
1534
- if(param_value == Qnil) {
1535
- paramValues[i] = NULL;
1536
- paramLengths[i] = 0;
1537
- }
1538
- else {
1539
- Check_Type(param_value, T_STRING);
1540
- /* make sure param_value doesn't get freed by the GC */
1541
- rb_ary_push(gc_array, param_value);
1542
- paramValues[i] = StringValuePtr(param_value);
1543
- paramLengths[i] = RSTRING_LEN(param_value);
1544
- }
1545
-
1546
- if(param_format == Qnil)
1547
- paramFormats[i] = 0;
1548
- else
1549
- paramFormats[i] = NUM2INT(param_format);
1550
- }
1551
-
1552
- result = PQsendQueryParams(conn, StringValuePtr(command), nParams, paramTypes,
1553
- (const char * const *)paramValues, paramLengths, paramFormats, resultFormat);
1554
-
1555
- rb_gc_unregister_address(&gc_array);
1556
-
1557
- xfree(paramTypes);
1558
- xfree(paramValues);
1559
- xfree(paramLengths);
1560
- xfree(paramFormats);
1561
-
1562
- if(result == 0) {
1563
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1564
- rb_iv_set(error, "@connection", self);
1565
- rb_exc_raise(error);
1566
- }
1567
- return Qnil;
1568
- }
1569
-
1570
- /*
1571
- * call-seq:
1572
- * conn.send_prepare( stmt_name, sql [, param_types ] ) -> nil
1573
- *
1574
- * Prepares statement _sql_ with name _name_ to be executed later.
1575
- * Sends prepare command asynchronously, and returns immediately.
1576
- * On failure, it raises a PGError exception.
1577
- *
1578
- * +param_types+ is an optional parameter to specify the Oids of the
1579
- * types of the parameters.
1580
- *
1581
- * If the types are not specified, they will be inferred by PostgreSQL.
1582
- * Instead of specifying type oids, it's recommended to simply add
1583
- * explicit casts in the query to ensure that the right type is used.
1584
- *
1585
- * For example: "SELECT $1::int"
1586
- *
1587
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1588
- * inside the SQL query.
1589
- */
1590
- static VALUE
1591
- pgconn_send_prepare(int argc, VALUE *argv, VALUE self)
1592
- {
1593
- PGconn *conn = get_pgconn(self);
1594
- int result;
1595
- VALUE name, command, in_paramtypes;
1596
- VALUE param;
1597
- VALUE error;
1598
- int i = 0;
1599
- int nParams = 0;
1600
- Oid *paramTypes = NULL;
1601
-
1602
- rb_scan_args(argc, argv, "21", &name, &command, &in_paramtypes);
1603
- Check_Type(name, T_STRING);
1604
- Check_Type(command, T_STRING);
1605
-
1606
- if(! NIL_P(in_paramtypes)) {
1607
- Check_Type(in_paramtypes, T_ARRAY);
1608
- nParams = RARRAY_LEN(in_paramtypes);
1609
- paramTypes = ALLOC_N(Oid, nParams);
1610
- for(i = 0; i < nParams; i++) {
1611
- param = rb_ary_entry(in_paramtypes, i);
1612
- Check_Type(param, T_FIXNUM);
1613
- if(param == Qnil)
1614
- paramTypes[i] = 0;
1615
- else
1616
- paramTypes[i] = NUM2INT(param);
1617
- }
1618
- }
1619
- result = PQsendPrepare(conn, StringValuePtr(name), StringValuePtr(command),
1620
- nParams, paramTypes);
1621
-
1622
- xfree(paramTypes);
1623
-
1624
- if(result == 0) {
1625
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1626
- rb_iv_set(error, "@connection", self);
1627
- rb_exc_raise(error);
1628
- }
1629
- return Qnil;
1630
- }
1631
-
1632
- /*
1633
- * call-seq:
1634
- * conn.send_query_prepared( statement_name [, params, result_format ] )
1635
- * -> nil
1636
- *
1637
- * Execute prepared named statement specified by _statement_name_
1638
- * asynchronously, and returns immediately.
1639
- * On failure, it raises a PGError exception.
1640
- *
1641
- * +params+ is an array of the optional bind parameters for the
1642
- * SQL query. Each element of the +params+ array may be either:
1643
- * a hash of the form:
1644
- * {:value => String (value of bind parameter)
1645
- * :format => Fixnum (0 for text, 1 for binary)
1646
- * }
1647
- * or, it may be a String. If it is a string, that is equivalent to the hash:
1648
- * { :value => <string value>, :format => 0 }
1649
- *
1650
- * PostgreSQL bind parameters are represented as $1, $1, $2, etc.,
1651
- * inside the SQL query. The 0th element of the +params+ array is bound
1652
- * to $1, the 1st element is bound to $2, etc. +nil+ is treated as +NULL+.
1653
- *
1654
- * The optional +result_format+ should be 0 for text results, 1
1655
- * for binary.
1656
- */
1657
- static VALUE
1658
- pgconn_send_query_prepared(int argc, VALUE *argv, VALUE self)
1659
- {
1660
- PGconn *conn = get_pgconn(self);
1661
- int result;
1662
- VALUE name, params, in_res_fmt;
1663
- VALUE param, param_value, param_format;
1664
- VALUE param_value_tmp;
1665
- VALUE sym_value, sym_format;
1666
- VALUE gc_array;
1667
- VALUE error;
1668
- int i = 0;
1669
- int nParams;
1670
- char ** paramValues;
1671
- int *paramLengths;
1672
- int *paramFormats;
1673
- int resultFormat;
1674
-
1675
- rb_scan_args(argc, argv, "12", &name, &params, &in_res_fmt);
1676
- Check_Type(name, T_STRING);
1677
-
1678
- if(NIL_P(params)) {
1679
- params = rb_ary_new2(0);
1680
- resultFormat = 0;
1681
- }
1682
- else {
1683
- Check_Type(params, T_ARRAY);
1684
- }
1685
-
1686
- if(NIL_P(in_res_fmt)) {
1687
- resultFormat = 0;
1688
- }
1689
- else {
1690
- resultFormat = NUM2INT(in_res_fmt);
1691
- }
1692
-
1693
- gc_array = rb_ary_new();
1694
- rb_gc_register_address(&gc_array);
1695
- sym_value = ID2SYM(rb_intern("value"));
1696
- sym_format = ID2SYM(rb_intern("format"));
1697
- nParams = RARRAY_LEN(params);
1698
- paramValues = ALLOC_N(char *, nParams);
1699
- paramLengths = ALLOC_N(int, nParams);
1700
- paramFormats = ALLOC_N(int, nParams);
1701
- for(i = 0; i < nParams; i++) {
1702
- param = rb_ary_entry(params, i);
1703
- if (TYPE(param) == T_HASH) {
1704
- param_value_tmp = rb_hash_aref(param, sym_value);
1705
- if(param_value_tmp == Qnil)
1706
- param_value = param_value_tmp;
1707
- else
1708
- param_value = rb_obj_as_string(param_value_tmp);
1709
- param_format = rb_hash_aref(param, sym_format);
1710
- }
1711
- else {
1712
- if(param == Qnil)
1713
- param_value = param;
1714
- else
1715
- param_value = rb_obj_as_string(param);
1716
- param_format = INT2NUM(0);
1717
- }
1718
-
1719
- if(param_value == Qnil) {
1720
- paramValues[i] = NULL;
1721
- paramLengths[i] = 0;
1722
- }
1723
- else {
1724
- Check_Type(param_value, T_STRING);
1725
- /* make sure param_value doesn't get freed by the GC */
1726
- rb_ary_push(gc_array, param_value);
1727
- paramValues[i] = StringValuePtr(param_value);
1728
- paramLengths[i] = RSTRING_LEN(param_value);
1729
- }
1730
-
1731
- if(param_format == Qnil)
1732
- paramFormats[i] = 0;
1733
- else
1734
- paramFormats[i] = NUM2INT(param_format);
1735
- }
1736
-
1737
- result = PQsendQueryPrepared(conn, StringValuePtr(name), nParams,
1738
- (const char * const *)paramValues, paramLengths, paramFormats,
1739
- resultFormat);
1740
-
1741
- rb_gc_unregister_address(&gc_array);
1742
-
1743
- xfree(paramValues);
1744
- xfree(paramLengths);
1745
- xfree(paramFormats);
1746
-
1747
- if(result == 0) {
1748
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1749
- rb_iv_set(error, "@connection", self);
1750
- rb_exc_raise(error);
1751
- }
1752
- return Qnil;
1753
- }
1754
-
1755
- /*
1756
- * call-seq:
1757
- * conn.send_describe_prepared( statement_name ) -> nil
1758
- *
1759
- * Asynchronously send _command_ to the server. Does not block.
1760
- * Use in combination with +conn.get_result+.
1761
- */
1762
- static VALUE
1763
- pgconn_send_describe_prepared(VALUE self, VALUE stmt_name)
1764
- {
1765
- VALUE error;
1766
- PGconn *conn = get_pgconn(self);
1767
- /* returns 0 on failure */
1768
- if(PQsendDescribePrepared(conn,StringValuePtr(stmt_name)) == 0) {
1769
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1770
- rb_iv_set(error, "@connection", self);
1771
- rb_exc_raise(error);
1772
- }
1773
- return Qnil;
1774
- }
1775
-
1776
-
1777
- /*
1778
- * call-seq:
1779
- * conn.send_describe_portal( portal_name ) -> nil
1780
- *
1781
- * Asynchronously send _command_ to the server. Does not block.
1782
- * Use in combination with +conn.get_result+.
1783
- */
1784
- static VALUE
1785
- pgconn_send_describe_portal(VALUE self, VALUE portal)
1786
- {
1787
- VALUE error;
1788
- PGconn *conn = get_pgconn(self);
1789
- /* returns 0 on failure */
1790
- if(PQsendDescribePortal(conn,StringValuePtr(portal)) == 0) {
1791
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1792
- rb_iv_set(error, "@connection", self);
1793
- rb_exc_raise(error);
1794
- }
1795
- return Qnil;
1796
- }
1797
-
1798
-
1799
- /*
1800
- * call-seq:
1801
- * conn.get_result() -> PGresult
1802
- * conn.get_result() {|pg_result| block }
1803
- *
1804
- * Blocks waiting for the next result from a call to
1805
- * +PGconn#send_query+ (or another asynchronous command), and returns
1806
- * it. Returns +nil+ if no more results are available.
1807
- *
1808
- * Note: call this function repeatedly until it returns +nil+, or else
1809
- * you will not be able to issue further commands.
1810
- *
1811
- * If the optional code block is given, it will be passed <i>result</i> as an argument,
1812
- * and the PGresult object will automatically be cleared when the block terminates.
1813
- * In this instance, <code>conn.exec</code> returns the value of the block.
1814
- */
1815
- static VALUE
1816
- pgconn_get_result(VALUE self)
1817
- {
1818
- PGconn *conn = get_pgconn(self);
1819
- PGresult *result;
1820
- VALUE rb_pgresult;
1821
-
1822
- result = PQgetResult(conn);
1823
- if(result == NULL)
1824
- return Qnil;
1825
- rb_pgresult = new_pgresult(result, conn);
1826
- if (rb_block_given_p()) {
1827
- return rb_ensure(rb_yield, rb_pgresult,
1828
- pgresult_clear, rb_pgresult);
1829
- }
1830
- return rb_pgresult;
1831
- }
1832
-
1833
- /*
1834
- * call-seq:
1835
- * conn.consume_input()
1836
- *
1837
- * If input is available from the server, consume it.
1838
- * After calling +consume_input+, you can check +is_busy+
1839
- * or *notifies* to see if the state has changed.
1840
- */
1841
- static VALUE
1842
- pgconn_consume_input(self)
1843
- VALUE self;
1844
- {
1845
- VALUE error;
1846
- PGconn *conn = get_pgconn(self);
1847
- /* returns 0 on error */
1848
- if(PQconsumeInput(conn) == 0) {
1849
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1850
- rb_iv_set(error, "@connection", self);
1851
- rb_exc_raise(error);
1852
- }
1853
- return Qnil;
1854
- }
1855
-
1856
- /*
1857
- * call-seq:
1858
- * conn.is_busy() -> Boolean
1859
- *
1860
- * Returns +true+ if a command is busy, that is, if
1861
- * PQgetResult would block. Otherwise returns +false+.
1862
- */
1863
- static VALUE
1864
- pgconn_is_busy(self)
1865
- VALUE self;
1866
- {
1867
- return PQisBusy(get_pgconn(self)) ? Qtrue : Qfalse;
1868
- }
1869
-
1870
- /*
1871
- * call-seq:
1872
- * conn.setnonblocking(Boolean) -> nil
1873
- *
1874
- * Sets the nonblocking status of the connection.
1875
- * In the blocking state, calls to PGconn#send_query
1876
- * will block until the message is sent to the server,
1877
- * but will not wait for the query results.
1878
- * In the nonblocking state, calls to PGconn#send_query
1879
- * will return an error if the socket is not ready for
1880
- * writing.
1881
- * Note: This function does not affect PGconn#exec, because
1882
- * that function doesn't return until the server has
1883
- * processed the query and returned the results.
1884
- * Returns +nil+.
1885
- */
1886
- static VALUE
1887
- pgconn_setnonblocking(self, state)
1888
- VALUE self, state;
1889
- {
1890
- int arg;
1891
- VALUE error;
1892
- PGconn *conn = get_pgconn(self);
1893
- if(state == Qtrue)
1894
- arg = 1;
1895
- else if (state == Qfalse)
1896
- arg = 0;
1897
- else
1898
- rb_raise(rb_eArgError, "Boolean value expected");
1899
-
1900
- if(PQsetnonblocking(conn, arg) == -1) {
1901
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1902
- rb_iv_set(error, "@connection", self);
1903
- rb_exc_raise(error);
1904
- }
1905
- return Qnil;
1906
- }
1907
-
1908
-
1909
- /*
1910
- * call-seq:
1911
- * conn.isnonblocking() -> Boolean
1912
- *
1913
- * Returns +true+ if a command is busy, that is, if
1914
- * PQgetResult would block. Otherwise returns +false+.
1915
- */
1916
- static VALUE
1917
- pgconn_isnonblocking(self)
1918
- VALUE self;
1919
- {
1920
- return PQisnonblocking(get_pgconn(self)) ? Qtrue : Qfalse;
1921
- }
1922
-
1923
- /*
1924
- * call-seq:
1925
- * conn.flush() -> Boolean
1926
- *
1927
- * Attempts to flush any queued output data to the server.
1928
- * Returns +true+ if data is successfully flushed, +false+
1929
- * if not (can only return +false+ if connection is
1930
- * nonblocking.
1931
- * Raises PGError exception if some other failure occurred.
1932
- */
1933
- static VALUE
1934
- pgconn_flush(self)
1935
- VALUE self;
1936
- {
1937
- PGconn *conn = get_pgconn(self);
1938
- int ret;
1939
- VALUE error;
1940
- ret = PQflush(conn);
1941
- if(ret == -1) {
1942
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
1943
- rb_iv_set(error, "@connection", self);
1944
- rb_exc_raise(error);
1945
- }
1946
- return (ret) ? Qfalse : Qtrue;
1947
- }
1948
-
1949
- /*
1950
- * call-seq:
1951
- * conn.cancel() -> String
1952
- *
1953
- * Requests cancellation of the command currently being
1954
- * processed. (Only implemented in PostgreSQL >= 8.0)
1955
- *
1956
- * Returns +nil+ on success, or a string containing the
1957
- * error message if a failure occurs.
1958
- */
1959
- static VALUE
1960
- pgconn_cancel(VALUE self)
1961
- {
1962
- #ifdef HAVE_PQGETCANCEL
1963
- char errbuf[256];
1964
- PGcancel *cancel;
1965
- VALUE retval;
1966
- int ret;
1967
-
1968
- cancel = PQgetCancel(get_pgconn(self));
1969
- if(cancel == NULL)
1970
- rb_raise(rb_ePGError,"Invalid connection!");
1971
-
1972
- ret = PQcancel(cancel, errbuf, 256);
1973
- if(ret == 1)
1974
- retval = Qnil;
1975
- else
1976
- retval = rb_str_new2(errbuf);
1977
-
1978
- PQfreeCancel(cancel);
1979
- return retval;
1980
- #else
1981
- rb_notimplement();
1982
- #endif
1983
- }
1984
-
1985
-
1986
- /*
1987
- * call-seq:
1988
- * conn.notifies()
1989
- *
1990
- * Returns a hash of the unprocessed notifications.
1991
- * If there is no unprocessed notifier, it returns +nil+.
1992
- */
1993
- static VALUE
1994
- pgconn_notifies(VALUE self)
1995
- {
1996
- PGconn* conn = get_pgconn(self);
1997
- PGnotify *notification;
1998
- VALUE hash;
1999
- VALUE sym_relname, sym_be_pid, sym_extra;
2000
- VALUE relname, be_pid, extra;
2001
-
2002
- sym_relname = ID2SYM(rb_intern("relname"));
2003
- sym_be_pid = ID2SYM(rb_intern("be_pid"));
2004
- sym_extra = ID2SYM(rb_intern("extra"));
2005
-
2006
- notification = PQnotifies(conn);
2007
- if (notification == NULL) {
2008
- return Qnil;
2009
- }
2010
-
2011
- hash = rb_hash_new();
2012
- relname = rb_tainted_str_new2(notification->relname);
2013
- be_pid = INT2NUM(notification->be_pid);
2014
- extra = rb_tainted_str_new2(PGNOTIFY_EXTRA(notification));
2015
-
2016
- rb_hash_aset(hash, sym_relname, relname);
2017
- rb_hash_aset(hash, sym_be_pid, be_pid);
2018
- rb_hash_aset(hash, sym_extra, extra);
2019
-
2020
- PQfreemem(notification);
2021
- return hash;
2022
- }
2023
-
2024
-
2025
- #ifdef _WIN32
2026
- /*
2027
- * Duplicate the sockets from libpq and create temporary CRT FDs
2028
- */
2029
- void create_crt_fd(fd_set *os_set, fd_set *crt_set)
2030
- {
2031
- int i;
2032
- crt_set->fd_count = os_set->fd_count;
2033
- for (i = 0; i < os_set->fd_count; i++) {
2034
- WSAPROTOCOL_INFO wsa_pi;
2035
- /* dupicate the SOCKET */
2036
- int r = WSADuplicateSocket(os_set->fd_array[i], GetCurrentProcessId(), &wsa_pi);
2037
- SOCKET s = WSASocket(wsa_pi.iAddressFamily, wsa_pi.iSocketType, wsa_pi.iProtocol, &wsa_pi, 0, 0);
2038
- /* create the CRT fd so ruby can get back to the SOCKET */
2039
- int fd = _open_osfhandle(s, O_RDWR|O_BINARY);
2040
- os_set->fd_array[i] = s;
2041
- crt_set->fd_array[i] = fd;
2042
- }
2043
- }
2044
-
2045
- /*
2046
- * Clean up the CRT FDs from create_crt_fd()
2047
- */
2048
- void cleanup_crt_fd(fd_set *os_set, fd_set *crt_set)
2049
- {
2050
- int i;
2051
- for (i = 0; i < os_set->fd_count; i++) {
2052
- /* cleanup the CRT fd */
2053
- _close(crt_set->fd_array[i]);
2054
- /* cleanup the duplicated SOCKET */
2055
- closesocket(os_set->fd_array[i]);
2056
- }
2057
- }
2058
- #endif
2059
-
2060
- /*
2061
- * call-seq:
2062
- * conn.wait_for_notify( [ timeout ] ) -> String
2063
- * conn.wait_for_notify( [ timeout ] ) { |event, pid| block }
2064
- * conn.wait_for_notify( [ timeout ] ) { |event, pid, payload| block } # PostgreSQL 9.0
2065
- *
2066
- * Blocks while waiting for notification(s), or until the optional
2067
- * _timeout_ is reached, whichever comes first. _timeout_ is
2068
- * measured in seconds and can be fractional.
2069
- *
2070
- * Returns +nil+ if _timeout_ is reached, the name of the NOTIFY
2071
- * event otherwise. If used in block form, passes the name of the
2072
- * NOTIFY +event+ and the generating +pid+ into the block.
2073
- *
2074
- * Under PostgreSQL 9.0 and later, if the notification is sent with
2075
- * the optional +payload+ string, it will be given to the block as the
2076
- * third argument.
2077
- *
2078
- */
2079
- static VALUE
2080
- pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2081
- {
2082
- PGconn *conn = get_pgconn( self );
2083
- PGnotify *notification;
2084
- int sd = PQsocket( conn );
2085
- int ret;
2086
- struct timeval timeout;
2087
- struct timeval *ptimeout = NULL;
2088
- VALUE timeout_in = Qnil, relname = Qnil, be_pid = Qnil, extra = Qnil;
2089
- double timeout_sec;
2090
- fd_set sd_rset;
2091
- #ifdef _WIN32
2092
- fd_set crt_sd_rset;
2093
- #endif
2094
-
2095
- if ( sd < 0 )
2096
- rb_bug( "PQsocket(conn): couldn't fetch the connection's socket!" );
2097
-
2098
- rb_scan_args( argc, argv, "01", &timeout_in );
2099
-
2100
- if ( RTEST(timeout_in) ) {
2101
- timeout_sec = NUM2DBL( timeout_in );
2102
- timeout.tv_sec = (long)timeout_sec;
2103
- timeout.tv_usec = (long)( (timeout_sec - (long)timeout_sec) * 1e6 );
2104
- ptimeout = &timeout;
2105
- }
2106
-
2107
- /* Check for notifications */
2108
- while ( (notification = PQnotifies(conn)) == NULL ) {
2109
- FD_ZERO( &sd_rset );
2110
- FD_SET( sd, &sd_rset );
2111
-
2112
- #ifdef _WIN32
2113
- create_crt_fd(&sd_rset, &crt_sd_rset);
2114
- #endif
2115
-
2116
- /* Wait for the socket to become readable before checking again */
2117
- ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout );
2118
-
2119
- #ifdef _WIN32
2120
- cleanup_crt_fd(&sd_rset, &crt_sd_rset);
2121
- #endif
2122
-
2123
- if ( ret < 0 )
2124
- rb_sys_fail( 0 );
2125
-
2126
- /* Return nil if the select timed out */
2127
- if ( ret == 0 ) return Qnil;
2128
-
2129
- /* Read the socket */
2130
- if ( (ret = PQconsumeInput(conn)) != 1 )
2131
- rb_raise( rb_ePGError, "PQconsumeInput == %d: %s", ret, PQerrorMessage(conn) );
2132
- }
2133
-
2134
- relname = rb_tainted_str_new2( notification->relname );
2135
- ASSOCIATE_INDEX( relname, self );
2136
- be_pid = INT2NUM( notification->be_pid );
2137
- #ifdef HAVE_ST_NOTIFY_EXTRA
2138
- if ( *notification->extra ) {
2139
- extra = rb_tainted_str_new2( notification->extra );
2140
- ASSOCIATE_INDEX( extra, self );
2141
- }
2142
- #endif
2143
- PQfreemem( notification );
2144
-
2145
- if ( rb_block_given_p() )
2146
- rb_yield_values( 3, relname, be_pid, extra );
2147
-
2148
- return relname;
2149
- }
2150
-
2151
-
2152
- /*
2153
- * call-seq:
2154
- * conn.put_copy_data( buffer ) -> Boolean
2155
- *
2156
- * Transmits _buffer_ as copy data to the server.
2157
- * Returns true if the data was sent, false if it was
2158
- * not sent (false is only possible if the connection
2159
- * is in nonblocking mode, and this command would block).
2160
- *
2161
- * Raises an exception if an error occurs.
2162
- */
2163
- static VALUE
2164
- pgconn_put_copy_data(self, buffer)
2165
- VALUE self, buffer;
2166
- {
2167
- int ret;
2168
- VALUE error;
2169
- PGconn *conn = get_pgconn(self);
2170
- Check_Type(buffer, T_STRING);
2171
-
2172
- ret = PQputCopyData(conn, RSTRING_PTR(buffer),
2173
- RSTRING_LEN(buffer));
2174
- if(ret == -1) {
2175
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
2176
- rb_iv_set(error, "@connection", self);
2177
- rb_exc_raise(error);
2178
- }
2179
- return (ret) ? Qtrue : Qfalse;
2180
- }
2181
-
2182
- /*
2183
- * call-seq:
2184
- * conn.put_copy_end( [ error_message ] ) -> Boolean
2185
- *
2186
- * Sends end-of-data indication to the server.
2187
- *
2188
- * _error_message_ is an optional parameter, and if set,
2189
- * forces the COPY command to fail with the string
2190
- * _error_message_.
2191
- *
2192
- * Returns true if the end-of-data was sent, false if it was
2193
- * not sent (false is only possible if the connection
2194
- * is in nonblocking mode, and this command would block).
2195
- */
2196
- static VALUE
2197
- pgconn_put_copy_end(int argc, VALUE *argv, VALUE self)
2198
- {
2199
- VALUE str;
2200
- VALUE error;
2201
- int ret;
2202
- char *error_message = NULL;
2203
- PGconn *conn = get_pgconn(self);
2204
-
2205
- if (rb_scan_args(argc, argv, "01", &str) == 0)
2206
- error_message = NULL;
2207
- else
2208
- error_message = StringValuePtr(str);
2209
-
2210
- ret = PQputCopyEnd(conn, error_message);
2211
- if(ret == -1) {
2212
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
2213
- rb_iv_set(error, "@connection", self);
2214
- rb_exc_raise(error);
2215
- }
2216
- return (ret) ? Qtrue : Qfalse;
2217
- }
2218
-
2219
- /*
2220
- * call-seq:
2221
- * conn.get_copy_data( [ async = false ] ) -> String
2222
- *
2223
- * Return a string containing one row of data, +nil+
2224
- * if the copy is done, or +false+ if the call would
2225
- * block (only possible if _async_ is true).
2226
- *
2227
- */
2228
- static VALUE
2229
- pgconn_get_copy_data(int argc, VALUE *argv, VALUE self )
2230
- {
2231
- VALUE async_in;
2232
- VALUE error;
2233
- VALUE result_str;
2234
- int ret;
2235
- int async;
2236
- char *buffer;
2237
- PGconn *conn = get_pgconn(self);
2238
-
2239
- if (rb_scan_args(argc, argv, "01", &async_in) == 0)
2240
- async = 0;
2241
- else
2242
- async = (async_in == Qfalse || async_in == Qnil) ? 0 : 1;
2243
-
2244
- ret = PQgetCopyData(conn, &buffer, async);
2245
- if(ret == -2) { // error
2246
- error = rb_exc_new2(rb_ePGError, PQerrorMessage(conn));
2247
- rb_iv_set(error, "@connection", self);
2248
- rb_exc_raise(error);
2249
- }
2250
- if(ret == -1) { // No data left
2251
- return Qnil;
2252
- }
2253
- if(ret == 0) { // would block
2254
- return Qfalse;
2255
- }
2256
- result_str = rb_tainted_str_new(buffer, ret);
2257
- PQfreemem(buffer);
2258
- return result_str;
2259
- }
2260
-
2261
- /*
2262
- * call-seq:
2263
- * conn.set_error_verbosity( verbosity ) -> Fixnum
2264
- *
2265
- * Sets connection's verbosity to _verbosity_ and returns
2266
- * the previous setting. Available settings are:
2267
- * * PQERRORS_TERSE
2268
- * * PQERRORS_DEFAULT
2269
- * * PQERRORS_VERBOSE
2270
- */
2271
- static VALUE
2272
- pgconn_set_error_verbosity(VALUE self, VALUE in_verbosity)
2273
- {
2274
- PGconn *conn = get_pgconn(self);
2275
- PGVerbosity verbosity = NUM2INT(in_verbosity);
2276
- return INT2FIX(PQsetErrorVerbosity(conn, verbosity));
2277
- }
2278
-
2279
- /*
2280
- * call-seq:
2281
- * conn.trace( stream ) -> nil
2282
- *
2283
- * Enables tracing message passing between backend. The
2284
- * trace message will be written to the stream _stream_,
2285
- * which must implement a method +fileno+ that returns
2286
- * a writable file descriptor.
2287
- */
2288
- static VALUE
2289
- pgconn_trace(VALUE self, VALUE stream)
2290
- {
2291
- VALUE fileno;
2292
- FILE *new_fp;
2293
- int old_fd, new_fd;
2294
- VALUE new_file;
2295
-
2296
- if(rb_respond_to(stream,rb_intern("fileno")) == Qfalse)
2297
- rb_raise(rb_eArgError, "stream does not respond to method: fileno");
2298
-
2299
- fileno = rb_funcall(stream, rb_intern("fileno"), 0);
2300
- if(fileno == Qnil)
2301
- rb_raise(rb_eArgError, "can't get file descriptor from stream");
2302
-
2303
- /* Duplicate the file descriptor and re-open
2304
- * it. Then, make it into a ruby File object
2305
- * and assign it to an instance variable.
2306
- * This prevents a problem when the File
2307
- * object passed to this function is closed
2308
- * before the connection object is. */
2309
- old_fd = NUM2INT(fileno);
2310
- new_fd = dup(old_fd);
2311
- new_fp = fdopen(new_fd, "w");
2312
-
2313
- if(new_fp == NULL)
2314
- rb_raise(rb_eArgError, "stream is not writable");
2315
-
2316
- new_file = rb_funcall(rb_cIO, rb_intern("new"), 1, INT2NUM(new_fd));
2317
- rb_iv_set(self, "@trace_stream", new_file);
2318
-
2319
- PQtrace(get_pgconn(self), new_fp);
2320
- return Qnil;
2321
- }
2322
-
2323
- /*
2324
- * call-seq:
2325
- * conn.untrace() -> nil
2326
- *
2327
- * Disables the message tracing.
2328
- */
2329
- static VALUE
2330
- pgconn_untrace(VALUE self)
2331
- {
2332
- VALUE trace_stream;
2333
- PQuntrace(get_pgconn(self));
2334
- trace_stream = rb_iv_get(self, "@trace_stream");
2335
- rb_funcall(trace_stream, rb_intern("close"), 0);
2336
- rb_iv_set(self, "@trace_stream", Qnil);
2337
- return Qnil;
2338
- }
2339
-
2340
- /*
2341
- * call-seq:
2342
- * conn.set_notice_receiver {|result| ... } -> Proc
2343
- *
2344
- * Notice and warning messages generated by the server are not returned
2345
- * by the query execution functions, since they do not imply failure of
2346
- * the query. Instead they are passed to a notice handling function, and
2347
- * execution continues normally after the handler returns. The default
2348
- * notice handling function prints the message on <tt>stderr</tt>, but the
2349
- * application can override this behavior by supplying its own handling
2350
- * function.
2351
- *
2352
- * This function takes a new block to act as the handler, which should
2353
- * accept a single parameter that will be a PGresult object, and returns
2354
- * the Proc object previously set, or +nil+ if it was previously the default.
2355
- *
2356
- * If you pass no arguments, it will reset the handler to the default.
2357
- */
2358
- static VALUE
2359
- pgconn_set_notice_receiver(VALUE self)
2360
- {
2361
- VALUE proc, old_proc;
2362
- PGconn *conn = get_pgconn(self);
2363
-
2364
- /* If default_notice_receiver is unset, assume that the current
2365
- * notice receiver is the default, and save it to a global variable.
2366
- * This should not be a problem because the default receiver is
2367
- * always the same, so won't vary among connections.
2368
- */
2369
- if(default_notice_receiver == NULL)
2370
- default_notice_receiver = PQsetNoticeReceiver(conn, NULL, NULL);
2371
-
2372
- old_proc = rb_iv_get(self, "@notice_receiver");
2373
- if( rb_block_given_p() ) {
2374
- proc = rb_block_proc();
2375
- PQsetNoticeReceiver(conn, notice_receiver_proxy, (void *)self);
2376
- } else {
2377
- /* if no block is given, set back to default */
2378
- proc = Qnil;
2379
- PQsetNoticeReceiver(conn, default_notice_receiver, NULL);
2380
- }
2381
-
2382
- rb_iv_set(self, "@notice_receiver", proc);
2383
- return old_proc;
2384
- }
2385
-
2386
- /*
2387
- * call-seq:
2388
- * conn.set_notice_processor {|message| ... } -> Proc
2389
- *
2390
- * Notice and warning messages generated by the server are not returned
2391
- * by the query execution functions, since they do not imply failure of
2392
- * the query. Instead they are passed to a notice handling function, and
2393
- * execution continues normally after the handler returns. The default
2394
- * notice handling function prints the message on <tt>stderr</tt>, but the
2395
- * application can override this behavior by supplying its own handling
2396
- * function.
2397
- *
2398
- * This function takes a new block to act as the handler, which should
2399
- * accept a single parameter that will be a PGresult object, and returns
2400
- * the Proc object previously set, or +nil+ if it was previously the default.
2401
- *
2402
- * If you pass no arguments, it will reset the handler to the default.
2403
- */
2404
- static VALUE
2405
- pgconn_set_notice_processor(VALUE self)
2406
- {
2407
- VALUE proc, old_proc;
2408
- PGconn *conn = get_pgconn(self);
2409
-
2410
- /* If default_notice_processor is unset, assume that the current
2411
- * notice processor is the default, and save it to a global variable.
2412
- * This should not be a problem because the default processor is
2413
- * always the same, so won't vary among connections.
2414
- */
2415
- if(default_notice_processor == NULL)
2416
- default_notice_processor = PQsetNoticeProcessor(conn, NULL, NULL);
2417
-
2418
- old_proc = rb_iv_get(self, "@notice_processor");
2419
- if( rb_block_given_p() ) {
2420
- proc = rb_block_proc();
2421
- PQsetNoticeProcessor(conn, notice_processor_proxy, (void *)self);
2422
- } else {
2423
- /* if no block is given, set back to default */
2424
- proc = Qnil;
2425
- PQsetNoticeProcessor(conn, default_notice_processor, NULL);
2426
- }
2427
-
2428
- rb_iv_set(self, "@notice_processor", proc);
2429
- return old_proc;
2430
- }
2431
- /*
2432
- * call-seq:
2433
- * conn.get_client_encoding() -> String
2434
- *
2435
- * Returns the client encoding as a String.
2436
- */
2437
- static VALUE
2438
- pgconn_get_client_encoding(VALUE self)
2439
- {
2440
- char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(get_pgconn(self)));
2441
- return rb_tainted_str_new2(encoding);
2442
- }
2443
-
2444
- /*
2445
- * call-seq:
2446
- * conn.set_client_encoding( encoding )
2447
- *
2448
- * Sets the client encoding to the _encoding_ String.
2449
- */
2450
- static VALUE
2451
- pgconn_set_client_encoding(VALUE self, VALUE str)
2452
- {
2453
- Check_Type(str, T_STRING);
2454
- if ((PQsetClientEncoding(get_pgconn(self), StringValuePtr(str))) == -1){
2455
- rb_raise(rb_ePGError, "invalid encoding name: %s",StringValuePtr(str));
2456
- }
2457
- return Qnil;
2458
- }
2459
-
2460
- /*
2461
- * call-seq:
2462
- * conn.transaction { |conn| ... } -> nil
2463
- *
2464
- * Executes a +BEGIN+ at the start of the block,
2465
- * and a +COMMIT+ at the end of the block, or
2466
- * +ROLLBACK+ if any exception occurs.
2467
- */
2468
- static VALUE
2469
- pgconn_transaction(VALUE self)
2470
- {
2471
- PGconn *conn = get_pgconn(self);
2472
- PGresult *result;
2473
- VALUE rb_pgresult;
2474
- int status;
2475
-
2476
- if (rb_block_given_p()) {
2477
- result = PQexec(conn, "BEGIN");
2478
- rb_pgresult = new_pgresult(result, conn);
2479
- pgresult_check(self, rb_pgresult);
2480
- rb_protect(rb_yield, self, &status);
2481
- if(status == 0) {
2482
- result = PQexec(conn, "COMMIT");
2483
- rb_pgresult = new_pgresult(result, conn);
2484
- pgresult_check(self, rb_pgresult);
2485
- }
2486
- else {
2487
- /* exception occurred, ROLLBACK and re-raise */
2488
- result = PQexec(conn, "ROLLBACK");
2489
- rb_pgresult = new_pgresult(result, conn);
2490
- pgresult_check(self, rb_pgresult);
2491
- rb_jump_tag(status);
2492
- }
2493
-
2494
- }
2495
- else {
2496
- /* no block supplied? */
2497
- rb_raise(rb_eArgError, "Must supply block for PGconn#transaction");
2498
- }
2499
- return Qnil;
2500
- }
2501
-
2502
-
2503
- /*
2504
- * call-seq:
2505
- * PGconn.quote_ident( str ) -> String
2506
- * conn.quote_ident( str ) -> String
2507
- *
2508
- * Returns a string that is safe for inclusion in a SQL query as an
2509
- * identifier. Note: this is not a quote function for values, but for
2510
- * identifiers.
2511
- *
2512
- * For example, in a typical SQL query: <tt>SELECT FOO FROM MYTABLE</tt>
2513
- * The identifier <tt>FOO</tt> is folded to lower case, so it actually
2514
- * means <tt>foo</tt>. If you really want to access the case-sensitive
2515
- * field name <tt>FOO</tt>, use this function like
2516
- * <tt>PGconn.quote_ident('FOO')</tt>, which will return <tt>"FOO"</tt>
2517
- * (with double-quotes). PostgreSQL will see the double-quotes, and
2518
- * it will not fold to lower case.
2519
- *
2520
- * Similarly, this function also protects against special characters,
2521
- * and other things that might allow SQL injection if the identifier
2522
- * comes from an untrusted source.
2523
- */
2524
- static VALUE
2525
- pgconn_s_quote_ident(VALUE self, VALUE in_str)
2526
- {
2527
- VALUE ret;
2528
- char *str = StringValuePtr(in_str);
2529
- /* result size at most NAMEDATALEN*2 plus surrounding
2530
- * double-quotes. */
2531
- char buffer[NAMEDATALEN*2+2];
2532
- unsigned int i=0,j=0;
2533
-
2534
- if(strlen(str) >= NAMEDATALEN) {
2535
- rb_raise(rb_eArgError,
2536
- "Input string is longer than NAMEDATALEN-1 (%d)",
2537
- NAMEDATALEN-1);
2538
- }
2539
- buffer[j++] = '"';
2540
- for(i = 0; i < strlen(str) && str[i]; i++) {
2541
- if(str[i] == '"')
2542
- buffer[j++] = '"';
2543
- buffer[j++] = str[i];
2544
- }
2545
- buffer[j++] = '"';
2546
- ret = rb_str_new(buffer,j);
2547
- OBJ_INFECT(ret, in_str);
2548
- return ret;
2549
- }
2550
-
2551
-
2552
- #ifndef _WIN32
2553
-
2554
- /*
2555
- * call-seq:
2556
- * conn.block( [ timeout ] ) -> Boolean
2557
- *
2558
- * Blocks until the server is no longer busy, or until the
2559
- * optional _timeout_ is reached, whichever comes first.
2560
- * _timeout_ is measured in seconds and can be fractional.
2561
- *
2562
- * Returns +false+ if _timeout_ is reached, +true+ otherwise.
2563
- *
2564
- * If +true+ is returned, +conn.is_busy+ will return +false+
2565
- * and +conn.get_result+ will not block.
2566
- */
2567
- static VALUE
2568
- pgconn_block( int argc, VALUE *argv, VALUE self ) {
2569
- PGconn *conn = get_pgconn( self );
2570
- int sd = PQsocket( conn );
2571
- int ret;
2572
-
2573
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2574
- * and does not wait (nor sleep) any time even if timeout is given.
2575
- * Instead use the Winsock events and rb_w32_wait_events(). */
2576
-
2577
- struct timeval timeout;
2578
- struct timeval *ptimeout = NULL;
2579
- fd_set sd_rset;
2580
- VALUE timeout_in;
2581
- double timeout_sec;
2582
-
2583
- if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2584
- timeout_sec = NUM2DBL( timeout_in );
2585
- timeout.tv_sec = (long)timeout_sec;
2586
- timeout.tv_usec = (long)((timeout_sec - (long)timeout_sec) * 1e6);
2587
- ptimeout = &timeout;
2588
- }
2589
-
2590
- /* Check for connection errors (PQisBusy is true on connection errors) */
2591
- if ( PQconsumeInput(conn) == 0 )
2592
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2593
-
2594
- while ( PQisBusy(conn) ) {
2595
- FD_ZERO( &sd_rset );
2596
- FD_SET( sd, &sd_rset );
2597
-
2598
- if ( (ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout )) < 0 )
2599
- rb_sys_fail( "rb_thread_select()" ); /* Raises */
2600
-
2601
- /* Return false if there was a timeout argument and the select() timed out */
2602
- if ( ret == 0 && argc )
2603
- return Qfalse;
2604
-
2605
- /* Check for connection errors (PQisBusy is true on connection errors) */
2606
- if ( PQconsumeInput(conn) == 0 )
2607
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2608
- }
2609
-
2610
- return Qtrue;
2611
- }
2612
-
2613
-
2614
- #else /* _WIN32 */
2615
-
2616
- /*
2617
- * Win32 PGconn#block -- on Windows, use platform-specific strategies to wait for the socket
2618
- * instead of rb_thread_select().
2619
- */
2620
-
2621
- /* Win32 + Ruby 1.9+ */
2622
- #ifdef HAVE_RUBY_VM_H
2623
-
2624
- int rb_w32_wait_events( HANDLE *events, int num, DWORD timeout );
2625
-
2626
- /* If WIN32 and Ruby 1.9 do not use rb_thread_select() which sometimes hangs
2627
- * and does not wait (nor sleep) any time even if timeout is given.
2628
- * Instead use the Winsock events and rb_w32_wait_events(). */
2629
-
2630
- static VALUE
2631
- pgconn_block( int argc, VALUE *argv, VALUE self ) {
2632
- PGconn *conn = get_pgconn( self );
2633
- int sd = PQsocket( conn );
2634
- int ret;
2635
-
2636
- DWORD timeout_milisec = INFINITY;
2637
- DWORD wait_ret;
2638
- WSAEVENT hEvent;
2639
- VALUE timeout_in;
2640
- double timeout_sec;
2641
-
2642
- hEvent = WSACreateEvent();
2643
-
2644
- if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2645
- timeout_sec = NUM2DBL( timeout_in );
2646
- timeout_milisec = (DWORD)( (timeout_sec - (DWORD)timeout_sec) * 1e3 );
2647
- }
2648
-
2649
- /* Check for connection errors (PQisBusy is true on connection errors) */
2650
- if( PQconsumeInput(conn) == 0 ) {
2651
- WSACloseEvent( hEvent );
2652
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2653
- }
2654
-
2655
- while ( PQisBusy(conn) ) {
2656
- if ( WSAEventSelect(sd, hEvent, FD_READ|FD_CLOSE) == SOCKET_ERROR ) {
2657
- WSACloseEvent( hEvent );
2658
- rb_raise( rb_ePGError, "WSAEventSelect socket error: %d", WSAGetLastError() );
2659
- }
2660
-
2661
- wait_ret = rb_w32_wait_events( &hEvent, 1, 100 );
2662
-
2663
- if ( wait_ret == WAIT_TIMEOUT ) {
2664
- ret = 0;
2665
- } else if ( wait_ret == WAIT_OBJECT_0 ) {
2666
- ret = 1;
2667
- } else if ( wait_ret == WAIT_FAILED ) {
2668
- WSACloseEvent( hEvent );
2669
- rb_raise( rb_ePGError, "Wait on socket error (WaitForMultipleObjects): %d", GetLastError() );
2670
- } else {
2671
- WSACloseEvent( hEvent );
2672
- rb_raise( rb_ePGError, "Wait on socket abandoned (WaitForMultipleObjects)" );
2673
- }
2674
-
2675
- /* Return false if there was a timeout argument and the select() timed out */
2676
- if ( ret == 0 && argc ) {
2677
- WSACloseEvent( hEvent );
2678
- return Qfalse;
2679
- }
2680
-
2681
- /* Check for connection errors (PQisBusy is true on connection errors) */
2682
- if ( PQconsumeInput(conn) == 0 ) {
2683
- WSACloseEvent( hEvent );
2684
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2685
- }
2686
- }
2687
-
2688
- WSACloseEvent( hEvent );
2689
-
2690
- return Qtrue;
2691
- }
2692
-
2693
- #else /* Win32 + Ruby < 1.9 */
2694
-
2695
- static VALUE
2696
- pgconn_block( int argc, VALUE *argv, VALUE self ) {
2697
- PGconn *conn = get_pgconn( self );
2698
- int sd = PQsocket( conn );
2699
- int ret;
2700
-
2701
- struct timeval timeout;
2702
- struct timeval *ptimeout = NULL;
2703
- fd_set sd_rset;
2704
- fd_set crt_sd_rset;
2705
- VALUE timeout_in;
2706
- double timeout_sec;
2707
-
2708
- /* Always set a timeout, as rb_thread_select() sometimes
2709
- * doesn't return when a second ruby thread is running although data
2710
- * could be read. So we use timeout-based polling instead.
2711
- */
2712
- timeout.tv_sec = 0;
2713
- timeout.tv_usec = 10000; // 10ms
2714
- ptimeout = &timeout;
2715
-
2716
- if ( rb_scan_args(argc, argv, "01", &timeout_in) == 1 ) {
2717
- timeout_sec = NUM2DBL( timeout_in );
2718
- timeout.tv_sec = (long)timeout_sec;
2719
- timeout.tv_usec = (long)((timeout_sec - (long)timeout_sec) * 1e6);
2720
- ptimeout = &timeout;
2721
- }
2722
-
2723
- /* Check for connection errors (PQisBusy is true on connection errors) */
2724
- if( PQconsumeInput(conn) == 0 )
2725
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2726
-
2727
- while ( PQisBusy(conn) ) {
2728
- FD_ZERO( &sd_rset );
2729
- FD_SET( sd, &sd_rset );
2730
-
2731
- create_crt_fd( &sd_rset, &crt_sd_rset );
2732
- ret = rb_thread_select( sd+1, &sd_rset, NULL, NULL, ptimeout );
2733
- cleanup_crt_fd( &sd_rset, &crt_sd_rset );
2734
-
2735
- /* Return false if there was a timeout argument and the select() timed out */
2736
- if ( ret == 0 && argc )
2737
- return Qfalse;
2738
-
2739
- /* Check for connection errors (PQisBusy is true on connection errors) */
2740
- if ( PQconsumeInput(conn) == 0 )
2741
- rb_raise( rb_ePGError, PQerrorMessage(conn) );
2742
- }
2743
-
2744
- return Qtrue;
2745
- }
2746
-
2747
- #endif /* Ruby 1.9 */
2748
- #endif /* Win32 */
2749
-
2750
-
2751
- /*
2752
- * call-seq:
2753
- * conn.get_last_result( ) -> PGresult
2754
- *
2755
- * This function retrieves all available results
2756
- * on the current connection (from previously issued
2757
- * asynchronous commands like +send_query()+) and
2758
- * returns the last non-NULL result, or +nil+ if no
2759
- * results are available.
2760
- *
2761
- * This function is similar to +PGconn#get_result+
2762
- * except that it is designed to get one and only
2763
- * one result.
2764
- */
2765
- static VALUE
2766
- pgconn_get_last_result(VALUE self)
2767
- {
2768
- PGconn *conn = get_pgconn(self);
2769
- VALUE rb_pgresult = Qnil;
2770
- PGresult *cur, *prev;
2771
-
2772
-
2773
- cur = prev = NULL;
2774
- while ((cur = PQgetResult(conn)) != NULL) {
2775
- int status;
2776
-
2777
- if (prev) PQclear(prev);
2778
- prev = cur;
2779
-
2780
- status = PQresultStatus(cur);
2781
- if (status == PGRES_COPY_OUT || status == PGRES_COPY_IN)
2782
- break;
2783
- }
2784
-
2785
- if (prev) {
2786
- rb_pgresult = new_pgresult(prev, conn);
2787
- pgresult_check(self, rb_pgresult);
2788
- }
2789
-
2790
- return rb_pgresult;
2791
- }
2792
-
2793
-
2794
- /*
2795
- * call-seq:
2796
- * conn.async_exec(sql [, params, result_format ] ) -> PGresult
2797
- * conn.async_exec(sql [, params, result_format ] ) {|pg_result| block }
2798
- *
2799
- * This function has the same behavior as +PGconn#exec+,
2800
- * except that it's implemented using asynchronous command
2801
- * processing and ruby's +rb_thread_select+ in order to
2802
- * allow other threads to process while waiting for the
2803
- * server to complete the request.
2804
- */
2805
- static VALUE
2806
- pgconn_async_exec(int argc, VALUE *argv, VALUE self)
2807
- {
2808
- VALUE rb_pgresult = Qnil;
2809
-
2810
- /* remove any remaining results from the queue */
2811
- pgconn_block( 0, NULL, self ); /* wait for input (without blocking) before reading the last result */
2812
- pgconn_get_last_result( self );
2813
-
2814
- pgconn_send_query( argc, argv, self );
2815
- pgconn_block( 0, NULL, self );
2816
- rb_pgresult = pgconn_get_last_result( self );
2817
-
2818
- if ( rb_block_given_p() ) {
2819
- return rb_ensure( rb_yield, rb_pgresult, pgresult_clear, rb_pgresult );
2820
- }
2821
- return rb_pgresult;
2822
- }
2823
-
2824
-
2825
- /**************************************************************************
2826
- * LARGE OBJECT SUPPORT
2827
- **************************************************************************/
2828
-
2829
- /*
2830
- * call-seq:
2831
- * conn.lo_creat( [mode] ) -> Fixnum
2832
- *
2833
- * Creates a large object with mode _mode_. Returns a large object Oid.
2834
- * On failure, it raises PGError exception.
2835
- */
2836
- static VALUE
2837
- pgconn_locreat(int argc, VALUE *argv, VALUE self)
2838
- {
2839
- Oid lo_oid;
2840
- int mode;
2841
- VALUE nmode;
2842
- PGconn *conn = get_pgconn(self);
2843
-
2844
- if (rb_scan_args(argc, argv, "01", &nmode) == 0)
2845
- mode = INV_READ;
2846
- else
2847
- mode = NUM2INT(nmode);
2848
-
2849
- lo_oid = lo_creat(conn, mode);
2850
- if (lo_oid == 0)
2851
- rb_raise(rb_ePGError, "lo_creat failed");
2852
-
2853
- return INT2FIX(lo_oid);
2854
- }
2855
-
2856
- /*
2857
- * call-seq:
2858
- * conn.lo_create( oid ) -> Fixnum
2859
- *
2860
- * Creates a large object with oid _oid_. Returns the large object Oid.
2861
- * On failure, it raises PGError exception.
2862
- */
2863
- static VALUE
2864
- pgconn_locreate(VALUE self, VALUE in_lo_oid)
2865
- {
2866
- Oid ret, lo_oid;
2867
- PGconn *conn = get_pgconn(self);
2868
- lo_oid = NUM2INT(in_lo_oid);
2869
-
2870
- ret = lo_create(conn, in_lo_oid);
2871
- if (ret == InvalidOid)
2872
- rb_raise(rb_ePGError, "lo_create failed");
2873
-
2874
- return INT2FIX(ret);
2875
- }
2876
-
2877
- /*
2878
- * call-seq:
2879
- * conn.lo_import(file) -> Fixnum
2880
- *
2881
- * Import a file to a large object. Returns a large object Oid.
2882
- *
2883
- * On failure, it raises a PGError exception.
2884
- */
2885
- static VALUE
2886
- pgconn_loimport(VALUE self, VALUE filename)
2887
- {
2888
- Oid lo_oid;
2889
-
2890
- PGconn *conn = get_pgconn(self);
2891
-
2892
- Check_Type(filename, T_STRING);
2893
-
2894
- lo_oid = lo_import(conn, StringValuePtr(filename));
2895
- if (lo_oid == 0) {
2896
- rb_raise(rb_ePGError, "%s", PQerrorMessage(conn));
2897
- }
2898
- return INT2FIX(lo_oid);
2899
- }
2900
-
2901
- /*
2902
- * call-seq:
2903
- * conn.lo_export( oid, file ) -> nil
2904
- *
2905
- * Saves a large object of _oid_ to a _file_.
2906
- */
2907
- static VALUE
2908
- pgconn_loexport(VALUE self, VALUE lo_oid, VALUE filename)
2909
- {
2910
- PGconn *conn = get_pgconn(self);
2911
- int oid;
2912
- Check_Type(filename, T_STRING);
2913
-
2914
- oid = NUM2INT(lo_oid);
2915
- if (oid < 0) {
2916
- rb_raise(rb_ePGError, "invalid large object oid %d",oid);
2917
- }
2918
-
2919
- if (lo_export(conn, oid, StringValuePtr(filename)) < 0) {
2920
- rb_raise(rb_ePGError, "%s", PQerrorMessage(conn));
2921
- }
2922
- return Qnil;
2923
- }
2924
-
2925
- /*
2926
- * call-seq:
2927
- * conn.lo_open( oid, [mode] ) -> Fixnum
2928
- *
2929
- * Open a large object of _oid_. Returns a large object descriptor
2930
- * instance on success. The _mode_ argument specifies the mode for
2931
- * the opened large object,which is either +INV_READ+, or +INV_WRITE+.
2932
- *
2933
- * If _mode_ is omitted, the default is +INV_READ+.
2934
- */
2935
- static VALUE
2936
- pgconn_loopen(int argc, VALUE *argv, VALUE self)
2937
- {
2938
- Oid lo_oid;
2939
- int fd, mode;
2940
- VALUE nmode, selfid;
2941
- PGconn *conn = get_pgconn(self);
2942
-
2943
- rb_scan_args(argc, argv, "11", &selfid, &nmode);
2944
- lo_oid = NUM2INT(selfid);
2945
- if(NIL_P(nmode))
2946
- mode = INV_READ;
2947
- else
2948
- mode = NUM2INT(nmode);
2949
-
2950
- if((fd = lo_open(conn, lo_oid, mode)) < 0) {
2951
- rb_raise(rb_ePGError, "can't open large object: %s", PQerrorMessage(conn));
2952
- }
2953
- return INT2FIX(fd);
2954
- }
2955
-
2956
- /*
2957
- * call-seq:
2958
- * conn.lo_write( lo_desc, buffer ) -> Fixnum
2959
- *
2960
- * Writes the string _buffer_ to the large object _lo_desc_.
2961
- * Returns the number of bytes written.
2962
- */
2963
- static VALUE
2964
- pgconn_lowrite(VALUE self, VALUE in_lo_desc, VALUE buffer)
2965
- {
2966
- int n;
2967
- PGconn *conn = get_pgconn(self);
2968
- int fd = NUM2INT(in_lo_desc);
2969
-
2970
- Check_Type(buffer, T_STRING);
2971
-
2972
- if( RSTRING_LEN(buffer) < 0) {
2973
- rb_raise(rb_ePGError, "write buffer zero string");
2974
- }
2975
- if((n = lo_write(conn, fd, StringValuePtr(buffer),
2976
- RSTRING_LEN(buffer))) < 0) {
2977
- rb_raise(rb_ePGError, "lo_write failed: %s", PQerrorMessage(conn));
2978
- }
2979
-
2980
- return INT2FIX(n);
2981
- }
2982
-
2983
- /*
2984
- * call-seq:
2985
- * conn.lo_read( lo_desc, len ) -> String
2986
- *
2987
- * Attempts to read _len_ bytes from large object _lo_desc_,
2988
- * returns resulting data.
2989
- */
2990
- static VALUE
2991
- pgconn_loread(VALUE self, VALUE in_lo_desc, VALUE in_len)
2992
- {
2993
- int ret;
2994
- PGconn *conn = get_pgconn(self);
2995
- int len = NUM2INT(in_len);
2996
- int lo_desc = NUM2INT(in_lo_desc);
2997
- VALUE str;
2998
- char *buffer;
2999
-
3000
- buffer = ALLOC_N(char, len);
3001
- if(buffer == NULL)
3002
- rb_raise(rb_eNoMemError, "ALLOC failed!");
3003
-
3004
- if (len < 0){
3005
- rb_raise(rb_ePGError,"nagative length %d given", len);
3006
- }
3007
-
3008
- if((ret = lo_read(conn, lo_desc, buffer, len)) < 0)
3009
- rb_raise(rb_ePGError, "lo_read failed");
3010
-
3011
- if(ret == 0) {
3012
- xfree(buffer);
3013
- return Qnil;
3014
- }
3015
-
3016
- str = rb_tainted_str_new(buffer, ret);
3017
- xfree(buffer);
3018
-
3019
- return str;
3020
- }
3021
-
3022
-
3023
- /*
3024
- * call-seq:
3025
- * conn.lo_lseek( lo_desc, offset, whence ) -> Fixnum
3026
- *
3027
- * Move the large object pointer _lo_desc_ to offset _offset_.
3028
- * Valid values for _whence_ are +SEEK_SET+, +SEEK_CUR+, and +SEEK_END+.
3029
- * (Or 0, 1, or 2.)
3030
- */
3031
- static VALUE
3032
- pgconn_lolseek(VALUE self, VALUE in_lo_desc, VALUE offset, VALUE whence)
3033
- {
3034
- PGconn *conn = get_pgconn(self);
3035
- int lo_desc = NUM2INT(in_lo_desc);
3036
- int ret;
3037
-
3038
- if((ret = lo_lseek(conn, lo_desc, NUM2INT(offset), NUM2INT(whence))) < 0) {
3039
- rb_raise(rb_ePGError, "lo_lseek failed");
3040
- }
3041
-
3042
- return INT2FIX(ret);
3043
- }
3044
-
3045
- /*
3046
- * call-seq:
3047
- * conn.lo_tell( lo_desc ) -> Fixnum
3048
- *
3049
- * Returns the current position of the large object _lo_desc_.
3050
- */
3051
- static VALUE
3052
- pgconn_lotell(VALUE self, VALUE in_lo_desc)
3053
- {
3054
- int position;
3055
- PGconn *conn = get_pgconn(self);
3056
- int lo_desc = NUM2INT(in_lo_desc);
3057
-
3058
- if((position = lo_tell(conn, lo_desc)) < 0)
3059
- rb_raise(rb_ePGError,"lo_tell failed");
3060
-
3061
- return INT2FIX(position);
3062
- }
3063
-
3064
- /*
3065
- * call-seq:
3066
- * conn.lo_truncate( lo_desc, len ) -> nil
3067
- *
3068
- * Truncates the large object _lo_desc_ to size _len_.
3069
- */
3070
- static VALUE
3071
- pgconn_lotruncate(VALUE self, VALUE in_lo_desc, VALUE in_len)
3072
- {
3073
- PGconn *conn = get_pgconn(self);
3074
- int lo_desc = NUM2INT(in_lo_desc);
3075
- size_t len = NUM2INT(in_len);
3076
-
3077
- if(lo_truncate(conn,lo_desc,len) < 0)
3078
- rb_raise(rb_ePGError,"lo_truncate failed");
3079
-
3080
- return Qnil;
3081
- }
3082
-
3083
- /*
3084
- * call-seq:
3085
- * conn.lo_close( lo_desc ) -> nil
3086
- *
3087
- * Closes the postgres large object of _lo_desc_.
3088
- */
3089
- static VALUE
3090
- pgconn_loclose(VALUE self, VALUE in_lo_desc)
3091
- {
3092
- PGconn *conn = get_pgconn(self);
3093
- int lo_desc = NUM2INT(in_lo_desc);
3094
-
3095
- if(lo_close(conn,lo_desc) < 0)
3096
- rb_raise(rb_ePGError,"lo_close failed");
3097
-
3098
- return Qnil;
3099
- }
3100
-
3101
- /*
3102
- * call-seq:
3103
- * conn.lo_unlink( oid ) -> nil
3104
- *
3105
- * Unlinks (deletes) the postgres large object of _oid_.
3106
- */
3107
- static VALUE
3108
- pgconn_lounlink(VALUE self, VALUE in_oid)
3109
- {
3110
- PGconn *conn = get_pgconn(self);
3111
- int oid = NUM2INT(in_oid);
3112
-
3113
- if (oid < 0)
3114
- rb_raise(rb_ePGError, "invalid oid %d",oid);
3115
-
3116
- if(lo_unlink(conn,oid) < 0)
3117
- rb_raise(rb_ePGError,"lo_unlink failed");
3118
-
3119
- return Qnil;
3120
- }
3121
-
3122
- /********************************************************************
3123
- *
3124
- * Document-class: PGresult
3125
- *
3126
- * The class to represent the query result tuples (rows).
3127
- * An instance of this class is created as the result of every query.
3128
- * You may need to invoke the #clear method of the instance when finished with
3129
- * the result for better memory performance.
3130
- *
3131
- * Example:
3132
- * require 'pg'
3133
- * conn = PGconn.open(:dbname => 'test')
3134
- * res = conn.exec('SELECT 1 AS a, 2 AS b, NULL AS c')
3135
- * res.getvalue(0,0) # '1'
3136
- * res[0]['b'] # '2'
3137
- * res[0]['c'] # nil
3138
- *
3139
- */
3140
-
3141
- /**************************************************************************
3142
- * PGresult INSTANCE METHODS
3143
- **************************************************************************/
3144
-
3145
- /*
3146
- * call-seq:
3147
- * res.result_status() -> Fixnum
3148
- *
3149
- * Returns the status of the query. The status value is one of:
3150
- * * +PGRES_EMPTY_QUERY+
3151
- * * +PGRES_COMMAND_OK+
3152
- * * +PGRES_TUPLES_OK+
3153
- * * +PGRES_COPY_OUT+
3154
- * * +PGRES_COPY_IN+
3155
- * * +PGRES_BAD_RESPONSE+
3156
- * * +PGRES_NONFATAL_ERROR+
3157
- * * +PGRES_FATAL_ERROR+
3158
- */
3159
- static VALUE
3160
- pgresult_result_status(VALUE self)
3161
- {
3162
- return INT2FIX(PQresultStatus(get_pgresult(self)));
3163
- }
3164
-
3165
- /*
3166
- * call-seq:
3167
- * res.res_status( status ) -> String
3168
- *
3169
- * Returns the string representation of status +status+.
3170
- *
3171
- */
3172
- static VALUE
3173
- pgresult_res_status(VALUE self, VALUE status)
3174
- {
3175
- VALUE ret = rb_tainted_str_new2(PQresStatus(NUM2INT(status)));
3176
- ASSOCIATE_INDEX(ret, self);
3177
- return ret;
3178
- }
3179
-
3180
- /*
3181
- * call-seq:
3182
- * res.error_message() -> String
3183
- *
3184
- * Returns the error message of the command as a string.
3185
- */
3186
- static VALUE
3187
- pgresult_error_message(VALUE self)
3188
- {
3189
- VALUE ret = rb_tainted_str_new2(PQresultErrorMessage(get_pgresult(self)));
3190
- ASSOCIATE_INDEX(ret, self);
3191
- return ret;
3192
- }
3193
-
3194
- /*
3195
- * call-seq:
3196
- * res.error_field(fieldcode) -> String
3197
- *
3198
- * Returns the individual field of an error.
3199
- *
3200
- * +fieldcode+ is one of:
3201
- * * +PG_DIAG_SEVERITY+
3202
- * * +PG_DIAG_SQLSTATE+
3203
- * * +PG_DIAG_MESSAGE_PRIMARY+
3204
- * * +PG_DIAG_MESSAGE_DETAIL+
3205
- * * +PG_DIAG_MESSAGE_HINT+
3206
- * * +PG_DIAG_STATEMENT_POSITION+
3207
- * * +PG_DIAG_INTERNAL_POSITION+
3208
- * * +PG_DIAG_INTERNAL_QUERY+
3209
- * * +PG_DIAG_CONTEXT+
3210
- * * +PG_DIAG_SOURCE_FILE+
3211
- * * +PG_DIAG_SOURCE_LINE+
3212
- * * +PG_DIAG_SOURCE_FUNCTION+
3213
- *
3214
- * An example:
3215
- *
3216
- * begin
3217
- * conn.exec( "SELECT * FROM nonexistant_table" )
3218
- * rescue PGError => err
3219
- * p [
3220
- * result.error_field( PGresult::PG_DIAG_SEVERITY ),
3221
- * result.error_field( PGresult::PG_DIAG_SQLSTATE ),
3222
- * result.error_field( PGresult::PG_DIAG_MESSAGE_PRIMARY ),
3223
- * result.error_field( PGresult::PG_DIAG_MESSAGE_DETAIL ),
3224
- * result.error_field( PGresult::PG_DIAG_MESSAGE_HINT ),
3225
- * result.error_field( PGresult::PG_DIAG_STATEMENT_POSITION ),
3226
- * result.error_field( PGresult::PG_DIAG_INTERNAL_POSITION ),
3227
- * result.error_field( PGresult::PG_DIAG_INTERNAL_QUERY ),
3228
- * result.error_field( PGresult::PG_DIAG_CONTEXT ),
3229
- * result.error_field( PGresult::PG_DIAG_SOURCE_FILE ),
3230
- * result.error_field( PGresult::PG_DIAG_SOURCE_LINE ),
3231
- * result.error_field( PGresult::PG_DIAG_SOURCE_FUNCTION ),
3232
- * ]
3233
- * end
3234
- *
3235
- * Outputs:
3236
- *
3237
- * ["ERROR", "42P01", "relation \"nonexistant_table\" does not exist", nil, nil,
3238
- * "15", nil, nil, nil, "path/to/parse_relation.c", "857", "parserOpenTable"]
3239
- */
3240
- static VALUE
3241
- pgresult_error_field(VALUE self, VALUE field)
3242
- {
3243
- PGresult *result = get_pgresult( self );
3244
- int fieldcode = NUM2INT( field );
3245
- char * fieldstr = PQresultErrorField( result, fieldcode );
3246
- VALUE ret = Qnil;
3247
-
3248
- if ( fieldstr ) {
3249
- ret = rb_tainted_str_new2( fieldstr );
3250
- ASSOCIATE_INDEX( ret, self );
3251
- }
3252
-
3253
- return ret;
3254
- }
3255
-
3256
- /*
3257
- * call-seq:
3258
- * res.clear() -> nil
3259
- *
3260
- * Clears the PGresult object as the result of the query.
3261
- */
3262
- static VALUE
3263
- pgresult_clear(VALUE self)
3264
- {
3265
- PQclear(get_pgresult(self));
3266
- DATA_PTR(self) = NULL;
3267
- return Qnil;
3268
- }
3269
-
3270
- /*
3271
- * call-seq:
3272
- * res.ntuples() -> Fixnum
3273
- *
3274
- * Returns the number of tuples in the query result.
3275
- */
3276
- static VALUE
3277
- pgresult_ntuples(VALUE self)
3278
- {
3279
- return INT2FIX(PQntuples(get_pgresult(self)));
3280
- }
3281
-
3282
- /*
3283
- * call-seq:
3284
- * res.nfields() -> Fixnum
3285
- *
3286
- * Returns the number of columns in the query result.
3287
- */
3288
- static VALUE
3289
- pgresult_nfields(VALUE self)
3290
- {
3291
- return INT2NUM(PQnfields(get_pgresult(self)));
3292
- }
3293
-
3294
- /*
3295
- * call-seq:
3296
- * res.fname( index ) -> String
3297
- *
3298
- * Returns the name of the column corresponding to _index_.
3299
- */
3300
- static VALUE
3301
- pgresult_fname(VALUE self, VALUE index)
3302
- {
3303
- VALUE fname;
3304
- PGresult *result;
3305
- int i = NUM2INT(index);
3306
-
3307
- result = get_pgresult(self);
3308
- if (i < 0 || i >= PQnfields(result)) {
3309
- rb_raise(rb_eArgError,"invalid field number %d", i);
3310
- }
3311
- fname = rb_tainted_str_new2(PQfname(result, i));
3312
- ASSOCIATE_INDEX(fname, self);
3313
- return fname;
3314
- }
3315
-
3316
- /*
3317
- * call-seq:
3318
- * res.fnumber( name ) -> Fixnum
3319
- *
3320
- * Returns the index of the field specified by the string _name_.
3321
- *
3322
- * Raises an ArgumentError if the specified _name_ isn't one of the field names;
3323
- * raises a TypeError if _name_ is not a String.
3324
- */
3325
- static VALUE
3326
- pgresult_fnumber(VALUE self, VALUE name)
3327
- {
3328
- int n;
3329
-
3330
- Check_Type(name, T_STRING);
3331
-
3332
- n = PQfnumber(get_pgresult(self), StringValuePtr(name));
3333
- if (n == -1) {
3334
- rb_raise(rb_eArgError,"Unknown field: %s", StringValuePtr(name));
3335
- }
3336
- return INT2FIX(n);
3337
- }
3338
-
3339
- /*
3340
- * call-seq:
3341
- * res.ftable( column_number ) -> Fixnum
3342
- *
3343
- * Returns the Oid of the table from which the column _column_number_
3344
- * was fetched.
3345
- *
3346
- * Raises ArgumentError if _column_number_ is out of range or if
3347
- * the Oid is undefined for that column.
3348
- */
3349
- static VALUE
3350
- pgresult_ftable(VALUE self, VALUE column_number)
3351
- {
3352
- Oid n ;
3353
- int col_number = NUM2INT(column_number);
3354
- PGresult *pgresult = get_pgresult(self);
3355
-
3356
- if( col_number < 0 || col_number >= PQnfields(pgresult))
3357
- rb_raise(rb_eArgError,"Invalid column index: %d", col_number);
3358
-
3359
- n = PQftable(pgresult, col_number);
3360
- return INT2FIX(n);
3361
- }
3362
-
3363
- /*
3364
- * call-seq:
3365
- * res.ftablecol( column_number ) -> Fixnum
3366
- *
3367
- * Returns the column number (within its table) of the table from
3368
- * which the column _column_number_ is made up.
3369
- *
3370
- * Raises ArgumentError if _column_number_ is out of range or if
3371
- * the column number from its table is undefined for that column.
3372
- */
3373
- static VALUE
3374
- pgresult_ftablecol(VALUE self, VALUE column_number)
3375
- {
3376
- int col_number = NUM2INT(column_number);
3377
- PGresult *pgresult = get_pgresult(self);
3378
-
3379
- int n;
3380
-
3381
- if( col_number < 0 || col_number >= PQnfields(pgresult))
3382
- rb_raise(rb_eArgError,"Invalid column index: %d", col_number);
3383
-
3384
- n = PQftablecol(pgresult, col_number);
3385
- return INT2FIX(n);
3386
- }
3387
-
3388
- /*
3389
- * call-seq:
3390
- * res.fformat( column_number ) -> Fixnum
3391
- *
3392
- * Returns the format (0 for text, 1 for binary) of column
3393
- * _column_number_.
3394
- *
3395
- * Raises ArgumentError if _column_number_ is out of range.
3396
- */
3397
- static VALUE
3398
- pgresult_fformat(VALUE self, VALUE column_number)
3399
- {
3400
- PGresult *result = get_pgresult(self);
3401
- int fnumber = NUM2INT(column_number);
3402
- if (fnumber < 0 || fnumber >= PQnfields(result)) {
3403
- rb_raise(rb_eArgError, "Column number is out of range: %d",
3404
- fnumber);
3405
- }
3406
- return INT2FIX(PQfformat(result, fnumber));
3407
- }
3408
-
3409
- /*
3410
- * call-seq:
3411
- * res.ftype( column_number )
3412
- *
3413
- * Returns the data type associated with _column_number_.
3414
- *
3415
- * The integer returned is the internal +OID+ number (in PostgreSQL)
3416
- * of the type. To get a human-readable value for the type, use the
3417
- * returned OID and the field's #fmod value with the format_type() SQL
3418
- * function:
3419
- *
3420
- * # Get the type of the second column of the result 'res'
3421
- * typename = conn.
3422
- * exec( "SELECT format_type($1,$2)", [res.ftype(1), res.fmod(1)] ).
3423
- * getvalue( 0, 0 )
3424
- *
3425
- * Raises an ArgumentError if _column_number_ is out of range.
3426
- */
3427
- static VALUE
3428
- pgresult_ftype(VALUE self, VALUE index)
3429
- {
3430
- PGresult* result = get_pgresult(self);
3431
- int i = NUM2INT(index);
3432
- if (i < 0 || i >= PQnfields(result)) {
3433
- rb_raise(rb_eArgError, "invalid field number %d", i);
3434
- }
3435
- return INT2NUM(PQftype(result, i));
3436
- }
3437
-
3438
- /*
3439
- * call-seq:
3440
- * res.fmod( column_number )
3441
- *
3442
- * Returns the type modifier associated with column _column_number_. See
3443
- * the #ftype method for an example of how to use this.
3444
- *
3445
- * Raises an ArgumentError if _column_number_ is out of range.
3446
- */
3447
- static VALUE
3448
- pgresult_fmod(VALUE self, VALUE column_number)
3449
- {
3450
- PGresult *result = get_pgresult(self);
3451
- int fnumber = NUM2INT(column_number);
3452
- int modifier;
3453
- if (fnumber < 0 || fnumber >= PQnfields(result)) {
3454
- rb_raise(rb_eArgError, "Column number is out of range: %d",
3455
- fnumber);
3456
- }
3457
- modifier = PQfmod(result,fnumber);
3458
-
3459
- return INT2NUM(modifier);
3460
- }
3461
-
3462
- /*
3463
- * call-seq:
3464
- * res.fsize( index )
3465
- *
3466
- * Returns the size of the field type in bytes. Returns <tt>-1</tt> if the field is variable sized.
3467
- *
3468
- * res = conn.exec("SELECT myInt, myVarChar50 FROM foo")
3469
- * res.size(0) => 4
3470
- * res.size(1) => -1
3471
- */
3472
- static VALUE
3473
- pgresult_fsize(VALUE self, VALUE index)
3474
- {
3475
- PGresult *result;
3476
- int i = NUM2INT(index);
3477
-
3478
- result = get_pgresult(self);
3479
- if (i < 0 || i >= PQnfields(result)) {
3480
- rb_raise(rb_eArgError,"invalid field number %d", i);
3481
- }
3482
- return INT2NUM(PQfsize(result, i));
3483
- }
3484
-
3485
- /*
3486
- * call-seq:
3487
- * res.getvalue( tup_num, field_num )
3488
- *
3489
- * Returns the value in tuple number _tup_num_, field _field_num_,
3490
- * or +nil+ if the field is +NULL+.
3491
- */
3492
- static VALUE
3493
- pgresult_getvalue(VALUE self, VALUE tup_num, VALUE field_num)
3494
- {
3495
- VALUE ret;
3496
- PGresult *result;
3497
- int i = NUM2INT(tup_num);
3498
- int j = NUM2INT(field_num);
3499
-
3500
- result = get_pgresult(self);
3501
- if(i < 0 || i >= PQntuples(result)) {
3502
- rb_raise(rb_eArgError,"invalid tuple number %d", i);
3503
- }
3504
- if(j < 0 || j >= PQnfields(result)) {
3505
- rb_raise(rb_eArgError,"invalid field number %d", j);
3506
- }
3507
- if(PQgetisnull(result, i, j))
3508
- return Qnil;
3509
- ret = rb_tainted_str_new(PQgetvalue(result, i, j),
3510
- PQgetlength(result, i, j));
3511
- ASSOCIATE_INDEX(ret, self);
3512
- return ret;
3513
- }
3514
-
3515
- /*
3516
- * call-seq:
3517
- * res.getisnull(tuple_position, field_position) -> boolean
3518
- *
3519
- * Returns +true+ if the specified value is +nil+; +false+ otherwise.
3520
- */
3521
- static VALUE
3522
- pgresult_getisnull(VALUE self, VALUE tup_num, VALUE field_num)
3523
- {
3524
- PGresult *result;
3525
- int i = NUM2INT(tup_num);
3526
- int j = NUM2INT(field_num);
3527
-
3528
- result = get_pgresult(self);
3529
- if (i < 0 || i >= PQntuples(result)) {
3530
- rb_raise(rb_eArgError,"invalid tuple number %d", i);
3531
- }
3532
- if (j < 0 || j >= PQnfields(result)) {
3533
- rb_raise(rb_eArgError,"invalid field number %d", j);
3534
- }
3535
- return PQgetisnull(result, i, j) ? Qtrue : Qfalse;
3536
- }
3537
-
3538
1
  /*
3539
- * call-seq:
3540
- * res.getlength( tup_num, field_num ) -> Fixnum
2
+ * pg.c - Toplevel extension
3
+ * $Id$
3541
4
  *
3542
- * Returns the (String) length of the field in bytes.
5
+ * Author/s:
3543
6
  *
3544
- * Equivalent to <tt>res.value(<i>tup_num</i>,<i>field_num</i>).length</tt>.
3545
- */
3546
- static VALUE
3547
- pgresult_getlength(VALUE self, VALUE tup_num, VALUE field_num)
3548
- {
3549
- PGresult *result;
3550
- int i = NUM2INT(tup_num);
3551
- int j = NUM2INT(field_num);
3552
-
3553
- result = get_pgresult(self);
3554
- if (i < 0 || i >= PQntuples(result)) {
3555
- rb_raise(rb_eArgError,"invalid tuple number %d", i);
3556
- }
3557
- if (j < 0 || j >= PQnfields(result)) {
3558
- rb_raise(rb_eArgError,"invalid field number %d", j);
3559
- }
3560
- return INT2FIX(PQgetlength(result, i, j));
3561
- }
3562
-
3563
- /*
3564
- * call-seq:
3565
- * res.nparams() -> Fixnum
7
+ * - Jeff Davis <ruby-pg@j-davis.com>
8
+ * - Guy Decoux (ts) <decoux@moulon.inra.fr>
9
+ * - Michael Granger <ged@FaerieMUD.org>
10
+ * - Dave Lee
11
+ * - Eiji Matsumoto <usagi@ruby.club.or.jp>
12
+ * - Yukihiro Matsumoto <matz@ruby-lang.org>
13
+ * - Noboru Saitou <noborus@netlab.jp>
3566
14
  *
3567
- * Returns the number of parameters of a prepared statement.
3568
- * Only useful for the result returned by conn.describePrepared
3569
- */
3570
- static VALUE
3571
- pgresult_nparams(VALUE self)
3572
- {
3573
- PGresult *result;
3574
-
3575
- result = get_pgresult(self);
3576
- return INT2FIX(PQnparams(result));
3577
- }
3578
-
3579
- /*
3580
- * call-seq:
3581
- * res.paramtype( param_number ) -> Oid
15
+ * See Contributors.rdoc for the many additional fine people that have contributed
16
+ * to this library over the years.
3582
17
  *
3583
- * Returns the Oid of the data type of parameter _param_number_.
3584
- * Only useful for the result returned by conn.describePrepared
3585
- */
3586
- static VALUE
3587
- pgresult_paramtype(VALUE self, VALUE param_number)
3588
- {
3589
- PGresult *result;
3590
-
3591
- result = get_pgresult(self);
3592
- return INT2FIX(PQparamtype(result,NUM2INT(param_number)));
3593
- }
3594
-
3595
- /*
3596
- * call-seq:
3597
- * res.cmd_status() -> String
18
+ * Copyright (c) 1997-2012 by the authors.
3598
19
  *
3599
- * Returns the status string of the last query command.
3600
- */
3601
- static VALUE
3602
- pgresult_cmd_status(VALUE self)
3603
- {
3604
- VALUE ret = rb_tainted_str_new2(PQcmdStatus(get_pgresult(self)));
3605
- ASSOCIATE_INDEX(ret, self);
3606
- return ret;
3607
- }
3608
-
3609
- /*
3610
- * call-seq:
3611
- * res.cmd_tuples() -> Fixnum
20
+ * 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
+ * for details.
3612
23
  *
3613
- * Returns the number of tuples (rows) affected by the SQL command.
24
+ * Portions of the code are from the PostgreSQL project, and are distributed
25
+ * under the terms of the PostgreSQL license, included in the file "POSTGRES".
3614
26
  *
3615
- * If the SQL command that generated the PGresult was not one of:
3616
- * * +INSERT+
3617
- * * +UPDATE+
3618
- * * +DELETE+
3619
- * * +MOVE+
3620
- * * +FETCH+
3621
- * or if no tuples were affected, <tt>0</tt> is returned.
3622
- */
3623
- static VALUE
3624
- pgresult_cmd_tuples(VALUE self)
3625
- {
3626
- long n;
3627
- n = strtol(PQcmdTuples(get_pgresult(self)),NULL, 10);
3628
- return INT2NUM(n);
3629
- }
3630
-
3631
- /*
3632
- * call-seq:
3633
- * res.oid_value() -> Fixnum
27
+ * Portions copyright LAIKA, Inc.
3634
28
  *
3635
- * Returns the +oid+ of the inserted row if applicable,
3636
- * otherwise +nil+.
3637
- */
3638
- static VALUE
3639
- pgresult_oid_value(VALUE self)
3640
- {
3641
- Oid n = PQoidValue(get_pgresult(self));
3642
- if (n == InvalidOid)
3643
- return Qnil;
3644
- else
3645
- return INT2FIX(n);
3646
- }
3647
-
3648
- /* Utility methods not in libpq */
3649
-
3650
- /*
3651
- * call-seq:
3652
- * res[ n ] -> Hash
3653
29
  *
3654
- * Returns tuple _n_ as a hash.
3655
- */
3656
- static VALUE
3657
- pgresult_aref(VALUE self, VALUE index)
3658
- {
3659
- PGresult *result = get_pgresult(self);
3660
- int tuple_num = NUM2INT(index);
3661
- int field_num;
3662
- VALUE fname,val;
3663
- VALUE tuple;
3664
-
3665
- if ( tuple_num < 0 || tuple_num >= PQntuples(result) )
3666
- rb_raise( rb_eIndexError, "Index %d is out of range", tuple_num );
3667
-
3668
- tuple = rb_hash_new();
3669
- for ( field_num = 0; field_num < PQnfields(result); field_num++ ) {
3670
- fname = rb_tainted_str_new2( PQfname(result,field_num) );
3671
- ASSOCIATE_INDEX(fname, self);
3672
- if ( PQgetisnull(result, tuple_num, field_num) ) {
3673
- rb_hash_aset( tuple, fname, Qnil );
3674
- }
3675
- else {
3676
- val = rb_tainted_str_new( PQgetvalue(result, tuple_num, field_num ),
3677
- PQgetlength(result, tuple_num, field_num) );
3678
-
3679
- /* associate client encoding for text format only */
3680
- if ( 0 == PQfformat(result, field_num) ) {
3681
- ASSOCIATE_INDEX( val, self );
3682
- } else {
3683
- #ifdef M17N_SUPPORTED
3684
- rb_enc_associate( val, rb_ascii8bit_encoding() );
3685
- #endif
3686
- }
3687
- rb_hash_aset( tuple, fname, val );
3688
- }
3689
- }
3690
- return tuple;
3691
- }
3692
-
3693
-
3694
- /*
3695
- * call-seq:
3696
- * res.values -> Array
30
+ * The following functions are part of libpq, but not available from ruby-pg,
31
+ * because they are deprecated, obsolete, or generally not useful:
3697
32
  *
3698
- * Returns all tuples as an array of arrays.
33
+ * - PQfreemem -- unnecessary: copied to ruby object, then freed. Ruby object's
34
+ * memory is freed when it is garbage collected.
35
+ * - PQbinaryTuples -- better to use PQfformat
36
+ * - PQprint -- not very useful
37
+ * - PQsetdb -- not very useful
38
+ * - PQoidStatus -- deprecated, use PQoidValue
39
+ * - PQrequestCancel -- deprecated, use PQcancel
40
+ * - PQfn -- use a prepared statement instead
41
+ * - PQgetline -- deprecated, use PQgetCopyData
42
+ * - PQgetlineAsync -- deprecated, use PQgetCopyData
43
+ * - PQputline -- deprecated, use PQputCopyData
44
+ * - PQputnbytes -- deprecated, use PQputCopyData
45
+ * - PQendcopy -- deprecated, use PQputCopyEnd
3699
46
  */
3700
- static VALUE
3701
- pgresult_values(VALUE self, VALUE index)
3702
- {
3703
- PGresult* result = (PGresult*) get_pgresult(self);
3704
- int row;
3705
- int field;
3706
- int num_rows = PQntuples(result);
3707
- int num_fields = PQnfields(result);
3708
- VALUE ary = rb_ary_new2(num_rows);
3709
-
3710
- for ( row = 0; row < num_rows; row++ ) {
3711
- /* create new row */
3712
- VALUE new_row = rb_ary_new2(num_fields);
3713
-
3714
- /* add to return array */
3715
- rb_ary_store( ary, row, new_row );
3716
-
3717
- /* populate it */
3718
- for ( field = 0; field < num_fields; field++ ) {
3719
- if ( PQgetisnull(result, row, field) ) {
3720
- rb_ary_store( new_row, field, Qnil );
3721
- }
3722
- else {
3723
- VALUE val = rb_tainted_str_new( PQgetvalue(result, row, field),
3724
- PQgetlength(result, row, field) );
3725
-
3726
- /* associate client encoding for text format only */
3727
- if ( 0 == PQfformat(result, field) ) {
3728
- ASSOCIATE_INDEX( val, self );
3729
- } else {
3730
- #ifdef M17N_SUPPORTED
3731
- rb_enc_associate( val, rb_ascii8bit_encoding() );
3732
- #endif
3733
- }
3734
-
3735
- rb_ary_store( new_row, field, val );
3736
- }
3737
- }
3738
- }
3739
- return ary;
3740
- }
3741
47
 
48
+ #include "pg.h"
3742
49
 
3743
- /*
3744
- * call-seq:
3745
- * res.column_values( n ) -> array
3746
- *
3747
- * Returns an Array of the values from the nth column of each
3748
- * tuple in the result.
3749
- *
3750
- */
3751
- static VALUE
3752
- pgresult_column_values(VALUE self, VALUE index)
3753
- {
3754
- int col = NUM2INT( index );
3755
- return make_column_result_array( self, col );
3756
- }
50
+ VALUE rb_mPG;
51
+ VALUE rb_ePGerror;
52
+ VALUE rb_mPGconstants;
3757
53
 
3758
54
 
3759
55
  /*
3760
- * call-seq:
3761
- * res.field_values( field ) -> array
56
+ * Document-class: PGError
3762
57
  *
3763
- * Returns an Array of the values from the given _field_ of each tuple in the result.
58
+ * This is the exception class raised when an error is returned from
59
+ * a libpq API call.
3764
60
  *
3765
- */
3766
- static VALUE
3767
- pgresult_field_values( VALUE self, VALUE field )
3768
- {
3769
- PGresult *result = get_pgresult( self );
3770
- const char *fieldname = RSTRING_PTR( field );
3771
- int fnum = PQfnumber( result, fieldname );
3772
-
3773
- if ( fnum < 0 )
3774
- rb_raise( rb_eIndexError, "no such field '%s' in result", fieldname );
3775
-
3776
- return make_column_result_array( self, fnum );
3777
- }
3778
-
3779
-
3780
- /*
3781
- * Make a Ruby array out of the encoded values from the specified
3782
- * column in the given result.
3783
- */
3784
- static VALUE
3785
- make_column_result_array( VALUE self, int col )
3786
- {
3787
- PGresult *result = get_pgresult( self );
3788
- int row = PQntuples( result );
3789
- VALUE ary = rb_ary_new2( row );
3790
- VALUE val = Qnil;
3791
-
3792
- if ( col >= PQnfields(result) )
3793
- rb_raise( rb_eIndexError, "no column %d in result", col );
3794
-
3795
- while ( row-- ) {
3796
- val = rb_tainted_str_new( PQgetvalue(result, row, col),
3797
- PQgetlength(result, row, col) );
3798
-
3799
- /* associate client encoding for text format only */
3800
- if ( 0 == PQfformat(result, col) ) {
3801
- ASSOCIATE_INDEX( val, self );
3802
- } else {
3803
- #ifdef M17N_SUPPORTED
3804
- rb_enc_associate( val, rb_ascii8bit_encoding() );
3805
- #endif
3806
- }
3807
-
3808
- rb_ary_store( ary, row, val );
3809
- }
3810
-
3811
- return ary;
3812
- }
3813
-
3814
-
3815
- /*
3816
- * call-seq:
3817
- * res.each{ |tuple| ... }
61
+ * The attributes +connection+ and +result+ are set to the connection
62
+ * object and result set object, respectively.
3818
63
  *
3819
- * Invokes block for each tuple in the result set.
64
+ * If the connection object or result set object is not available from
65
+ * the context in which the error was encountered, it is +nil+.
3820
66
  */
3821
- static VALUE
3822
- pgresult_each(VALUE self)
3823
- {
3824
- PGresult *result = get_pgresult(self);
3825
- int tuple_num;
3826
-
3827
- for(tuple_num = 0; tuple_num < PQntuples(result); tuple_num++) {
3828
- rb_yield(pgresult_aref(self, INT2NUM(tuple_num)));
3829
- }
3830
- return self;
3831
- }
3832
67
 
3833
68
  /*
3834
- * call-seq:
3835
- * res.fields() -> Array
3836
- *
3837
- * Returns an array of Strings representing the names of the fields in the result.
69
+ * M17n functions
3838
70
  */
3839
- static VALUE
3840
- pgresult_fields(VALUE self)
3841
- {
3842
- PGresult *result;
3843
- VALUE ary;
3844
- int n, i;
3845
-
3846
- result = get_pgresult(self);
3847
- n = PQnfields(result);
3848
- ary = rb_ary_new2(n);
3849
- for (i=0;i<n;i++) {
3850
- VALUE val = rb_tainted_str_new2(PQfname(result, i));
3851
- ASSOCIATE_INDEX(val, self);
3852
- rb_ary_push(ary, val);
3853
- }
3854
- return ary;
3855
- }
3856
-
3857
71
 
3858
72
  #ifdef M17N_SUPPORTED
3859
73
  /**
3860
74
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
3861
75
  */
3862
- static const char * const (enc_pg2ruby_mapping[][2]) = {
3863
- {"BIG5", "Big5" },
3864
- {"EUC_CN", "GB2312" },
3865
- {"EUC_JP", "EUC-JP" },
3866
- {"EUC_JIS_2004", "EUC-JP" },
3867
- {"EUC_KR", "EUC-KR" },
3868
- {"EUC_TW", "EUC-TW" },
3869
- {"GB18030", "GB18030" },
3870
- {"GBK", "GBK" },
3871
- {"ISO_8859_5", "ISO-8859-5" },
3872
- {"ISO_8859_6", "ISO-8859-6" },
3873
- {"ISO_8859_7", "ISO-8859-7" },
3874
- {"ISO_8859_8", "ISO-8859-8" },
3875
- /* {"JOHAB", "JOHAB" }, dummy */
3876
- {"KOI8", "KOI8-R" },
3877
- {"KOI8R", "KOI8-R" },
3878
- {"KOI8U", "KOI8-U" },
3879
- {"LATIN1", "ISO-8859-1" },
3880
- {"LATIN2", "ISO-8859-2" },
3881
- {"LATIN3", "ISO-8859-3" },
3882
- {"LATIN4", "ISO-8859-4" },
3883
- {"LATIN5", "ISO-8859-5" },
3884
- {"LATIN6", "ISO-8859-6" },
3885
- {"LATIN7", "ISO-8859-7" },
3886
- {"LATIN8", "ISO-8859-8" },
3887
- {"LATIN9", "ISO-8859-9" },
3888
- {"LATIN10", "ISO-8859-10" },
3889
- {"MULE_INTERNAL", "Emacs-Mule" },
3890
- {"SJIS", "Windows-31J" },
3891
- {"SHIFT_JIS_2004","Windows-31J" },
3892
- /* {"SQL_ASCII", NULL }, special case*/
3893
- {"UHC", "CP949" },
3894
- {"UTF8", "UTF-8" },
3895
- {"WIN866", "IBM866" },
3896
- {"WIN874", "Windows-874" },
3897
- {"WIN1250", "Windows-1250"},
3898
- {"WIN1251", "Windows-1251"},
3899
- {"WIN1252", "Windows-1252"},
3900
- {"WIN1253", "Windows-1253"},
3901
- {"WIN1254", "Windows-1254"},
3902
- {"WIN1255", "Windows-1255"},
3903
- {"WIN1256", "Windows-1256"},
3904
- {"WIN1257", "Windows-1257"},
3905
- {"WIN1258", "Windows-1258"}
76
+ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
77
+ {"BIG5", "Big5" },
78
+ {"EUC_CN", "GB2312" },
79
+ {"EUC_JP", "EUC-JP" },
80
+ {"EUC_JIS_2004", "EUC-JP" },
81
+ {"EUC_KR", "EUC-KR" },
82
+ {"EUC_TW", "EUC-TW" },
83
+ {"GB18030", "GB18030" },
84
+ {"GBK", "GBK" },
85
+ {"ISO_8859_5", "ISO-8859-5" },
86
+ {"ISO_8859_6", "ISO-8859-6" },
87
+ {"ISO_8859_7", "ISO-8859-7" },
88
+ {"ISO_8859_8", "ISO-8859-8" },
89
+ /* {"JOHAB", "JOHAB" }, dummy */
90
+ {"KOI8", "KOI8-R" },
91
+ {"KOI8R", "KOI8-R" },
92
+ {"KOI8U", "KOI8-U" },
93
+ {"LATIN1", "ISO-8859-1" },
94
+ {"LATIN2", "ISO-8859-2" },
95
+ {"LATIN3", "ISO-8859-3" },
96
+ {"LATIN4", "ISO-8859-4" },
97
+ {"LATIN5", "ISO-8859-9" },
98
+ {"LATIN6", "ISO-8859-10" },
99
+ {"LATIN7", "ISO-8859-13" },
100
+ {"LATIN8", "ISO-8859-14" },
101
+ {"LATIN9", "ISO-8859-15" },
102
+ {"LATIN10", "ISO-8859-16" },
103
+ {"MULE_INTERNAL", "Emacs-Mule" },
104
+ {"SJIS", "Windows-31J" },
105
+ {"SHIFT_JIS_2004","Windows-31J" },
106
+ /* {"SQL_ASCII", NULL }, special case*/
107
+ {"UHC", "CP949" },
108
+ {"UTF8", "UTF-8" },
109
+ {"WIN866", "IBM866" },
110
+ {"WIN874", "Windows-874" },
111
+ {"WIN1250", "Windows-1250"},
112
+ {"WIN1251", "Windows-1251"},
113
+ {"WIN1252", "Windows-1252"},
114
+ {"WIN1253", "Windows-1253"},
115
+ {"WIN1254", "Windows-1254"},
116
+ {"WIN1255", "Windows-1255"},
117
+ {"WIN1256", "Windows-1256"},
118
+ {"WIN1257", "Windows-1257"},
119
+ {"WIN1258", "Windows-1258"}
3906
120
  };
3907
121
 
3908
122
 
@@ -3912,7 +126,14 @@ static const char * const (enc_pg2ruby_mapping[][2]) = {
3912
126
  static struct st_table *enc_pg2ruby;
3913
127
  static ID s_id_index;
3914
128
 
3915
- static int enc_get_index(VALUE val)
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)
3916
137
  {
3917
138
  int i = ENCODING_GET_INLINED(val);
3918
139
  if (i == ENCODING_INLINE_MAX) {
@@ -3922,21 +143,18 @@ static int enc_get_index(VALUE val)
3922
143
  return i;
3923
144
  }
3924
145
 
3925
- #ifdef HAVE_RB_ENCDB_ALIAS
3926
- # define ENC_ALIAS(name, orig) rb_encdb_alias((name), (orig))
3927
- #elif HAVE_RB_ENC_ALIAS
3928
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
3929
- #else
3930
- extern int rb_enc_alias(const char *alias, const char *orig); /* declaration missing in Ruby 1.9.1 */
3931
- # define ENC_ALIAS(name, orig) rb_enc_alias((name), (orig))
3932
- #endif
3933
146
 
147
+ /*
148
+ * Look up the JOHAB encoding, creating it as a dummy encoding if it's not
149
+ * already defined.
150
+ */
3934
151
  static rb_encoding *
3935
- find_or_create_johab(void)
152
+ pg_find_or_create_johab(void)
3936
153
  {
3937
154
  static const char * const aliases[] = { "JOHAB", "Windows-1361", "CP1361" };
3938
155
  int enc_index;
3939
- int i;
156
+ size_t i;
157
+
3940
158
  for (i = 0; i < sizeof(aliases)/sizeof(aliases[0]); ++i) {
3941
159
  enc_index = rb_enc_find_index(aliases[i]);
3942
160
  if (enc_index > 0) return rb_enc_from_index(enc_index);
@@ -3950,465 +168,200 @@ find_or_create_johab(void)
3950
168
  }
3951
169
 
3952
170
  /*
3953
- * Returns the client_encoding of the given connection as a rb_encoding*
171
+ * Return the given PostgreSQL encoding ID as an rb_encoding.
3954
172
  *
3955
- * * returns NULL if the client encoding is 'SQL_ASCII'.
3956
- * * returns ASCII-8BIT if the client encoding is unknown.
173
+ * - returns NULL if the client encoding is 'SQL_ASCII'.
174
+ * - returns ASCII-8BIT if the client encoding is unknown.
3957
175
  */
3958
- static rb_encoding *
3959
- pgconn_get_client_encoding_as_rb_encoding(PGconn* conn)
176
+ rb_encoding *
177
+ pg_get_pg_encoding_as_rb_encoding( int enc_id )
3960
178
  {
3961
179
  rb_encoding *enc;
3962
- int enc_id = PQclientEncoding(conn);
3963
180
 
3964
- if (st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc)) {
181
+ /* Use the cached value if it exists */
182
+ if ( st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc) ) {
3965
183
  return enc;
3966
184
  }
3967
185
  else {
3968
- int i;
3969
- const char *name = pg_encoding_to_char(enc_id);
3970
- if (strcmp("SQL_ASCII", name) == 0) {
3971
- enc = NULL;
3972
- goto cache;
3973
- }
3974
- for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
3975
- if (strcmp(name, enc_pg2ruby_mapping[i][0]) == 0) {
3976
- enc = rb_enc_find(enc_pg2ruby_mapping[i][1]);
3977
- goto cache;
3978
- }
3979
- }
186
+ const char *name = pg_encoding_to_char( enc_id );
3980
187
 
3981
- /* Ruby 1.9.1 does not supoort JOHAB */
3982
- if (strcmp(name, "JOHAB") == 0) {
3983
- enc = find_or_create_johab();
3984
- goto cache;
3985
- }
188
+ enc = pg_get_pg_encname_as_rb_encoding( name );
189
+ st_insert( enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc );
3986
190
 
3987
- enc = rb_ascii8bit_encoding();
191
+ return enc;
3988
192
  }
3989
- cache:
3990
- st_insert(enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc);
3991
- return enc;
3992
- }
3993
193
 
194
+ }
3994
195
 
3995
- /*
3996
- * Returns the given rb_encoding as the equivalent PostgreSQL encoding string.
3997
- *
196
+ /*
197
+ * Return the given PostgreSQL encoding name as an rb_encoding.
3998
198
  */
3999
- static const char *
4000
- pgconn_get_rb_encoding_as_pg_encname( rb_encoding *enc )
199
+ rb_encoding *
200
+ pg_get_pg_encname_as_rb_encoding( const char *pg_encname )
4001
201
  {
4002
- const char *rb_encname = rb_enc_name( enc );
4003
- const char *encname = NULL;
4004
- int i;
202
+ size_t i;
4005
203
 
4006
- for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
4007
- if (strcmp(rb_encname, enc_pg2ruby_mapping[i][1]) == 0) {
4008
- encname = enc_pg2ruby_mapping[i][0];
4009
- }
204
+ /* Trying looking it up in the conversion table */
205
+ for ( i = 0; i < sizeof(pg_enc_pg2ruby_mapping)/sizeof(pg_enc_pg2ruby_mapping[0]); ++i ) {
206
+ if ( strcmp(pg_encname, pg_enc_pg2ruby_mapping[i][0]) == 0 )
207
+ return rb_enc_find( pg_enc_pg2ruby_mapping[i][1] );
4010
208
  }
4011
209
 
4012
- if ( !encname ) encname = "SQL_ASCII";
4013
-
4014
- return encname;
4015
- }
210
+ /* JOHAB isn't a builtin encoding, so make up a dummy encoding if it's seen */
211
+ if ( strncmp(pg_encname, "JOHAB", 5) == 0 )
212
+ return pg_find_or_create_johab();
4016
213
 
4017
-
4018
- /*
4019
- * call-seq:
4020
- * conn.internal_encoding() -> Encoding
4021
- *
4022
- * defined in Ruby 1.9 or later.
4023
- *
4024
- * Returns:
4025
- * * an Encoding - client_encoding of the connection as a Ruby Encoding object.
4026
- * * nil - the client_encoding is 'SQL_ASCII'
4027
- */
4028
- static VALUE
4029
- pgconn_internal_encoding(VALUE self)
4030
- {
4031
- return rb_enc_from_encoding(pgconn_get_client_encoding_as_rb_encoding(get_pgconn(self)));
214
+ /* Fallthrough to ASCII-8BIT */
215
+ return rb_ascii8bit_encoding();
4032
216
  }
4033
217
 
4034
- static VALUE pgconn_external_encoding(VALUE self);
4035
-
4036
218
  /*
4037
- * call-seq:
4038
- * conn.internal_encoding = value
4039
- *
4040
- * A wrapper of +PGconn#set_client_encoding+.
4041
- * defined in Ruby 1.9 or later.
4042
- *
4043
- * +value+ can be one of:
4044
- * * an Encoding
4045
- * * a String - a name of Encoding
4046
- * * +nil+ - sets 'SQL_ASCII' to the client_encoding.
219
+ * Get the client encoding of the specified connection handle and return it as a rb_encoding.
4047
220
  */
4048
- static VALUE
4049
- pgconn_internal_encoding_set(VALUE self, VALUE enc)
221
+ rb_encoding *
222
+ pg_conn_enc_get( PGconn *conn )
4050
223
  {
4051
- if (NIL_P(enc)) {
4052
- pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("SQL_ASCII"));
4053
- return enc;
4054
- }
4055
- else if (TYPE(enc) == T_STRING && strcasecmp("JOHAB", RSTRING_PTR(enc)) == 0) {
4056
- pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
4057
- return enc;
4058
- }
4059
- else {
4060
- int i;
4061
- const char *name;
4062
- name = rb_enc_name(rb_to_encoding(enc));
4063
-
4064
- /* sequential search becuase rarely called */
4065
- for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
4066
- if (strcmp(name, enc_pg2ruby_mapping[i][1]) == 0) {
4067
- if (PQsetClientEncoding(get_pgconn(self), enc_pg2ruby_mapping[i][0]) == -1) {
4068
- VALUE server_encoding = pgconn_external_encoding(self);
4069
- rb_raise(rb_eEncCompatError, "imcompatible character encodings: %s and %s",
4070
- rb_enc_name(rb_to_encoding(server_encoding)),
4071
- enc_pg2ruby_mapping[i][0]);
4072
- }
4073
- return enc;
4074
- }
4075
- }
4076
-
4077
- /* Ruby 1.9.1 does not support JOHAB */
4078
- if (strcasecmp(name, "JOHAB") == 0) {
4079
- pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
4080
- return enc;
4081
- }
4082
- }
4083
-
4084
- enc = rb_inspect(enc);
4085
- rb_raise(rb_ePGError, "unknown encoding: %s", StringValuePtr(enc));
224
+ int enc_id = PQclientEncoding( conn );
225
+ return pg_get_pg_encoding_as_rb_encoding( enc_id );
4086
226
  }
4087
227
 
4088
228
 
4089
-
4090
- static VALUE enc_server_encoding_getvalue(VALUE pgresult)
4091
- {
4092
- return pgresult_getvalue(pgresult, INT2FIX(0), INT2FIX(0));
4093
- }
4094
-
4095
229
  /*
4096
- * call-seq:
4097
- * conn.external_encoding() -> Encoding
4098
- *
4099
- * defined in Ruby 1.9 or later.
4100
- * * Returns the server_encoding of the connected database as a Ruby Encoding object.
4101
- * * Maps 'SQL_ASCII' to ASCII-8BIT.
230
+ * Returns the given rb_encoding as the equivalent PostgreSQL encoding string.
4102
231
  */
4103
- static VALUE
4104
- pgconn_external_encoding(VALUE self)
232
+ const char *
233
+ pg_get_rb_encoding_as_pg_encoding( rb_encoding *enc )
4105
234
  {
4106
- VALUE enc;
4107
- enc = rb_iv_get(self, "@external_encoding");
4108
- if (RTEST(enc)) {
4109
- return enc;
4110
- }
4111
- else {
4112
- int i;
4113
- VALUE query = rb_usascii_str_new_cstr("SHOW server_encoding");
4114
- VALUE pgresult = pgconn_exec(1, &query, self);
4115
- VALUE enc_name = rb_ensure(enc_server_encoding_getvalue, pgresult, pgresult_clear, pgresult);
4116
-
4117
- if (strcmp("SQL_ASCII", StringValuePtr(enc_name)) == 0) {
4118
- enc = rb_enc_from_encoding(rb_ascii8bit_encoding());
4119
- goto cache;
4120
- }
4121
- for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
4122
- if (strcmp(StringValuePtr(enc_name), enc_pg2ruby_mapping[i][0]) == 0) {
4123
- enc = rb_enc_from_encoding(rb_enc_find(enc_pg2ruby_mapping[i][1]));
4124
- goto cache;
4125
- }
4126
- }
235
+ const char *rb_encname = rb_enc_name( enc );
236
+ const char *encname = NULL;
237
+ size_t i;
4127
238
 
4128
- /* Ruby 1.9.1 does not supoort JOHAB */
4129
- if (strcmp(StringValuePtr(enc_name), "JOHAB") == 0) {
4130
- enc = rb_enc_from_encoding(find_or_create_johab());
4131
- goto cache;
239
+ for (i = 0; i < sizeof(pg_enc_pg2ruby_mapping)/sizeof(pg_enc_pg2ruby_mapping[0]); ++i) {
240
+ if (strcmp(rb_encname, pg_enc_pg2ruby_mapping[i][1]) == 0) {
241
+ encname = pg_enc_pg2ruby_mapping[i][0];
4132
242
  }
4133
-
4134
- /* fallback */
4135
- enc = rb_enc_from_encoding(rb_enc_find(StringValuePtr(enc_name)));
4136
243
  }
4137
244
 
4138
- cache:
4139
- rb_iv_set(self, "@external_encoding", enc);
4140
- return enc;
4141
- }
245
+ if ( !encname ) encname = "SQL_ASCII";
4142
246
 
4143
- static void
4144
- init_m17n(void)
4145
- {
4146
- enc_pg2ruby = st_init_numtable();
4147
- s_id_index = rb_intern("@encoding");
4148
- rb_define_method(rb_cPGconn, "internal_encoding", pgconn_internal_encoding, 0);
4149
- rb_define_method(rb_cPGconn, "internal_encoding=", pgconn_internal_encoding_set, 1);
4150
- rb_define_method(rb_cPGconn, "external_encoding", pgconn_external_encoding, 0);
247
+ return encname;
4151
248
  }
4152
249
 
250
+ #endif /* M17N_SUPPORTED */
4153
251
 
4154
- #endif
4155
- /**************************************************************************/
4156
252
 
4157
253
  void
4158
254
  Init_pg_ext()
4159
255
  {
4160
- rb_ePGError = rb_define_class("PGError", rb_eStandardError);
4161
- rb_cPGconn = rb_define_class("PGconn", rb_cObject);
4162
- rb_cPGresult = rb_define_class("PGresult", rb_cObject);
4163
-
4164
- /* Library version */
4165
- rb_define_const( rb_cPGconn, "VERSION", rb_str_new2(VERSION) );
4166
-
4167
- /*************************
4168
- * PGError
4169
- *************************/
4170
- rb_define_alias(rb_ePGError, "error", "message");
4171
- rb_define_attr(rb_ePGError, "connection", 1, 0);
4172
- rb_define_attr(rb_ePGError, "result", 1, 0);
256
+ rb_mPG = rb_define_module( "PG" );
257
+ rb_ePGerror = rb_define_class_under( rb_mPG, "Error", rb_eStandardError );
258
+ rb_mPGconstants = rb_define_module_under( rb_mPG, "Constants" );
4173
259
 
4174
260
  /*************************
4175
- * PGconn
261
+ * PG::Error
4176
262
  *************************/
263
+ rb_define_alias( rb_ePGerror, "error", "message" );
264
+ rb_define_attr( rb_ePGerror, "connection", 1, 0 );
265
+ rb_define_attr( rb_ePGerror, "result", 1, 0 );
4177
266
 
4178
- /****** PGconn CLASS METHODS ******/
4179
- rb_define_alloc_func(rb_cPGconn, pgconn_alloc);
4180
- rb_define_singleton_alias(rb_cPGconn, "connect", "new");
4181
- rb_define_singleton_alias(rb_cPGconn, "open", "new");
4182
- rb_define_singleton_alias(rb_cPGconn, "setdb", "new");
4183
- rb_define_singleton_alias(rb_cPGconn, "setdblogin", "new");
4184
- rb_define_singleton_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
4185
- rb_define_singleton_alias(rb_cPGconn, "escape", "escape_string");
4186
- rb_define_singleton_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4187
- rb_define_singleton_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4188
- rb_define_singleton_method(rb_cPGconn, "isthreadsafe", pgconn_s_isthreadsafe, 0);
4189
- rb_define_singleton_method(rb_cPGconn, "encrypt_password", pgconn_s_encrypt_password, 2);
4190
- rb_define_singleton_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4191
- rb_define_singleton_method(rb_cPGconn, "connect_start", pgconn_s_connect_start, -1);
4192
- rb_define_singleton_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4193
-
4194
- /****** PGconn CLASS CONSTANTS: Connection Status ******/
267
+ /****** PG::Connection CLASS CONSTANTS: Connection Status ******/
4195
268
 
4196
269
  /* Connection succeeded */
4197
- rb_define_const(rb_cPGconn, "CONNECTION_OK", INT2FIX(CONNECTION_OK));
270
+ rb_define_const(rb_mPGconstants, "CONNECTION_OK", INT2FIX(CONNECTION_OK));
4198
271
  /* Connection failed */
4199
- rb_define_const(rb_cPGconn, "CONNECTION_BAD", INT2FIX(CONNECTION_BAD));
272
+ rb_define_const(rb_mPGconstants, "CONNECTION_BAD", INT2FIX(CONNECTION_BAD));
4200
273
 
4201
- /****** PGconn CLASS CONSTANTS: Nonblocking connection status ******/
274
+ /****** PG::Connection CLASS CONSTANTS: Nonblocking connection status ******/
4202
275
 
4203
276
  /* Waiting for connection to be made. */
4204
- rb_define_const(rb_cPGconn, "CONNECTION_STARTED", INT2FIX(CONNECTION_STARTED));
277
+ rb_define_const(rb_mPGconstants, "CONNECTION_STARTED", INT2FIX(CONNECTION_STARTED));
4205
278
  /* Connection OK; waiting to send. */
4206
- rb_define_const(rb_cPGconn, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE));
279
+ rb_define_const(rb_mPGconstants, "CONNECTION_MADE", INT2FIX(CONNECTION_MADE));
4207
280
  /* Waiting for a response from the server. */
4208
- rb_define_const(rb_cPGconn, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE));
281
+ rb_define_const(rb_mPGconstants, "CONNECTION_AWAITING_RESPONSE", INT2FIX(CONNECTION_AWAITING_RESPONSE));
4209
282
  /* Received authentication; waiting for backend start-up to finish. */
4210
- rb_define_const(rb_cPGconn, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK));
283
+ rb_define_const(rb_mPGconstants, "CONNECTION_AUTH_OK", INT2FIX(CONNECTION_AUTH_OK));
4211
284
  /* Negotiating SSL encryption. */
4212
- rb_define_const(rb_cPGconn, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
285
+ rb_define_const(rb_mPGconstants, "CONNECTION_SSL_STARTUP", INT2FIX(CONNECTION_SSL_STARTUP));
4213
286
  /* Negotiating environment-driven parameter settings. */
4214
- rb_define_const(rb_cPGconn, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
287
+ rb_define_const(rb_mPGconstants, "CONNECTION_SETENV", INT2FIX(CONNECTION_SETENV));
4215
288
 
4216
- /****** PGconn CLASS CONSTANTS: Nonblocking connection polling status ******/
289
+ /****** PG::Connection CLASS CONSTANTS: Nonblocking connection polling status ******/
4217
290
 
4218
291
  /* Async connection is waiting to read */
4219
- rb_define_const(rb_cPGconn, "PGRES_POLLING_READING", INT2FIX(PGRES_POLLING_READING));
292
+ rb_define_const(rb_mPGconstants, "PGRES_POLLING_READING", INT2FIX(PGRES_POLLING_READING));
4220
293
  /* Async connection is waiting to write */
4221
- rb_define_const(rb_cPGconn, "PGRES_POLLING_WRITING", INT2FIX(PGRES_POLLING_WRITING));
294
+ rb_define_const(rb_mPGconstants, "PGRES_POLLING_WRITING", INT2FIX(PGRES_POLLING_WRITING));
4222
295
  /* Async connection failed or was reset */
4223
- rb_define_const(rb_cPGconn, "PGRES_POLLING_FAILED", INT2FIX(PGRES_POLLING_FAILED));
296
+ rb_define_const(rb_mPGconstants, "PGRES_POLLING_FAILED", INT2FIX(PGRES_POLLING_FAILED));
4224
297
  /* Async connection succeeded */
4225
- rb_define_const(rb_cPGconn, "PGRES_POLLING_OK", INT2FIX(PGRES_POLLING_OK));
298
+ rb_define_const(rb_mPGconstants, "PGRES_POLLING_OK", INT2FIX(PGRES_POLLING_OK));
4226
299
 
4227
- /****** PGconn CLASS CONSTANTS: Transaction Status ******/
300
+ /****** PG::Connection CLASS CONSTANTS: Transaction Status ******/
4228
301
 
4229
302
  /* Transaction is currently idle (#transaction_status) */
4230
- rb_define_const(rb_cPGconn, "PQTRANS_IDLE", INT2FIX(PQTRANS_IDLE));
303
+ rb_define_const(rb_mPGconstants, "PQTRANS_IDLE", INT2FIX(PQTRANS_IDLE));
4231
304
  /* Transaction is currently active; query has been sent to the server, but not yet completed. (#transaction_status) */
4232
- rb_define_const(rb_cPGconn, "PQTRANS_ACTIVE", INT2FIX(PQTRANS_ACTIVE));
305
+ rb_define_const(rb_mPGconstants, "PQTRANS_ACTIVE", INT2FIX(PQTRANS_ACTIVE));
4233
306
  /* Transaction is currently idle, in a valid transaction block (#transaction_status) */
4234
- rb_define_const(rb_cPGconn, "PQTRANS_INTRANS", INT2FIX(PQTRANS_INTRANS));
307
+ rb_define_const(rb_mPGconstants, "PQTRANS_INTRANS", INT2FIX(PQTRANS_INTRANS));
4235
308
  /* Transaction is currently idle, in a failed transaction block (#transaction_status) */
4236
- rb_define_const(rb_cPGconn, "PQTRANS_INERROR", INT2FIX(PQTRANS_INERROR));
309
+ rb_define_const(rb_mPGconstants, "PQTRANS_INERROR", INT2FIX(PQTRANS_INERROR));
4237
310
  /* Transaction's connection is bad (#transaction_status) */
4238
- rb_define_const(rb_cPGconn, "PQTRANS_UNKNOWN", INT2FIX(PQTRANS_UNKNOWN));
311
+ rb_define_const(rb_mPGconstants, "PQTRANS_UNKNOWN", INT2FIX(PQTRANS_UNKNOWN));
4239
312
 
4240
- /****** PGconn CLASS CONSTANTS: Error Verbosity ******/
313
+ /****** PG::Connection CLASS CONSTANTS: Error Verbosity ******/
4241
314
 
4242
315
  /* Terse error verbosity level (#set_error_verbosity) */
4243
- rb_define_const(rb_cPGconn, "PQERRORS_TERSE", INT2FIX(PQERRORS_TERSE));
316
+ rb_define_const(rb_mPGconstants, "PQERRORS_TERSE", INT2FIX(PQERRORS_TERSE));
4244
317
  /* Default error verbosity level (#set_error_verbosity) */
4245
- rb_define_const(rb_cPGconn, "PQERRORS_DEFAULT", INT2FIX(PQERRORS_DEFAULT));
318
+ rb_define_const(rb_mPGconstants, "PQERRORS_DEFAULT", INT2FIX(PQERRORS_DEFAULT));
4246
319
  /* Verbose error verbosity level (#set_error_verbosity) */
4247
- rb_define_const(rb_cPGconn, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
320
+ rb_define_const(rb_mPGconstants, "PQERRORS_VERBOSE", INT2FIX(PQERRORS_VERBOSE));
4248
321
 
4249
- /****** PGconn CLASS CONSTANTS: Large Objects ******/
322
+ /****** PG::Connection CLASS CONSTANTS: Large Objects ******/
4250
323
 
4251
324
  /* Flag for #lo_creat, #lo_open -- open for writing */
4252
- rb_define_const(rb_cPGconn, "INV_WRITE", INT2FIX(INV_WRITE));
325
+ rb_define_const(rb_mPGconstants, "INV_WRITE", INT2FIX(INV_WRITE));
4253
326
  /* Flag for #lo_creat, #lo_open -- open for reading */
4254
- rb_define_const(rb_cPGconn, "INV_READ", INT2FIX(INV_READ));
327
+ rb_define_const(rb_mPGconstants, "INV_READ", INT2FIX(INV_READ));
4255
328
  /* Flag for #lo_lseek -- seek from object start */
4256
- rb_define_const(rb_cPGconn, "SEEK_SET", INT2FIX(SEEK_SET));
329
+ rb_define_const(rb_mPGconstants, "SEEK_SET", INT2FIX(SEEK_SET));
4257
330
  /* Flag for #lo_lseek -- seek from current position */
4258
- rb_define_const(rb_cPGconn, "SEEK_CUR", INT2FIX(SEEK_CUR));
331
+ rb_define_const(rb_mPGconstants, "SEEK_CUR", INT2FIX(SEEK_CUR));
4259
332
  /* Flag for #lo_lseek -- seek from object end */
4260
- rb_define_const(rb_cPGconn, "SEEK_END", INT2FIX(SEEK_END));
4261
-
4262
- /****** PGconn INSTANCE METHODS: Connection Control ******/
4263
- rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
4264
- rb_define_method(rb_cPGconn, "connect_poll", pgconn_connect_poll, 0);
4265
- rb_define_method(rb_cPGconn, "finish", pgconn_finish, 0);
4266
- rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0);
4267
- rb_define_method(rb_cPGconn, "reset_start", pgconn_reset_start, 0);
4268
- rb_define_method(rb_cPGconn, "reset_poll", pgconn_reset_poll, 0);
4269
- rb_define_method(rb_cPGconn, "conndefaults", pgconn_s_conndefaults, 0);
4270
- rb_define_alias(rb_cPGconn, "close", "finish");
4271
-
4272
- /****** PGconn INSTANCE METHODS: Connection Status ******/
4273
- rb_define_method(rb_cPGconn, "db", pgconn_db, 0);
4274
- rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
4275
- rb_define_method(rb_cPGconn, "pass", pgconn_pass, 0);
4276
- rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
4277
- rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
4278
- rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
4279
- rb_define_method(rb_cPGconn, "options", pgconn_options, 0);
4280
- rb_define_method(rb_cPGconn, "status", pgconn_status, 0);
4281
- rb_define_method(rb_cPGconn, "transaction_status", pgconn_transaction_status, 0);
4282
- rb_define_method(rb_cPGconn, "parameter_status", pgconn_parameter_status, 1);
4283
- rb_define_method(rb_cPGconn, "protocol_version", pgconn_protocol_version, 0);
4284
- rb_define_method(rb_cPGconn, "server_version", pgconn_server_version, 0);
4285
- rb_define_method(rb_cPGconn, "error_message", pgconn_error_message, 0);
4286
- rb_define_method(rb_cPGconn, "socket", pgconn_socket, 0);
4287
- rb_define_method(rb_cPGconn, "backend_pid", pgconn_backend_pid, 0);
4288
- rb_define_method(rb_cPGconn, "connection_needs_password", pgconn_connection_needs_password, 0);
4289
- rb_define_method(rb_cPGconn, "connection_used_password", pgconn_connection_used_password, 0);
4290
- //rb_define_method(rb_cPGconn, "getssl", pgconn_getssl, 0);
4291
-
4292
- /****** PGconn INSTANCE METHODS: Command Execution ******/
4293
- rb_define_method(rb_cPGconn, "exec", pgconn_exec, -1);
4294
- rb_define_alias(rb_cPGconn, "query", "exec");
4295
- rb_define_method(rb_cPGconn, "prepare", pgconn_prepare, -1);
4296
- rb_define_method(rb_cPGconn, "exec_prepared", pgconn_exec_prepared, -1);
4297
- rb_define_method(rb_cPGconn, "describe_prepared", pgconn_describe_prepared, 1);
4298
- rb_define_method(rb_cPGconn, "describe_portal", pgconn_describe_portal, 1);
4299
- rb_define_method(rb_cPGconn, "make_empty_pgresult", pgconn_make_empty_pgresult, 1);
4300
- rb_define_method(rb_cPGconn, "escape_string", pgconn_s_escape, 1);
4301
- rb_define_alias(rb_cPGconn, "escape", "escape_string");
4302
- rb_define_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
4303
- rb_define_method(rb_cPGconn, "unescape_bytea", pgconn_s_unescape_bytea, 1);
4304
-
4305
- /****** PGconn INSTANCE METHODS: Asynchronous Command Processing ******/
4306
- rb_define_method(rb_cPGconn, "send_query", pgconn_send_query, -1);
4307
- rb_define_method(rb_cPGconn, "send_prepare", pgconn_send_prepare, -1);
4308
- rb_define_method(rb_cPGconn, "send_query_prepared", pgconn_send_query_prepared, -1);
4309
- rb_define_method(rb_cPGconn, "send_describe_prepared", pgconn_send_describe_prepared, 1);
4310
- rb_define_method(rb_cPGconn, "send_describe_portal", pgconn_send_describe_portal, 1);
4311
- rb_define_method(rb_cPGconn, "get_result", pgconn_get_result, 0);
4312
- rb_define_method(rb_cPGconn, "consume_input", pgconn_consume_input, 0);
4313
- rb_define_method(rb_cPGconn, "is_busy", pgconn_is_busy, 0);
4314
- rb_define_method(rb_cPGconn, "setnonblocking", pgconn_setnonblocking, 1);
4315
- rb_define_method(rb_cPGconn, "isnonblocking", pgconn_isnonblocking, 0);
4316
- rb_define_alias(rb_cPGconn, "nonblocking?", "isnonblocking");
4317
- rb_define_method(rb_cPGconn, "flush", pgconn_flush, 0);
4318
-
4319
- /****** PGconn INSTANCE METHODS: Cancelling Queries in Progress ******/
4320
- rb_define_method(rb_cPGconn, "cancel", pgconn_cancel, 0);
4321
-
4322
- /****** PGconn INSTANCE METHODS: NOTIFY ******/
4323
- rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
4324
-
4325
- /****** PGconn INSTANCE METHODS: COPY ******/
4326
- rb_define_method(rb_cPGconn, "put_copy_data", pgconn_put_copy_data, 1);
4327
- rb_define_method(rb_cPGconn, "put_copy_end", pgconn_put_copy_end, -1);
4328
- rb_define_method(rb_cPGconn, "get_copy_data", pgconn_get_copy_data, -1);
333
+ rb_define_const(rb_mPGconstants, "SEEK_END", INT2FIX(SEEK_END));
4329
334
 
4330
- /****** PGconn INSTANCE METHODS: Control Functions ******/
4331
- rb_define_method(rb_cPGconn, "set_error_verbosity", pgconn_set_error_verbosity, 1);
4332
- rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
4333
- rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
4334
335
 
4335
- /****** PGconn INSTANCE METHODS: Notice Processing ******/
4336
- rb_define_method(rb_cPGconn, "set_notice_receiver", pgconn_set_notice_receiver, 0);
4337
- rb_define_method(rb_cPGconn, "set_notice_processor", pgconn_set_notice_processor, 0);
4338
-
4339
- /****** PGconn INSTANCE METHODS: Other ******/
4340
- rb_define_method(rb_cPGconn, "get_client_encoding", pgconn_get_client_encoding, 0);
4341
- rb_define_method(rb_cPGconn, "set_client_encoding", pgconn_set_client_encoding, 1);
4342
- rb_define_method(rb_cPGconn, "transaction", pgconn_transaction, 0);
4343
- rb_define_method(rb_cPGconn, "block", pgconn_block, -1);
4344
- rb_define_method(rb_cPGconn, "wait_for_notify", pgconn_wait_for_notify, -1);
4345
- rb_define_alias(rb_cPGconn, "notifies_wait", "wait_for_notify");
4346
- rb_define_method(rb_cPGconn, "quote_ident", pgconn_s_quote_ident, 1);
4347
- rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, -1);
4348
- rb_define_alias(rb_cPGconn, "async_query", "async_exec");
4349
- rb_define_method(rb_cPGconn, "get_last_result", pgconn_get_last_result, 0);
4350
-
4351
- /****** PGconn INSTANCE METHODS: Large Object Support ******/
4352
- rb_define_method(rb_cPGconn, "lo_creat", pgconn_locreat, -1);
4353
- rb_define_alias(rb_cPGconn, "locreat", "lo_creat");
4354
- rb_define_method(rb_cPGconn, "lo_create", pgconn_locreate, 1);
4355
- rb_define_alias(rb_cPGconn, "locreate", "lo_create");
4356
- rb_define_method(rb_cPGconn, "lo_import", pgconn_loimport, 1);
4357
- rb_define_alias(rb_cPGconn, "loimport", "lo_import");
4358
- rb_define_method(rb_cPGconn, "lo_export", pgconn_loexport, 2);
4359
- rb_define_alias(rb_cPGconn, "loexport", "lo_export");
4360
- rb_define_method(rb_cPGconn, "lo_open", pgconn_loopen, -1);
4361
- rb_define_alias(rb_cPGconn, "loopen", "lo_open");
4362
- rb_define_method(rb_cPGconn, "lo_write",pgconn_lowrite, 2);
4363
- rb_define_alias(rb_cPGconn, "lowrite", "lo_write");
4364
- rb_define_method(rb_cPGconn, "lo_read",pgconn_loread, 2);
4365
- rb_define_alias(rb_cPGconn, "loread", "lo_read");
4366
- rb_define_method(rb_cPGconn, "lo_lseek",pgconn_lolseek, 3);
4367
- rb_define_alias(rb_cPGconn, "lolseek", "lo_lseek");
4368
- rb_define_alias(rb_cPGconn, "lo_seek", "lo_lseek");
4369
- rb_define_alias(rb_cPGconn, "loseek", "lo_lseek");
4370
- rb_define_method(rb_cPGconn, "lo_tell",pgconn_lotell, 1);
4371
- rb_define_alias(rb_cPGconn, "lotell", "lo_tell");
4372
- rb_define_method(rb_cPGconn, "lo_truncate", pgconn_lotruncate, 2);
4373
- rb_define_alias(rb_cPGconn, "lotruncate", "lo_truncate");
4374
- rb_define_method(rb_cPGconn, "lo_close",pgconn_loclose, 1);
4375
- rb_define_alias(rb_cPGconn, "loclose", "lo_close");
4376
- rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
4377
- rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
4378
-
4379
- /*************************
4380
- * PGresult
4381
- *************************/
4382
- rb_include_module(rb_cPGresult, rb_mEnumerable);
4383
-
4384
- /****** PGresult CONSTANTS: result status ******/
336
+ /****** PG::Result CONSTANTS: result status ******/
4385
337
 
4386
338
  /* #result_status constant: The string sent to the server was empty. */
4387
- rb_define_const(rb_cPGresult, "PGRES_EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY));
339
+ rb_define_const(rb_mPGconstants, "PGRES_EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY));
4388
340
  /* #result_status constant: Successful completion of a command returning no data. */
4389
- rb_define_const(rb_cPGresult, "PGRES_COMMAND_OK", INT2FIX(PGRES_COMMAND_OK));
4390
- /* #result_status constant: Successful completion of a command returning data
341
+ rb_define_const(rb_mPGconstants, "PGRES_COMMAND_OK", INT2FIX(PGRES_COMMAND_OK));
342
+ /* #result_status constant: Successful completion of a command returning data
4391
343
  (such as a SELECT or SHOW). */
4392
- rb_define_const(rb_cPGresult, "PGRES_TUPLES_OK", INT2FIX(PGRES_TUPLES_OK));
344
+ rb_define_const(rb_mPGconstants, "PGRES_TUPLES_OK", INT2FIX(PGRES_TUPLES_OK));
4393
345
  /* #result_status constant: Copy Out (from server) data transfer started. */
4394
- rb_define_const(rb_cPGresult, "PGRES_COPY_OUT", INT2FIX(PGRES_COPY_OUT));
346
+ rb_define_const(rb_mPGconstants, "PGRES_COPY_OUT", INT2FIX(PGRES_COPY_OUT));
4395
347
  /* #result_status constant: Copy In (to server) data transfer started. */
4396
- rb_define_const(rb_cPGresult, "PGRES_COPY_IN", INT2FIX(PGRES_COPY_IN));
348
+ rb_define_const(rb_mPGconstants, "PGRES_COPY_IN", INT2FIX(PGRES_COPY_IN));
4397
349
  /* #result_status constant: The server’s response was not understood. */
4398
- rb_define_const(rb_cPGresult, "PGRES_BAD_RESPONSE", INT2FIX(PGRES_BAD_RESPONSE));
350
+ rb_define_const(rb_mPGconstants, "PGRES_BAD_RESPONSE", INT2FIX(PGRES_BAD_RESPONSE));
4399
351
  /* #result_status constant: A nonfatal error (a notice or warning) occurred. */
4400
- rb_define_const(rb_cPGresult, "PGRES_NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR));
352
+ rb_define_const(rb_mPGconstants, "PGRES_NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR));
4401
353
  /* #result_status constant: A fatal error occurred. */
4402
- rb_define_const(rb_cPGresult, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
354
+ rb_define_const(rb_mPGconstants, "PGRES_FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
4403
355
 
4404
- /****** PGresult CONSTANTS: result error field codes ******/
356
+ /****** Result CONSTANTS: result error field codes ******/
4405
357
 
4406
358
  /* #result_error_field argument constant: The severity; the field contents
4407
359
  * are ERROR, FATAL, or PANIC (in an error message), or WARNING, NOTICE,
4408
360
  * DEBUG, INFO, or LOG (in a notice message), or a localized translation
4409
361
  * of one of these. Always present.
4410
362
  */
4411
- rb_define_const(rb_cPGresult, "PG_DIAG_SEVERITY", INT2FIX(PG_DIAG_SEVERITY));
363
+ rb_define_const(rb_mPGconstants, "PG_DIAG_SEVERITY", INT2FIX(PG_DIAG_SEVERITY));
364
+
4412
365
  /* #result_error_field argument constant: The SQLSTATE code for the
4413
366
  * error. The SQLSTATE code identies the type of error that has occurred;
4414
367
  * it can be used by front-end applications to perform specic operations
@@ -4416,97 +369,79 @@ Init_pg_ext()
4416
369
  * error. For a list of the possible SQLSTATE codes, see Appendix A.
4417
370
  * This eld is not localizable, and is always present.
4418
371
  */
4419
- rb_define_const(rb_cPGresult, "PG_DIAG_SQLSTATE", INT2FIX(PG_DIAG_SQLSTATE));
372
+ rb_define_const(rb_mPGconstants, "PG_DIAG_SQLSTATE", INT2FIX(PG_DIAG_SQLSTATE));
373
+
4420
374
  /* #result_error_field argument constant: The primary human-readable
4421
375
  * error message (typically one line). Always present. */
4422
- rb_define_const(rb_cPGresult, "PG_DIAG_MESSAGE_PRIMARY", INT2FIX(PG_DIAG_MESSAGE_PRIMARY));
376
+ rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_PRIMARY", INT2FIX(PG_DIAG_MESSAGE_PRIMARY));
377
+
4423
378
  /* #result_error_field argument constant: Detail: an optional secondary
4424
379
  * error message carrying more detail about the problem. Might run to
4425
380
  * multiple lines.
4426
381
  */
4427
- rb_define_const(rb_cPGresult, "PG_DIAG_MESSAGE_DETAIL", INT2FIX(PG_DIAG_MESSAGE_DETAIL));
382
+ rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_DETAIL", INT2FIX(PG_DIAG_MESSAGE_DETAIL));
383
+
4428
384
  /* #result_error_field argument constant: Hint: an optional suggestion
4429
385
  * what to do about the problem. This is intended to differ from detail
4430
386
  * in that it offers advice (potentially inappropriate) rather than
4431
387
  * hard facts. Might run to multiple lines.
4432
388
  */
4433
- rb_define_const(rb_cPGresult, "PG_DIAG_MESSAGE_HINT", INT2FIX(PG_DIAG_MESSAGE_HINT));
389
+
390
+ rb_define_const(rb_mPGconstants, "PG_DIAG_MESSAGE_HINT", INT2FIX(PG_DIAG_MESSAGE_HINT));
4434
391
  /* #result_error_field argument constant: A string containing a decimal
4435
392
  * integer indicating an error cursor position as an index into the
4436
393
  * original statement string. The rst character has index 1, and
4437
394
  * positions are measured in characters not bytes.
4438
395
  */
4439
- rb_define_const(rb_cPGresult, "PG_DIAG_STATEMENT_POSITION", INT2FIX(PG_DIAG_STATEMENT_POSITION));
396
+
397
+ rb_define_const(rb_mPGconstants, "PG_DIAG_STATEMENT_POSITION", INT2FIX(PG_DIAG_STATEMENT_POSITION));
4440
398
  /* #result_error_field argument constant: This is dened the same as
4441
399
  * the PG_DIAG_STATEMENT_POSITION eld, but it is used when the cursor
4442
400
  * position refers to an internally generated command rather than the
4443
401
  * one submitted by the client. The PG_DIAG_INTERNAL_QUERY eld will
4444
402
  * always appear when this eld appears.
4445
403
  */
4446
- rb_define_const(rb_cPGresult, "PG_DIAG_INTERNAL_POSITION", INT2FIX(PG_DIAG_INTERNAL_POSITION));
404
+
405
+ rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_POSITION", INT2FIX(PG_DIAG_INTERNAL_POSITION));
4447
406
  /* #result_error_field argument constant: The text of a failed
4448
407
  * internally-generated command. This could be, for example, a SQL
4449
408
  * query issued by a PL/pgSQL function.
4450
409
  */
4451
- rb_define_const(rb_cPGresult, "PG_DIAG_INTERNAL_QUERY", INT2FIX(PG_DIAG_INTERNAL_QUERY));
410
+
411
+ rb_define_const(rb_mPGconstants, "PG_DIAG_INTERNAL_QUERY", INT2FIX(PG_DIAG_INTERNAL_QUERY));
4452
412
  /* #result_error_field argument constant: An indication of the context
4453
413
  * in which the error occurred. Presently this includes a call stack
4454
414
  * traceback of active procedural language functions and internally-generated
4455
415
  * queries. The trace is one entry per line, most recent rst.
4456
416
  */
4457
- rb_define_const(rb_cPGresult, "PG_DIAG_CONTEXT", INT2FIX(PG_DIAG_CONTEXT));
417
+
418
+ rb_define_const(rb_mPGconstants, "PG_DIAG_CONTEXT", INT2FIX(PG_DIAG_CONTEXT));
4458
419
  /* #result_error_field argument constant: The le name of the source-code
4459
420
  * location where the error was reported. */
4460
- rb_define_const(rb_cPGresult, "PG_DIAG_SOURCE_FILE", INT2FIX(PG_DIAG_SOURCE_FILE));
421
+ rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FILE", INT2FIX(PG_DIAG_SOURCE_FILE));
422
+
4461
423
  /* #result_error_field argument constant: The line number of the
4462
424
  * source-code location where the error was reported. */
4463
- rb_define_const(rb_cPGresult, "PG_DIAG_SOURCE_LINE", INT2FIX(PG_DIAG_SOURCE_LINE));
425
+ rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_LINE", INT2FIX(PG_DIAG_SOURCE_LINE));
426
+
4464
427
  /* #result_error_field argument constant: The name of the source-code
4465
428
  * function reporting the error. */
4466
- rb_define_const(rb_cPGresult, "PG_DIAG_SOURCE_FUNCTION", INT2FIX(PG_DIAG_SOURCE_FUNCTION));
429
+ rb_define_const(rb_mPGconstants, "PG_DIAG_SOURCE_FUNCTION", INT2FIX(PG_DIAG_SOURCE_FUNCTION));
4467
430
 
4468
431
  /* Invalid OID constant */
4469
- rb_define_const(rb_cPGresult, "InvalidOid", INT2FIX(InvalidOid));
4470
-
4471
- /****** PGresult INSTANCE METHODS: libpq ******/
4472
- rb_define_method(rb_cPGresult, "result_status", pgresult_result_status, 0);
4473
- rb_define_method(rb_cPGresult, "res_status", pgresult_res_status, 1);
4474
- rb_define_method(rb_cPGresult, "error_message", pgresult_error_message, 0);
4475
- rb_define_alias( rb_cPGresult, "result_error_message", "error_message");
4476
- rb_define_method(rb_cPGresult, "error_field", pgresult_error_field, 1);
4477
- rb_define_alias( rb_cPGresult, "result_error_field", "error_field" );
4478
- rb_define_method(rb_cPGresult, "clear", pgresult_clear, 0);
4479
- rb_define_method(rb_cPGresult, "ntuples", pgresult_ntuples, 0);
4480
- rb_define_alias(rb_cPGresult, "num_tuples", "ntuples");
4481
- rb_define_method(rb_cPGresult, "nfields", pgresult_nfields, 0);
4482
- rb_define_alias(rb_cPGresult, "num_fields", "nfields");
4483
- rb_define_method(rb_cPGresult, "fname", pgresult_fname, 1);
4484
- rb_define_method(rb_cPGresult, "fnumber", pgresult_fnumber, 1);
4485
- rb_define_method(rb_cPGresult, "ftable", pgresult_ftable, 1);
4486
- rb_define_method(rb_cPGresult, "ftablecol", pgresult_ftablecol, 1);
4487
- rb_define_method(rb_cPGresult, "fformat", pgresult_fformat, 1);
4488
- rb_define_method(rb_cPGresult, "ftype", pgresult_ftype, 1);
4489
- rb_define_method(rb_cPGresult, "fmod", pgresult_fmod, 1);
4490
- rb_define_method(rb_cPGresult, "fsize", pgresult_fsize, 1);
4491
- rb_define_method(rb_cPGresult, "getvalue", pgresult_getvalue, 2);
4492
- rb_define_method(rb_cPGresult, "getisnull", pgresult_getisnull, 2);
4493
- rb_define_method(rb_cPGresult, "getlength", pgresult_getlength, 2);
4494
- rb_define_method(rb_cPGresult, "nparams", pgresult_nparams, 0);
4495
- rb_define_method(rb_cPGresult, "paramtype", pgresult_paramtype, 1);
4496
- rb_define_method(rb_cPGresult, "cmd_status", pgresult_cmd_status, 0);
4497
- rb_define_method(rb_cPGresult, "cmd_tuples", pgresult_cmd_tuples, 0);
4498
- rb_define_alias(rb_cPGresult, "cmdtuples", "cmd_tuples");
4499
- rb_define_method(rb_cPGresult, "oid_value", pgresult_oid_value, 0);
432
+ rb_define_const(rb_mPGconstants, "INVALID_OID", INT2FIX(InvalidOid));
433
+ rb_define_const(rb_mPGconstants, "InvalidOid", INT2FIX(InvalidOid));
4500
434
 
4501
- /****** PGresult INSTANCE METHODS: other ******/
4502
- rb_define_method(rb_cPGresult, "[]", pgresult_aref, 1);
4503
- rb_define_method(rb_cPGresult, "each", pgresult_each, 0);
4504
- rb_define_method(rb_cPGresult, "fields", pgresult_fields, 0);
4505
- rb_define_method(rb_cPGresult, "values", pgresult_values, 0);
4506
- rb_define_method(rb_cPGresult, "column_values", pgresult_column_values, 1);
4507
- rb_define_method(rb_cPGresult, "field_values", pgresult_field_values, 1);
435
+ /* Add the constants to the toplevel namespace */
436
+ rb_include_module( rb_mPG, rb_mPGconstants );
4508
437
 
4509
- #ifdef M17N_SUPPORTED
4510
- init_m17n();
438
+ #ifdef M17N_SUPPORTED
439
+ enc_pg2ruby = st_init_numtable();
440
+ s_id_index = rb_intern("@encoding");
4511
441
  #endif
442
+
443
+ /* Initialize the main extension classes */
444
+ init_pg_connection();
445
+ init_pg_result();
4512
446
  }
447
+