postgres 0.7.1

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