postgres 0.7.1

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.
data/extconf.rb ADDED
@@ -0,0 +1,47 @@
1
+ if VERSION < "1.3"
2
+ print "This library is for ruby-1.3 or higher.\n"
3
+ exit 1
4
+ end
5
+
6
+ require "mkmf"
7
+
8
+ dir_config('pgsql')
9
+
10
+ $CFLAGS = ""
11
+ $LDFLAGS = ""
12
+
13
+ have_library("wsock32", "cygwin32_socket") or have_library("socket", "socket")
14
+ have_library("inet", "gethostbyname")
15
+ have_library("nsl", "gethostbyname")
16
+ have_header("sys/un.h")
17
+ if have_func("socket") or have_func("cygwin32_socket")
18
+ have_func("hsterror")
19
+ unless have_func("gethostname")
20
+ have_func("uname")
21
+ end
22
+ if ENV["SOCKS_SERVER"] # test if SOCKSsocket needed
23
+ if have_library("socks", "Rconnect")
24
+ $CFLAGS+="-DSOCKS"
25
+ end
26
+ end
27
+ incdir = ENV["POSTGRES_INCLUDE"]
28
+ incdir ||= with_config("pgsql-include-dir")
29
+ if incdir
30
+ $CFLAGS += "-I#{incdir}"
31
+ puts "Using PostgreSQL include directory: #{incdir}"
32
+ end
33
+ libdir = ENV["POSTGRES_LIB"]
34
+ libdir ||= with_config("pgsql-lib-dir")
35
+ if libdir
36
+ $LDFLAGS += "-L#{libdir}"
37
+ puts "Using PostgreSQL lib directory: #{libdir}"
38
+ end
39
+ if have_library("pq", "PQsetdbLogin")
40
+ have_func("PQsetClientEncoding")
41
+ have_func("pg_encoding_to_char")
42
+ have_func("PQescapeString")
43
+ create_makefile("postgres")
44
+ else
45
+ puts "Could not find PostgreSQL libraries: Makefile not created"
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+
3
+ SPEC = Gem::Specification.new do |s|
4
+ s.name = "postgres"
5
+ s.version = %q{0.7.1}
6
+ s.author = "Yukihiro Matsumoto, Eiji Matsumoto, Noboru Saitou"
7
+ s.email = "noborus@netlab.jp"
8
+ s.homepage = "http://www.postgresql.jp/interfaces/ruby/"
9
+ s.autorequire = "postgres"
10
+ s.platform = Gem::Platform::RUBY
11
+ s.summary = "The extension library to access a PostgreSQL database from Ruby."
12
+ s.extensions = %w{extconf.rb}
13
+ s.files = Dir.glob('**/*')
14
+ s.requirements = ["none"]
15
+ s.require_paths = %w{.}
16
+ s.required_ruby_version = %q{> 0.0.0}
17
+ end
18
+
19
+ if $0 == __FILE__
20
+ Gem::manage_gems
21
+ Gem::Builder.new(spec).build
22
+ end
data/postgres.c ADDED
@@ -0,0 +1,1513 @@
1
+ /************************************************
2
+
3
+ postgres.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: noboru $
12
+ $Date: 2003/01/06 01:38:20 $
13
+ ************************************************/
14
+
15
+ #include "ruby.h"
16
+ #include "rubyio.h"
17
+
18
+ #include <libpq-fe.h>
19
+ #include <libpq/libpq-fs.h> /* large-object interface */
20
+ #include <stdio.h>
21
+ #include <stdlib.h>
22
+ #include <sys/types.h>
23
+
24
+ #ifndef HAVE_PG_ENCODING_TO_CHAR
25
+ #define pg_encoding_to_char(x) "SQL_ASCII"
26
+ #endif
27
+
28
+ static VALUE rb_cPGconn;
29
+ static VALUE rb_cPGresult;
30
+
31
+ static VALUE rb_ePGError;
32
+
33
+ static VALUE pgresult_result _((VALUE));
34
+ static VALUE pgresult_result_with_clear _((VALUE));
35
+ static VALUE pgresult_new _((PGresult*));
36
+
37
+ EXTERN VALUE rb_mEnumerable;
38
+
39
+ static VALUE rb_cPGlarge;
40
+
41
+ /* Large Object support */
42
+ typedef struct pglarge_object
43
+ {
44
+ PGconn *pgconn;
45
+ Oid lo_oid;
46
+ int lo_fd;
47
+ } PGlarge;
48
+
49
+ static VALUE pglarge_new _((PGconn*, Oid, int));
50
+ /* Large Object support */
51
+
52
+ static void
53
+ free_pgconn(ptr)
54
+ PGconn *ptr;
55
+ {
56
+ PQfinish(ptr);
57
+ }
58
+
59
+ static VALUE
60
+ pgconn_s_connect(argc, argv, pgconn)
61
+ int argc;
62
+ VALUE *argv;
63
+ VALUE pgconn;
64
+ {
65
+ VALUE arg[7];
66
+ char *pghost, *pgopt, *pgtty, *pgdbname, *pglogin, *pgpwd;
67
+ int pgport;
68
+ char port_buffer[20];
69
+ PGconn *conn;
70
+
71
+ pghost=pgopt=pgtty=pgdbname=pglogin=pgpwd=NULL;
72
+ pgport = -1;
73
+ rb_scan_args(argc,argv,"07", &arg[0], &arg[1], &arg[2], &arg[3], &arg[4],
74
+ &arg[5], &arg[6]);
75
+ if (!NIL_P(arg[0])) {
76
+ Check_Type(arg[0], T_STRING);
77
+ pghost = STR2CSTR(arg[0]);
78
+ }
79
+ if (!NIL_P(arg[1])) {
80
+ pgport = NUM2INT(arg[1]);
81
+ }
82
+ if (!NIL_P(arg[2])) {
83
+ Check_Type(arg[2], T_STRING);
84
+ pgopt = STR2CSTR(arg[2]);
85
+ }
86
+ if (!NIL_P(arg[3])) {
87
+ Check_Type(arg[3], T_STRING);
88
+ pgtty = STR2CSTR(arg[3]);
89
+ }
90
+ if (!NIL_P(arg[4])) {
91
+ Check_Type(arg[4], T_STRING);
92
+ pgdbname = STR2CSTR(arg[4]);
93
+ }
94
+ if (!NIL_P(arg[5])) {
95
+ Check_Type(arg[5], T_STRING);
96
+ pglogin = STR2CSTR(arg[5]);
97
+ }
98
+ if (!NIL_P(arg[6])) {
99
+ Check_Type(arg[6], T_STRING);
100
+ pgpwd = STR2CSTR(arg[6]);
101
+ }
102
+ if (pgport!=-1) {
103
+ sprintf(port_buffer, "%d", pgport);
104
+ conn = PQsetdbLogin(pghost, port_buffer, pgopt, pgtty, pgdbname,
105
+ pglogin, pgpwd);
106
+ }
107
+ else {
108
+ conn = PQsetdbLogin(pghost, NULL, pgopt, pgtty, pgdbname,
109
+ pglogin, pgpwd);
110
+ }
111
+
112
+ if (PQstatus(conn) == CONNECTION_BAD) {
113
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
114
+ }
115
+
116
+ return Data_Wrap_Struct(pgconn, 0, free_pgconn, conn);
117
+ }
118
+
119
+ #ifdef HAVE_PQESCAPESTRING
120
+ static VALUE
121
+ pgconn_s_escape(self, obj)
122
+ VALUE self;
123
+ VALUE obj;
124
+ {
125
+ char *to;
126
+ long len;
127
+ VALUE ret;
128
+
129
+ Check_Type(obj, T_STRING);
130
+
131
+ to = ALLOC_N(char, RSTRING(obj)->len * 2);
132
+
133
+ len = PQescapeString(to, RSTRING(obj)->ptr, RSTRING(obj)->len);
134
+
135
+ ret = rb_str_new(to, len);
136
+ OBJ_INFECT(ret, obj);
137
+
138
+ free(to);
139
+
140
+ return ret;
141
+ }
142
+
143
+ static VALUE
144
+ pgconn_s_quote(self, obj)
145
+ VALUE self;
146
+ VALUE obj;
147
+ {
148
+ VALUE ret;
149
+ char *to;
150
+ long len;
151
+ long idx;
152
+
153
+ switch(TYPE(obj)) {
154
+ case T_STRING:
155
+
156
+ to = ALLOC_N(char, RSTRING(obj)->len * 2 + 2);
157
+
158
+ *to = '\'';
159
+ len = PQescapeString(to + 1, RSTRING(obj)->ptr, RSTRING(obj)->len);
160
+ *(to + len + 1) = '\'';
161
+
162
+ ret = rb_str_new(to, len + 2);
163
+ OBJ_INFECT(ret, obj);
164
+
165
+ free(to);
166
+ break;
167
+
168
+ case T_FIXNUM:
169
+ case T_BIGNUM:
170
+ case T_FLOAT:
171
+ ret = rb_obj_as_string(obj);
172
+ break;
173
+
174
+ case T_NIL:
175
+ ret = rb_str_new2("NULL");
176
+ break;
177
+
178
+ case T_TRUE:
179
+ ret = rb_str_new2("'t'");
180
+ break;
181
+
182
+ case T_FALSE:
183
+ ret = rb_str_new2("'f'");
184
+ break;
185
+
186
+ case T_ARRAY:
187
+ ret = rb_str_new(0,0);
188
+ len = RARRAY(obj)->len;
189
+ for(idx=0; idx<len; idx++) {
190
+ rb_str_concat(ret, pgconn_s_quote(self, rb_ary_entry(obj, idx)));
191
+ if (idx<len-1) {
192
+ rb_str_cat2(ret, ", ");
193
+ }
194
+ }
195
+ break;
196
+ default:
197
+ if (rb_block_given_p()==Qtrue) {
198
+ ret = rb_yield(obj);
199
+ } else {
200
+ rb_raise(rb_ePGError, "can't quote");
201
+ }
202
+ }
203
+
204
+ return ret;
205
+ }
206
+
207
+ static VALUE
208
+ pgconn_s_escape_bytea(self, obj)
209
+ VALUE self;
210
+ VALUE obj;
211
+ {
212
+ unsigned char c;
213
+ char *from, *to;
214
+ long idx;
215
+ size_t from_len, to_len;
216
+ VALUE ret;
217
+
218
+ Check_Type(obj, T_STRING);
219
+ from = RSTRING(obj)->ptr;
220
+ from_len = RSTRING(obj)->len;
221
+
222
+ to = (char *)PQescapeBytea(from, from_len, &to_len);
223
+
224
+ ret = rb_str_new(to, to_len - 1);
225
+ OBJ_INFECT(ret, obj);
226
+
227
+ free(to);
228
+
229
+ return ret;
230
+ }
231
+ #endif
232
+
233
+ static VALUE
234
+ pgconn_s_new(argc, argv, pgconn)
235
+ int argc;
236
+ VALUE *argv;
237
+ VALUE pgconn;
238
+ {
239
+ VALUE conn = pgconn_s_connect(argc, argv, pgconn);
240
+
241
+ rb_obj_call_init(conn, argc, argv);
242
+ return conn;
243
+ }
244
+
245
+ static VALUE
246
+ pgconn_init(argc, argv, conn)
247
+ int argc;
248
+ VALUE *argv;
249
+ VALUE conn;
250
+ {
251
+ return conn;
252
+ }
253
+
254
+ static PGconn*
255
+ get_pgconn(obj)
256
+ VALUE obj;
257
+ {
258
+ PGconn *conn;
259
+
260
+ Data_Get_Struct(obj, PGconn, conn);
261
+ if (conn == 0) rb_raise(rb_ePGError, "closed connection");
262
+ return conn;
263
+ }
264
+
265
+ static VALUE
266
+ pgconn_close(obj)
267
+ VALUE obj;
268
+ {
269
+ PQfinish(get_pgconn(obj));
270
+ DATA_PTR(obj) = 0;
271
+
272
+ return Qnil;
273
+ }
274
+
275
+ static VALUE
276
+ pgconn_reset(obj)
277
+ VALUE obj;
278
+ {
279
+ PQreset(get_pgconn(obj));
280
+ return obj;
281
+ }
282
+
283
+ static PGresult*
284
+ get_pgresult(obj)
285
+ VALUE obj;
286
+ {
287
+ PGresult *result;
288
+
289
+ Data_Get_Struct(obj, PGresult, result);
290
+ if (result == 0) rb_raise(rb_ePGError, "query not performed");
291
+ return result;
292
+ }
293
+
294
+ static VALUE
295
+ pgconn_exec(obj, str)
296
+ VALUE obj, str;
297
+ {
298
+ PGconn *conn = get_pgconn(obj);
299
+ PGresult *result;
300
+ int status;
301
+ char *msg;
302
+
303
+ Check_Type(str, T_STRING);
304
+
305
+ result = PQexec(conn, STR2CSTR(str));
306
+ if (!result) {
307
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
308
+ }
309
+ status = PQresultStatus(result);
310
+
311
+ switch (status) {
312
+ case PGRES_TUPLES_OK:
313
+ case PGRES_COPY_OUT:
314
+ case PGRES_COPY_IN:
315
+ case PGRES_EMPTY_QUERY:
316
+ case PGRES_COMMAND_OK: /* no data will be received */
317
+ return pgresult_new(result);
318
+
319
+ case PGRES_BAD_RESPONSE:
320
+ case PGRES_FATAL_ERROR:
321
+ case PGRES_NONFATAL_ERROR:
322
+ msg = PQerrorMessage(conn);
323
+ break;
324
+ default:
325
+ msg = "internal error : unknown result status.";
326
+ break;
327
+ }
328
+ PQclear(result);
329
+ rb_raise(rb_ePGError, msg);
330
+ }
331
+
332
+ static VALUE
333
+ pgconn_async_exec(obj, str)
334
+ VALUE obj, str;
335
+ {
336
+ PGconn *conn = get_pgconn(obj);
337
+ PGresult *result;
338
+ int status;
339
+ char *msg;
340
+
341
+ int cs;
342
+ int ret;
343
+ fd_set rset;
344
+
345
+ Check_Type(str, T_STRING);
346
+
347
+ while(result = PQgetResult(conn)) {
348
+ PQclear(result);
349
+ }
350
+
351
+ if (!PQsendQuery(conn, RSTRING(str)->ptr)) {
352
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
353
+ }
354
+
355
+ cs = PQsocket(conn);
356
+ for(;;) {
357
+ FD_ZERO(&rset);
358
+ FD_SET(cs, &rset);
359
+ ret = rb_thread_select(cs + 1, &rset, NULL, NULL, NULL);
360
+ if (ret < 0) {
361
+ rb_sys_fail(0);
362
+ }
363
+
364
+ if (ret == 0) {
365
+ continue;
366
+ }
367
+
368
+ if (PQconsumeInput(conn) == 0) {
369
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
370
+ }
371
+
372
+ if (PQisBusy(conn) == 0) {
373
+ break;
374
+ }
375
+ }
376
+
377
+ result = PQgetResult(conn);
378
+
379
+ if (!result) {
380
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
381
+ }
382
+ status = PQresultStatus(result);
383
+
384
+ switch (status) {
385
+ case PGRES_TUPLES_OK:
386
+ case PGRES_COPY_OUT:
387
+ case PGRES_COPY_IN:
388
+ case PGRES_EMPTY_QUERY:
389
+ case PGRES_COMMAND_OK: /* no data will be received */
390
+ return pgresult_new(result);
391
+
392
+ case PGRES_BAD_RESPONSE:
393
+ case PGRES_FATAL_ERROR:
394
+ case PGRES_NONFATAL_ERROR:
395
+ msg = PQerrorMessage(conn);
396
+ break;
397
+ default:
398
+ msg = "internal error : unknown result status.";
399
+ break;
400
+ }
401
+ PQclear(result);
402
+ rb_raise(rb_ePGError, msg);
403
+ }
404
+
405
+
406
+ static VALUE
407
+ pgconn_query(obj, str)
408
+ VALUE obj, str;
409
+ {
410
+ return pgresult_result_with_clear(pgconn_exec(obj, str));
411
+ }
412
+
413
+ static VALUE
414
+ pgconn_async_query(obj, str)
415
+ VALUE obj, str;
416
+ {
417
+ return pgresult_result_with_clear(pgconn_async_exec(obj, str));
418
+ }
419
+
420
+
421
+ static VALUE
422
+ pgconn_get_notify(obj)
423
+ VALUE obj;
424
+ {
425
+ PGnotify *notify;
426
+ VALUE ary;
427
+
428
+ /* gets notify and builds result */
429
+ notify = PQnotifies(get_pgconn(obj));
430
+ if (notify == NULL) {
431
+ /* there are no unhandled notifications */
432
+ return Qnil;
433
+ }
434
+ ary = rb_ary_new3(2, rb_tainted_str_new2(notify->relname),
435
+ INT2NUM(notify->be_pid));
436
+ free(notify);
437
+
438
+ /* returns result */
439
+ return ary;
440
+ }
441
+
442
+ static VALUE pg_escape_regex;
443
+ static VALUE pg_escape_str;
444
+ static ID pg_gsub_bang_id;
445
+
446
+ static VALUE
447
+ pgconn_insert_table(obj, table, values)
448
+ VALUE obj, table, values;
449
+ {
450
+ PGconn *conn = get_pgconn(obj);
451
+ PGresult *result;
452
+ VALUE s, buffer;
453
+ int i, j;
454
+ int res = 0;
455
+
456
+ Check_Type(table, T_STRING);
457
+ Check_Type(values, T_ARRAY);
458
+ i = RARRAY(values)->len;
459
+ while (i--) {
460
+ if (TYPE(RARRAY(RARRAY(values)->ptr[i])) != T_ARRAY) {
461
+ rb_raise(rb_ePGError, "second arg must contain some kind of arrays.");
462
+ }
463
+ }
464
+
465
+ buffer = rb_str_new(0, RSTRING(table)->len + 17 + 1);
466
+ /* starts query */
467
+ snprintf(RSTRING(buffer)->ptr, RSTRING(buffer)->len, "copy %s from stdin ", STR2CSTR(table));
468
+
469
+ result = PQexec(conn, STR2CSTR(buffer));
470
+ if (!result){
471
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
472
+ }
473
+ PQclear(result);
474
+
475
+ for (i = 0; i < RARRAY(values)->len; i++) {
476
+ struct RArray *row = RARRAY(RARRAY(values)->ptr[i]);
477
+ buffer = rb_tainted_str_new(0,0);
478
+ for (j = 0; j < row->len; j++) {
479
+ if (j > 0) rb_str_cat(buffer, "\t", 1);
480
+ if (NIL_P(row->ptr[j])) {
481
+ rb_str_cat(buffer, "\\N",2);
482
+ } else {
483
+ s = rb_obj_as_string(row->ptr[j]);
484
+ rb_funcall(s,pg_gsub_bang_id,2,pg_escape_regex,pg_escape_str);
485
+ rb_str_cat(buffer, STR2CSTR(s), RSTRING(s)->len);
486
+ }
487
+ }
488
+ rb_str_cat(buffer, "\n\0", 2);
489
+ /* sends data */
490
+ PQputline(conn, STR2CSTR(buffer));
491
+ }
492
+ PQputline(conn, "\\.\n");
493
+ res = PQendcopy(conn);
494
+
495
+ return obj;
496
+ }
497
+
498
+ static VALUE
499
+ pgconn_putline(obj, str)
500
+ VALUE obj, str;
501
+ {
502
+ Check_Type(str, T_STRING);
503
+ PQputline(get_pgconn(obj), STR2CSTR(str));
504
+ return obj;
505
+ }
506
+
507
+ static VALUE
508
+ pgconn_getline(obj)
509
+ VALUE obj;
510
+ {
511
+ PGconn *conn = get_pgconn(obj);
512
+ VALUE str;
513
+ long size = BUFSIZ;
514
+ long bytes = 0;
515
+ int ret;
516
+
517
+ str = rb_tainted_str_new(0, size);
518
+
519
+ for (;;) {
520
+ ret = PQgetline(conn, RSTRING(str)->ptr + bytes, size - bytes);
521
+ switch (ret) {
522
+ case EOF:
523
+ return Qnil;
524
+ case 0:
525
+ return str;
526
+ case 1:
527
+ break;
528
+ }
529
+ bytes += BUFSIZ;
530
+ size += BUFSIZ;
531
+ rb_str_resize(str, size);
532
+ }
533
+ return Qnil;
534
+ }
535
+
536
+ static VALUE
537
+ pgconn_endcopy(obj)
538
+ VALUE obj;
539
+ {
540
+ if (PQendcopy(get_pgconn(obj)) == 1) {
541
+ rb_raise(rb_ePGError, "cannot complete copying");
542
+ }
543
+ return Qnil;
544
+ }
545
+
546
+ static VALUE
547
+ pgconn_notifies(obj)
548
+ VALUE obj;
549
+ {
550
+ PGnotify *notifies = PQnotifies(get_pgconn(obj));
551
+ return Qnil;
552
+ }
553
+
554
+ static VALUE
555
+ pgconn_host(obj)
556
+ VALUE obj;
557
+ {
558
+ char *host = PQhost(get_pgconn(obj));
559
+ if (!host) return Qnil;
560
+ return rb_tainted_str_new2(host);
561
+ }
562
+
563
+ static VALUE
564
+ pgconn_port(obj)
565
+ VALUE obj;
566
+ {
567
+ char* port = PQport(get_pgconn(obj));
568
+ return INT2NUM(atol(port));
569
+ }
570
+
571
+ static VALUE
572
+ pgconn_db(obj)
573
+ VALUE obj;
574
+ {
575
+ char *db = PQdb(get_pgconn(obj));
576
+ if (!db) return Qnil;
577
+ return rb_tainted_str_new2(db);
578
+ }
579
+
580
+ static VALUE
581
+ pgconn_options(obj)
582
+ VALUE obj;
583
+ {
584
+ char *options = PQoptions(get_pgconn(obj));
585
+ if (!options) return Qnil;
586
+ return rb_tainted_str_new2(options);
587
+ }
588
+
589
+ static VALUE
590
+ pgconn_tty(obj)
591
+ VALUE obj;
592
+ {
593
+ char *tty = PQtty(get_pgconn(obj));
594
+ if (!tty) return Qnil;
595
+ return rb_tainted_str_new2(tty);
596
+ }
597
+
598
+ static VALUE
599
+ pgconn_user(obj)
600
+ VALUE obj;
601
+ {
602
+ char *user = PQuser(get_pgconn(obj));
603
+ if (!user) return Qnil;
604
+ return rb_tainted_str_new2(user);
605
+ }
606
+
607
+ static VALUE
608
+ pgconn_status(obj)
609
+ VALUE obj;
610
+ {
611
+ int status = PQstatus(get_pgconn(obj));
612
+ return INT2NUM(status);
613
+ }
614
+
615
+ static VALUE
616
+ pgconn_error(obj)
617
+ VALUE obj;
618
+ {
619
+ char *error = PQerrorMessage(get_pgconn(obj));
620
+ if (!error) return Qnil;
621
+ return rb_tainted_str_new2(error);
622
+ }
623
+
624
+ static VALUE
625
+ pgconn_trace(obj, port)
626
+ VALUE obj, port;
627
+ {
628
+ OpenFile* fp;
629
+
630
+ Check_Type(port, T_FILE);
631
+ GetOpenFile(port, fp);
632
+
633
+ PQtrace(get_pgconn(obj), fp->f2?fp->f2:fp->f);
634
+
635
+ return obj;
636
+ }
637
+
638
+ static VALUE
639
+ pgconn_untrace(obj)
640
+ VALUE obj;
641
+ {
642
+ PQuntrace(get_pgconn(obj));
643
+ return obj;
644
+ }
645
+
646
+ #ifdef HAVE_PQSETCLIENTENCODING
647
+ static VALUE
648
+ pgconn_client_encoding(obj)
649
+ VALUE obj;
650
+ {
651
+ char *encoding = (char *)pg_encoding_to_char(PQclientEncoding(get_pgconn(obj)));
652
+ return rb_tainted_str_new2(encoding);
653
+ }
654
+
655
+ static VALUE
656
+ pgconn_set_client_encoding(obj, str)
657
+ VALUE obj, str;
658
+ {
659
+ Check_Type(str, T_STRING);
660
+ if ((PQsetClientEncoding(get_pgconn(obj), STR2CSTR(str))) == -1){
661
+ rb_raise(rb_ePGError, "invalid encoding name %s",str);
662
+ }
663
+ return Qnil;
664
+ }
665
+ #endif
666
+
667
+ static void
668
+ free_pgresult(ptr)
669
+ PGresult *ptr;
670
+ {
671
+ PQclear(ptr);
672
+ }
673
+
674
+ static VALUE
675
+ fetch_pgresult(result, tuple_index, field_index)
676
+ PGresult *result;
677
+ int tuple_index;
678
+ int field_index;
679
+ {
680
+ VALUE value;
681
+ if (PQgetisnull(result, tuple_index, field_index) != 1) {
682
+ char * valuestr = PQgetvalue(result, tuple_index, field_index);
683
+ value = rb_tainted_str_new2(valuestr);
684
+ } else {
685
+ value = Qnil;
686
+ }
687
+ return value;
688
+ }
689
+
690
+
691
+ static VALUE
692
+ pgresult_new(ptr)
693
+ PGresult *ptr;
694
+ {
695
+ return Data_Wrap_Struct(rb_cPGresult, 0, free_pgresult, ptr);
696
+ }
697
+
698
+ static VALUE
699
+ pgresult_status(obj)
700
+ VALUE obj;
701
+ {
702
+ int status;
703
+
704
+ status = PQresultStatus(get_pgresult(obj));
705
+ return INT2NUM(status);
706
+ }
707
+
708
+ static VALUE
709
+ pgresult_result(obj)
710
+ VALUE obj;
711
+ {
712
+ PGresult *result;
713
+ VALUE ary;
714
+ int nt, nf, i, j;
715
+
716
+ result = get_pgresult(obj);
717
+ nt = PQntuples(result);
718
+ nf = PQnfields(result);
719
+ ary = rb_ary_new2(nt);
720
+ for (i=0; i<nt; i++) {
721
+ VALUE row = rb_ary_new2(nf);
722
+ for (j=0; j<nf; j++) {
723
+ VALUE value = fetch_pgresult(result, i, j);
724
+ rb_ary_push(row, value);
725
+ }
726
+ rb_ary_push(ary, row);
727
+ };
728
+
729
+ return ary;
730
+ }
731
+
732
+ static VALUE
733
+ pgresult_each(obj)
734
+ VALUE obj;
735
+ {
736
+ PGresult *result;
737
+ int nt, nf, i, j;
738
+
739
+ result = get_pgresult(obj);
740
+ nt = PQntuples(result);
741
+ nf = PQnfields(result);
742
+ for (i=0; i<nt; i++) {
743
+ VALUE row = rb_ary_new2(nf);
744
+ for (j=0; j<nf; j++) {
745
+ VALUE value = fetch_pgresult(result, i, j);
746
+ rb_ary_push(row, value);
747
+ }
748
+ rb_yield(row);
749
+ };
750
+
751
+ return Qnil;
752
+ }
753
+
754
+ static VALUE
755
+ pgresult_aref(argc, argv, obj)
756
+ int argc;
757
+ VALUE *argv;
758
+ VALUE obj;
759
+ {
760
+ PGresult *result;
761
+ VALUE a1, a2, val;
762
+ int i, j, nf, nt;
763
+
764
+ result = get_pgresult(obj);
765
+ nt = PQntuples(result);
766
+ nf = PQnfields(result);
767
+ switch (rb_scan_args(argc, argv, "11", &a1, &a2)) {
768
+ case 1:
769
+ i = NUM2INT(a1);
770
+ if( i >= nt ) return Qnil;
771
+
772
+ val = rb_ary_new();
773
+ for (j=0; j<nf; j++) {
774
+ VALUE value = fetch_pgresult(result, i, j);
775
+ rb_ary_push(val, value);
776
+ }
777
+ return val;
778
+
779
+ case 2:
780
+ i = NUM2INT(a1);
781
+ if( i >= nt ) return Qnil;
782
+ j = NUM2INT(a2);
783
+ if( j >= nf ) return Qnil;
784
+ return fetch_pgresult(result, i, j);
785
+
786
+ default:
787
+ return Qnil; /* not reached */
788
+ }
789
+ }
790
+
791
+ static VALUE
792
+ pgresult_fields(obj)
793
+ VALUE obj;
794
+ {
795
+ PGresult *result;
796
+ VALUE ary;
797
+ int n, i;
798
+
799
+ result = get_pgresult(obj);
800
+ n = PQnfields(result);
801
+ ary = rb_ary_new2(n);
802
+ for (i=0;i<n;i++) {
803
+ rb_ary_push(ary, rb_tainted_str_new2(PQfname(result, i)));
804
+ }
805
+ return ary;
806
+ }
807
+
808
+ static VALUE
809
+ pgresult_num_tuples(obj)
810
+ VALUE obj;
811
+ {
812
+ int n;
813
+
814
+ n = PQntuples(get_pgresult(obj));
815
+ return INT2NUM(n);
816
+ }
817
+
818
+ static VALUE
819
+ pgresult_num_fields(obj)
820
+ VALUE obj;
821
+ {
822
+ int n;
823
+
824
+ n = PQnfields(get_pgresult(obj));
825
+ return INT2NUM(n);
826
+ }
827
+
828
+ static VALUE
829
+ pgresult_fieldname(obj, index)
830
+ VALUE obj, index;
831
+ {
832
+ PGresult *result;
833
+ int i = NUM2INT(index);
834
+ char *name;
835
+
836
+ result = get_pgresult(obj);
837
+ if (i < 0 || i >= PQnfields(result)) {
838
+ rb_raise(rb_eArgError,"invalid field number %d", i);
839
+ }
840
+ name = PQfname(result, i);
841
+ return rb_tainted_str_new2(name);
842
+ }
843
+
844
+ static VALUE
845
+ pgresult_fieldnum(obj, name)
846
+ VALUE obj, name;
847
+ {
848
+ int n;
849
+
850
+ Check_Type(name, T_STRING);
851
+
852
+ n = PQfnumber(get_pgresult(obj), STR2CSTR(name));
853
+ if (n == -1) {
854
+ rb_raise(rb_eArgError,"Unknown field: %s", STR2CSTR(name));
855
+ }
856
+ return INT2NUM(n);
857
+ }
858
+
859
+ static VALUE
860
+ pgresult_type(obj, index)
861
+ VALUE obj, index;
862
+ {
863
+ PGresult *result;
864
+ int i = NUM2INT(index);
865
+ int type;
866
+
867
+ result = get_pgresult(obj);
868
+ if (i < 0 || i >= PQnfields(result)) {
869
+ rb_raise(rb_eArgError,"invalid field number %d", i);
870
+ }
871
+ type = PQftype(result, i);
872
+ return INT2NUM(type);
873
+ }
874
+
875
+ static VALUE
876
+ pgresult_size(obj, index)
877
+ VALUE obj, index;
878
+ {
879
+ PGresult *result;
880
+ int i = NUM2INT(index);
881
+ int size;
882
+
883
+ result = get_pgresult(obj);
884
+ if (i < 0 || i >= PQnfields(result)) {
885
+ rb_raise(rb_eArgError,"invalid field number %d", i);
886
+ }
887
+ size = PQfsize(result, i);
888
+ return INT2NUM(size);
889
+ }
890
+
891
+ static VALUE
892
+ pgresult_getvalue(obj, tup_num, field_num)
893
+ VALUE obj, tup_num, field_num;
894
+ {
895
+ PGresult *result;
896
+ int i = NUM2INT(tup_num);
897
+ int j = NUM2INT(field_num);
898
+
899
+ result = get_pgresult(obj);
900
+ if (i < 0 || i >= PQntuples(result)) {
901
+ rb_raise(rb_eArgError,"invalid tuple number %d", i);
902
+ }
903
+ if (j < 0 || j >= PQnfields(result)) {
904
+ rb_raise(rb_eArgError,"invalid field number %d", j);
905
+ }
906
+
907
+ return fetch_pgresult(result, i, j);
908
+ }
909
+
910
+ static VALUE
911
+ pgresult_getlength(obj, tup_num, field_num)
912
+ VALUE obj, tup_num, field_num;
913
+ {
914
+ PGresult *result;
915
+ int i = NUM2INT(tup_num);
916
+ int j = NUM2INT(field_num);
917
+
918
+ result = get_pgresult(obj);
919
+ if (i < 0 || i >= PQntuples(result)) {
920
+ rb_raise(rb_eArgError,"invalid tuple number %d", i);
921
+ }
922
+ if (j < 0 || j >= PQnfields(result)) {
923
+ rb_raise(rb_eArgError,"invalid field number %d", j);
924
+ }
925
+ return INT2FIX(PQgetlength(result, i, j));
926
+ }
927
+
928
+ static VALUE
929
+ pgresult_getisnull(obj, tup_num, field_num)
930
+ VALUE obj, tup_num, field_num;
931
+ {
932
+ PGresult *result;
933
+ int i = NUM2INT(tup_num);
934
+ int j = NUM2INT(field_num);
935
+
936
+ result = get_pgresult(obj);
937
+ if (i < 0 || i >= PQntuples(result)) {
938
+ rb_raise(rb_eArgError,"invalid tuple number %d", i);
939
+ }
940
+ if (j < 0 || j >= PQnfields(result)) {
941
+ rb_raise(rb_eArgError,"invalid field number %d", j);
942
+ }
943
+ return PQgetisnull(result, i, j) ? Qtrue : Qfalse;
944
+ }
945
+
946
+ static VALUE
947
+ pgresult_print(obj, file, opt)
948
+ VALUE obj, file, opt;
949
+ {
950
+ VALUE value;
951
+ ID mem;
952
+ OpenFile* fp;
953
+ PQprintOpt po;
954
+
955
+ Check_Type(file, T_FILE);
956
+ Check_Type(opt, T_STRUCT);
957
+ GetOpenFile(file, fp);
958
+
959
+ memset(&po, 0, sizeof(po));
960
+
961
+ mem = rb_intern("header");
962
+ value = rb_struct_getmember(opt, mem);
963
+ po.header = value == Qtrue ? 1 : 0;
964
+
965
+ mem = rb_intern("align");
966
+ value = rb_struct_getmember(opt, mem);
967
+ po.align = value == Qtrue ? 1 : 0;
968
+
969
+ mem = rb_intern("standard");
970
+ value = rb_struct_getmember(opt, mem);
971
+ po.standard = value == Qtrue ? 1 : 0;
972
+
973
+ mem = rb_intern("html3");
974
+ value = rb_struct_getmember(opt, mem);
975
+ po.html3 = value == Qtrue ? 1 : 0;
976
+
977
+ mem = rb_intern("expanded");
978
+ value = rb_struct_getmember(opt, mem);
979
+ po.expanded = value == Qtrue ? 1 : 0;
980
+
981
+ mem = rb_intern("pager");
982
+ value = rb_struct_getmember(opt, mem);
983
+ po.pager = value == Qtrue ? 1 : 0;
984
+
985
+ mem = rb_intern("fieldSep");
986
+ value = rb_struct_getmember(opt, mem);
987
+ if (!NIL_P(value)) {
988
+ Check_Type(value, T_STRING);
989
+ po.fieldSep = STR2CSTR(value);
990
+ }
991
+
992
+ mem = rb_intern("tableOpt");
993
+ value = rb_struct_getmember(opt, mem);
994
+ if (!NIL_P(value)) {
995
+ Check_Type(value, T_STRING);
996
+ po.tableOpt = STR2CSTR(value);
997
+ }
998
+
999
+ mem = rb_intern("caption");
1000
+ value = rb_struct_getmember(opt, mem);
1001
+ if (!NIL_P(value)) {
1002
+ Check_Type(value, T_STRING);
1003
+ po.caption = STR2CSTR(value);
1004
+ }
1005
+
1006
+ PQprint(fp->f2?fp->f2:fp->f, get_pgresult(obj), &po);
1007
+ return obj;
1008
+ }
1009
+
1010
+ static VALUE
1011
+ pgresult_cmdtuples(obj)
1012
+ VALUE obj;
1013
+ {
1014
+ long n;
1015
+ n = strtol(PQcmdTuples(get_pgresult(obj)),NULL, 10);
1016
+ return INT2NUM(n);
1017
+ }
1018
+
1019
+ static VALUE
1020
+ pgresult_cmdstatus(obj)
1021
+ VALUE obj;
1022
+ {
1023
+ return rb_tainted_str_new2(PQcmdStatus(get_pgresult(obj)));
1024
+ }
1025
+
1026
+ static VALUE
1027
+ pgresult_clear(obj)
1028
+ VALUE obj;
1029
+ {
1030
+ PQclear(get_pgresult(obj));
1031
+ DATA_PTR(obj) = 0;
1032
+
1033
+ return Qnil;
1034
+ }
1035
+
1036
+ static VALUE
1037
+ pgresult_result_with_clear(obj)
1038
+ VALUE obj;
1039
+ {
1040
+ VALUE tuples = pgresult_result(obj);
1041
+ pgresult_clear(obj);
1042
+ return tuples;
1043
+ }
1044
+
1045
+ /* Large Object support */
1046
+ static PGlarge*
1047
+ get_pglarge(obj)
1048
+ VALUE obj;
1049
+ {
1050
+ PGlarge *pglarge;
1051
+ Data_Get_Struct(obj, PGlarge, pglarge);
1052
+ if (pglarge == 0) rb_raise(rb_ePGError, "invalid large object");
1053
+ return pglarge;
1054
+ }
1055
+
1056
+ static VALUE
1057
+ pgconn_loimport(obj, filename)
1058
+ VALUE obj, filename;
1059
+ {
1060
+ Oid lo_oid;
1061
+
1062
+ PGconn *conn = get_pgconn(obj);
1063
+
1064
+ Check_Type(filename, T_STRING);
1065
+
1066
+ lo_oid = lo_import(conn, STR2CSTR(filename));
1067
+ if (lo_oid == 0) {
1068
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
1069
+ }
1070
+ return pglarge_new(conn, lo_oid, -1);
1071
+ }
1072
+
1073
+ static VALUE
1074
+ pgconn_loexport(obj, lo_oid,filename)
1075
+ VALUE obj, lo_oid, filename;
1076
+ {
1077
+ PGconn *conn = get_pgconn(obj);
1078
+ int oid;
1079
+ Check_Type(filename, T_STRING);
1080
+
1081
+ oid = NUM2INT(lo_oid);
1082
+ if (oid < 0) {
1083
+ rb_raise(rb_ePGError, "invalid large object oid %d",oid);
1084
+ }
1085
+
1086
+ if (!lo_export(conn, oid, STR2CSTR(filename))) {
1087
+ rb_raise(rb_ePGError, PQerrorMessage(conn));
1088
+ }
1089
+ return Qnil;
1090
+ }
1091
+
1092
+ static VALUE
1093
+ pgconn_locreate(argc, argv, obj)
1094
+ int argc;
1095
+ VALUE *argv;
1096
+ VALUE obj;
1097
+ {
1098
+ Oid lo_oid;
1099
+ int mode;
1100
+ VALUE nmode;
1101
+ PGconn *conn;
1102
+
1103
+ if (rb_scan_args(argc, argv, "01", &nmode) == 0) {
1104
+ mode = INV_READ;
1105
+ }
1106
+ else {
1107
+ mode = FIX2INT(nmode);
1108
+ }
1109
+
1110
+ conn = get_pgconn(obj);
1111
+ lo_oid = lo_creat(conn, mode);
1112
+ if (lo_oid == 0){
1113
+ rb_raise(rb_ePGError, "can't creat large object");
1114
+ }
1115
+
1116
+ return pglarge_new(conn, lo_oid, -1);
1117
+ }
1118
+
1119
+ static VALUE
1120
+ pgconn_loopen(argc, argv, obj)
1121
+ int argc;
1122
+ VALUE *argv;
1123
+ VALUE obj;
1124
+ {
1125
+ Oid lo_oid;
1126
+ int fd, mode;
1127
+ VALUE nmode, objid;
1128
+ PGconn *conn = get_pgconn(obj);
1129
+
1130
+ switch (rb_scan_args(argc, argv, "02", &objid, &nmode)) {
1131
+ case 1:
1132
+ lo_oid = NUM2INT(objid);
1133
+ mode = INV_READ;
1134
+ break;
1135
+ case 2:
1136
+ lo_oid = NUM2INT(objid);
1137
+ mode = FIX2INT(nmode);
1138
+ break;
1139
+ default:
1140
+ mode = INV_READ;
1141
+ lo_oid = lo_creat(conn, mode);
1142
+ if (lo_oid == 0){
1143
+ rb_raise(rb_ePGError, "can't creat large object");
1144
+ }
1145
+ }
1146
+ if((fd = lo_open(conn, lo_oid, mode)) < 0) {
1147
+ rb_raise(rb_ePGError, "can't open large object");
1148
+ }
1149
+ return pglarge_new(conn, lo_oid, fd);
1150
+ }
1151
+
1152
+ static VALUE
1153
+ pgconn_lounlink(obj, lo_oid)
1154
+ VALUE obj, lo_oid;
1155
+ {
1156
+ PGconn *conn;
1157
+ int oid = NUM2INT(lo_oid);
1158
+ int result;
1159
+
1160
+ if (oid < 0){
1161
+ rb_raise(rb_ePGError, "invalid oid %d",oid);
1162
+ }
1163
+ conn = get_pgconn(obj);
1164
+ result = lo_unlink(conn,oid);
1165
+
1166
+ return Qnil;
1167
+ }
1168
+
1169
+ static void
1170
+ free_pglarge(ptr)
1171
+ PGlarge *ptr;
1172
+ {
1173
+ if ((ptr->lo_fd) > 0) {
1174
+ lo_close(ptr->pgconn,ptr->lo_fd);
1175
+ }
1176
+ free(ptr);
1177
+ }
1178
+
1179
+ static VALUE
1180
+ pglarge_new(conn, lo_oid ,lo_fd)
1181
+ PGconn *conn;
1182
+ Oid lo_oid;
1183
+ int lo_fd;
1184
+ {
1185
+ VALUE obj;
1186
+ PGlarge *pglarge;
1187
+
1188
+ obj = Data_Make_Struct(rb_cPGlarge, PGlarge, 0, free_pglarge, pglarge);
1189
+ pglarge->pgconn = conn;
1190
+ pglarge->lo_oid = lo_oid;
1191
+ pglarge->lo_fd = lo_fd;
1192
+
1193
+ return obj;
1194
+ }
1195
+
1196
+ static VALUE
1197
+ pglarge_oid(obj)
1198
+ VALUE obj;
1199
+ {
1200
+ PGlarge *pglarge = get_pglarge(obj);
1201
+
1202
+ return INT2NUM(pglarge->lo_oid);
1203
+ }
1204
+
1205
+ static VALUE
1206
+ pglarge_open(argc, argv, obj)
1207
+ int argc;
1208
+ VALUE *argv;
1209
+ VALUE obj;
1210
+ {
1211
+ PGlarge *pglarge = get_pglarge(obj);
1212
+ VALUE nmode;
1213
+ int fd;
1214
+ int mode;
1215
+
1216
+ if (rb_scan_args(argc, argv, "01", &nmode) == 0) {
1217
+ mode = INV_READ;
1218
+ }
1219
+ else {
1220
+ mode = FIX2INT(nmode);
1221
+ }
1222
+
1223
+ if((fd = lo_open(pglarge->pgconn, pglarge->lo_oid, mode)) < 0) {
1224
+ rb_raise(rb_ePGError, "can't open large object");
1225
+ }
1226
+ pglarge->lo_fd = fd;
1227
+
1228
+ return INT2FIX(pglarge->lo_fd);
1229
+ }
1230
+
1231
+ static VALUE
1232
+ pglarge_close(obj)
1233
+ VALUE obj;
1234
+ {
1235
+ PGlarge *pglarge = get_pglarge(obj);
1236
+
1237
+ if((lo_close(pglarge->pgconn, pglarge->lo_fd)) < 0) {
1238
+ rb_raise(rb_ePGError, "can't closed large object");
1239
+ }
1240
+ DATA_PTR(obj) = 0;
1241
+
1242
+ return Qnil;
1243
+ }
1244
+
1245
+ static VALUE
1246
+ pglarge_tell(obj)
1247
+ VALUE obj;
1248
+ {
1249
+ int start;
1250
+ PGlarge *pglarge = get_pglarge(obj);
1251
+
1252
+ if ((start = lo_tell(pglarge->pgconn,pglarge->lo_fd)) == -1) {
1253
+ rb_raise(rb_ePGError, "error while getting position");
1254
+ }
1255
+ return INT2NUM(start);
1256
+ }
1257
+
1258
+ static VALUE
1259
+ loread_all(obj)
1260
+ VALUE obj;
1261
+ {
1262
+ PGlarge *pglarge = get_pglarge(obj);
1263
+ VALUE str;
1264
+ long siz = BUFSIZ;
1265
+ long bytes = 0;
1266
+ int n;
1267
+
1268
+ str = rb_tainted_str_new(0,siz);
1269
+ for (;;) {
1270
+ n = lo_read(pglarge->pgconn, pglarge->lo_fd, RSTRING(str)->ptr + bytes,siz - bytes);
1271
+ if (n == 0 && bytes == 0) return Qnil;
1272
+ bytes += n;
1273
+ if (bytes < siz ) break;
1274
+ siz += BUFSIZ;
1275
+ rb_str_resize(str,siz);
1276
+ }
1277
+ if (bytes == 0) return rb_tainted_str_new(0,0);
1278
+ if (bytes != siz) rb_str_resize(str, bytes);
1279
+ return str;
1280
+ }
1281
+
1282
+ static VALUE
1283
+ pglarge_read(argc, argv, obj)
1284
+ int argc;
1285
+ VALUE *argv;
1286
+ VALUE obj;
1287
+ {
1288
+ int len;
1289
+ PGlarge *pglarge = get_pglarge(obj);
1290
+ VALUE str;
1291
+ VALUE length;
1292
+
1293
+ rb_scan_args(argc, argv, "01", &length);
1294
+ if (NIL_P(length)) {
1295
+ return loread_all(obj);
1296
+ }
1297
+
1298
+ len = NUM2INT(length);
1299
+ if (len < 0){
1300
+ rb_raise(rb_ePGError,"nagative length %d given", len);
1301
+ }
1302
+ str = rb_tainted_str_new(0,len);
1303
+
1304
+ if((len = lo_read(pglarge->pgconn, pglarge->lo_fd, STR2CSTR(str), len)) < 0) {
1305
+ rb_raise(rb_ePGError, "error while reading");
1306
+ }
1307
+ if (len == 0) return Qnil;
1308
+ RSTRING(str)->len = len;
1309
+ return str;
1310
+ }
1311
+
1312
+ static VALUE
1313
+ pglarge_write(obj, buffer)
1314
+ VALUE obj, buffer;
1315
+ {
1316
+ int n;
1317
+ PGlarge *pglarge = get_pglarge(obj);
1318
+
1319
+ Check_Type(buffer, T_STRING);
1320
+
1321
+ if( RSTRING(buffer)->len < 0) {
1322
+ rb_raise(rb_ePGError, "write buffer zero string");
1323
+ }
1324
+ if((n = lo_write(pglarge->pgconn, pglarge->lo_fd, STR2CSTR(buffer), RSTRING(buffer)->len)) == -1) {
1325
+ rb_raise(rb_ePGError, "buffer truncated during write");
1326
+ }
1327
+
1328
+ return INT2FIX(n);
1329
+ }
1330
+
1331
+ static VALUE
1332
+ pglarge_seek(obj, offset, whence)
1333
+ VALUE obj, offset, whence;
1334
+ {
1335
+ PGlarge *pglarge = get_pglarge(obj);
1336
+ int ret;
1337
+
1338
+ if((ret = lo_lseek(pglarge->pgconn, pglarge->lo_fd, NUM2INT(offset), NUM2INT(whence))) == -1) {
1339
+ rb_raise(rb_ePGError, "error while moving cursor");
1340
+ }
1341
+
1342
+ return INT2NUM(ret);
1343
+ }
1344
+
1345
+ static VALUE
1346
+ pglarge_size(obj)
1347
+ VALUE obj;
1348
+ {
1349
+ PGlarge *pglarge = get_pglarge(obj);
1350
+ int start, end;
1351
+
1352
+ if ((start = lo_tell(pglarge->pgconn,pglarge->lo_fd)) == -1) {
1353
+ rb_raise(rb_ePGError, "error while getting position");
1354
+ }
1355
+
1356
+ if ((end = lo_lseek(pglarge->pgconn, pglarge->lo_fd, 0, SEEK_END)) == -1) {
1357
+ rb_raise(rb_ePGError, "error while moving cursor");
1358
+ }
1359
+
1360
+ if ((start = lo_lseek(pglarge->pgconn, pglarge->lo_fd,start, SEEK_SET)) == -1) {
1361
+ rb_raise(rb_ePGError, "error while moving back to posiion");
1362
+ }
1363
+
1364
+ return INT2NUM(end);
1365
+ }
1366
+
1367
+ static VALUE
1368
+ pglarge_export(obj, filename)
1369
+ VALUE obj, filename;
1370
+ {
1371
+ PGlarge *pglarge = get_pglarge(obj);
1372
+
1373
+ Check_Type(filename, T_STRING);
1374
+
1375
+ if (!lo_export(pglarge->pgconn, pglarge->lo_oid, STR2CSTR(filename))){
1376
+ rb_raise(rb_ePGError, PQerrorMessage(pglarge->pgconn));
1377
+ }
1378
+
1379
+ return Qnil;
1380
+ }
1381
+
1382
+ static VALUE
1383
+ pglarge_unlink(obj)
1384
+ VALUE obj;
1385
+ {
1386
+ PGlarge *pglarge = get_pglarge(obj);
1387
+
1388
+ if (!lo_unlink(pglarge->pgconn,pglarge->lo_oid)) {
1389
+ rb_raise(rb_ePGError, PQerrorMessage(pglarge->pgconn));
1390
+ }
1391
+ DATA_PTR(obj) = 0;
1392
+
1393
+ return Qnil;
1394
+ }
1395
+ /* Large Object support */
1396
+
1397
+ void
1398
+ Init_postgres()
1399
+ {
1400
+ pg_gsub_bang_id = rb_intern("gsub!");
1401
+ pg_escape_regex = rb_reg_new("([\\t\\n\\\\])",10,0);
1402
+ rb_global_variable(&pg_escape_regex);
1403
+ pg_escape_str = rb_str_new("\\\\\\1",4);
1404
+ rb_global_variable(&pg_escape_str);
1405
+
1406
+ rb_ePGError = rb_define_class("PGError", rb_eStandardError);
1407
+
1408
+ rb_cPGconn = rb_define_class("PGconn", rb_cObject);
1409
+ rb_define_singleton_method(rb_cPGconn, "new", pgconn_s_new, -1);
1410
+ rb_define_singleton_method(rb_cPGconn, "connect", pgconn_s_connect, -1);
1411
+ rb_define_singleton_method(rb_cPGconn, "setdb", pgconn_s_connect, -1);
1412
+ rb_define_singleton_method(rb_cPGconn, "setdblogin", pgconn_s_connect, -1);
1413
+ #ifdef HAVE_PQESCAPESTRING
1414
+ rb_define_singleton_method(rb_cPGconn, "escape", pgconn_s_escape, 1);
1415
+ rb_define_singleton_method(rb_cPGconn, "quote", pgconn_s_quote, 1);
1416
+ rb_define_singleton_method(rb_cPGconn, "escape_bytea", pgconn_s_escape_bytea, 1);
1417
+ #endif
1418
+ rb_define_const(rb_cPGconn, "CONNECTION_OK", INT2FIX(CONNECTION_OK));
1419
+ rb_define_const(rb_cPGconn, "CONNECTION_BAD", INT2FIX(CONNECTION_BAD));
1420
+
1421
+ rb_define_method(rb_cPGconn, "initialize", pgconn_init, -1);
1422
+ rb_define_method(rb_cPGconn, "db", pgconn_db, 0);
1423
+ rb_define_method(rb_cPGconn, "host", pgconn_host, 0);
1424
+ rb_define_method(rb_cPGconn, "options", pgconn_options, 0);
1425
+ rb_define_method(rb_cPGconn, "port", pgconn_port, 0);
1426
+ rb_define_method(rb_cPGconn, "tty", pgconn_tty, 0);
1427
+ rb_define_method(rb_cPGconn, "status", pgconn_status, 0);
1428
+ rb_define_method(rb_cPGconn, "error", pgconn_error, 0);
1429
+ rb_define_method(rb_cPGconn, "close", pgconn_close, 0);
1430
+ rb_define_alias(rb_cPGconn, "finish", "close");
1431
+ rb_define_method(rb_cPGconn, "reset", pgconn_reset, 0);
1432
+ rb_define_method(rb_cPGconn, "user", pgconn_user, 0);
1433
+ rb_define_method(rb_cPGconn, "trace", pgconn_trace, 1);
1434
+ rb_define_method(rb_cPGconn, "untrace", pgconn_untrace, 0);
1435
+
1436
+ rb_define_method(rb_cPGconn, "exec", pgconn_exec, 1);
1437
+ rb_define_method(rb_cPGconn, "query", pgconn_query, 1);
1438
+ rb_define_method(rb_cPGconn, "async_exec", pgconn_async_exec, 1);
1439
+ rb_define_method(rb_cPGconn, "async_query", pgconn_async_query, 1);
1440
+ rb_define_method(rb_cPGconn, "get_notify", pgconn_get_notify, 0);
1441
+ rb_define_method(rb_cPGconn, "insert_table", pgconn_insert_table, 2);
1442
+ rb_define_method(rb_cPGconn, "putline", pgconn_putline, 1);
1443
+ rb_define_method(rb_cPGconn, "getline", pgconn_getline, 0);
1444
+ rb_define_method(rb_cPGconn, "endcopy", pgconn_endcopy, 0);
1445
+ rb_define_method(rb_cPGconn, "notifies", pgconn_notifies, 0);
1446
+
1447
+ #ifdef HAVE_PQSETCLIENTENCODING
1448
+ rb_define_method(rb_cPGconn, "client_encoding",pgconn_client_encoding, 0);
1449
+ rb_define_method(rb_cPGconn, "set_client_encoding",pgconn_set_client_encoding, 1);
1450
+ #endif
1451
+
1452
+ /* Large Object support */
1453
+ rb_define_method(rb_cPGconn, "lo_import", pgconn_loimport, 1);
1454
+ rb_define_alias(rb_cPGconn, "loimport", "lo_import");
1455
+ rb_define_method(rb_cPGconn, "lo_create", pgconn_locreate, -1);
1456
+ rb_define_alias(rb_cPGconn, "locreate", "lo_create");
1457
+ rb_define_method(rb_cPGconn, "lo_open", pgconn_loopen, -1);
1458
+ rb_define_alias(rb_cPGconn, "loopen", "lo_open");
1459
+ rb_define_method(rb_cPGconn, "lo_export", pgconn_loexport, 2);
1460
+ rb_define_alias(rb_cPGconn, "loexport", "lo_export");
1461
+ rb_define_method(rb_cPGconn, "lo_unlink", pgconn_lounlink, 1);
1462
+ rb_define_alias(rb_cPGconn, "lounlink", "lo_unlink");
1463
+
1464
+ rb_cPGlarge = rb_define_class("PGlarge", rb_cObject);
1465
+ rb_define_method(rb_cPGlarge, "oid",pglarge_oid, 0);
1466
+ rb_define_method(rb_cPGlarge, "open",pglarge_open, -1);
1467
+ rb_define_method(rb_cPGlarge, "close",pglarge_close, 0);
1468
+ rb_define_method(rb_cPGlarge, "read",pglarge_read, -1);
1469
+ rb_define_method(rb_cPGlarge, "write",pglarge_write, 1);
1470
+ rb_define_method(rb_cPGlarge, "seek",pglarge_seek, 2);
1471
+ rb_define_method(rb_cPGlarge, "tell",pglarge_tell, 0);
1472
+ rb_define_method(rb_cPGlarge, "size",pglarge_size, 0);
1473
+ rb_define_method(rb_cPGlarge, "export",pglarge_export, 1);
1474
+ rb_define_method(rb_cPGlarge, "unlink",pglarge_unlink, 0);
1475
+
1476
+ rb_define_const(rb_cPGlarge, "INV_WRITE", INT2FIX(INV_WRITE));
1477
+ rb_define_const(rb_cPGlarge, "INV_READ", INT2FIX(INV_READ));
1478
+ rb_define_const(rb_cPGlarge, "SEEK_SET", INT2FIX(SEEK_SET));
1479
+ rb_define_const(rb_cPGlarge, "SEEK_CUR", INT2FIX(SEEK_CUR));
1480
+ rb_define_const(rb_cPGlarge, "SEEK_END", INT2FIX(SEEK_END));
1481
+ /* Large Object support */
1482
+
1483
+ rb_cPGresult = rb_define_class("PGresult", rb_cObject);
1484
+ rb_include_module(rb_cPGresult, rb_mEnumerable);
1485
+
1486
+ rb_define_const(rb_cPGresult, "EMPTY_QUERY", INT2FIX(PGRES_EMPTY_QUERY));
1487
+ rb_define_const(rb_cPGresult, "COMMAND_OK", INT2FIX(PGRES_COMMAND_OK));
1488
+ rb_define_const(rb_cPGresult, "TUPLES_OK", INT2FIX(PGRES_TUPLES_OK));
1489
+ rb_define_const(rb_cPGresult, "COPY_OUT", INT2FIX(PGRES_COPY_OUT));
1490
+ rb_define_const(rb_cPGresult, "COPY_IN", INT2FIX(PGRES_COPY_IN));
1491
+ rb_define_const(rb_cPGresult, "BAD_RESPONSE", INT2FIX(PGRES_BAD_RESPONSE));
1492
+ rb_define_const(rb_cPGresult, "NONFATAL_ERROR",INT2FIX(PGRES_NONFATAL_ERROR));
1493
+ rb_define_const(rb_cPGresult, "FATAL_ERROR", INT2FIX(PGRES_FATAL_ERROR));
1494
+
1495
+ rb_define_method(rb_cPGresult, "status", pgresult_status, 0);
1496
+ rb_define_method(rb_cPGresult, "result", pgresult_result, 0);
1497
+ rb_define_method(rb_cPGresult, "each", pgresult_each, 0);
1498
+ rb_define_method(rb_cPGresult, "[]", pgresult_aref, -1);
1499
+ rb_define_method(rb_cPGresult, "fields", pgresult_fields, 0);
1500
+ rb_define_method(rb_cPGresult, "num_tuples", pgresult_num_tuples, 0);
1501
+ rb_define_method(rb_cPGresult, "num_fields", pgresult_num_fields, 0);
1502
+ rb_define_method(rb_cPGresult, "fieldname", pgresult_fieldname, 1);
1503
+ rb_define_method(rb_cPGresult, "fieldnum", pgresult_fieldnum, 1);
1504
+ rb_define_method(rb_cPGresult, "type", pgresult_type, 1);
1505
+ rb_define_method(rb_cPGresult, "size", pgresult_size, 1);
1506
+ rb_define_method(rb_cPGresult, "getvalue", pgresult_getvalue, 2);
1507
+ rb_define_method(rb_cPGresult, "getlength", pgresult_getlength, 2);
1508
+ rb_define_method(rb_cPGresult, "getisnull", pgresult_getisnull, 2);
1509
+ rb_define_method(rb_cPGresult, "cmdtuples", pgresult_cmdtuples, 0);
1510
+ rb_define_method(rb_cPGresult, "cmdstatus", pgresult_cmdstatus, 0);
1511
+ rb_define_method(rb_cPGresult, "print", pgresult_print, 2);
1512
+ rb_define_method(rb_cPGresult, "clear", pgresult_clear, 0);
1513
+ }