pg 0.12.0 → 0.16.0

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