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

Sign up to get free protection for your applications and to get access to all the features.
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
+