File Coverage

blib/lib/Net/FTPServer/DBeg1/IOBlob.pm
Criterion Covered Total %
statement 12 59 20.3
branch 0 8 0.0
condition 0 11 0.0
subroutine 4 13 30.7
pod 7 8 87.5
total 23 99 23.2


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             # Net::FTPServer A Perl FTP Server
4             # Copyright (C) 2000 Bibliotech Ltd., Unit 2-3, 50 Carnwath Road,
5             # London, SW6 3EG, United Kingdom.
6             #
7             # This program is free software; you can redistribute it and/or modify
8             # it under the terms of the GNU General Public License as published by
9             # the Free Software Foundation; either version 2 of the License, or
10             # (at your option) any later version.
11             #
12             # This program is distributed in the hope that it will be useful,
13             # but WITHOUT ANY WARRANTY; without even the implied warranty of
14             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             # GNU General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License
18             # along with this program; if not, write to the Free Software
19             # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20              
21             =pod
22              
23             =head1 NAME
24              
25             Net::FTPServer::DBeg1::IOBlob - The example DB FTP server personality
26              
27             =head1 SYNOPSIS
28              
29             use Net::FTPServer::DBeg1::IOBlob;
30              
31             =head1 METHODS
32              
33             =cut
34              
35             package Net::FTPServer::DBeg1::IOBlob;
36              
37 1     1   15957 use strict;
  1         3  
  1         29  
38              
39 1     1   5 use vars qw($VERSION);
  1         2  
  1         77  
40             ( $VERSION ) = '$Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/;
41              
42 1     1   6 use DBI;
  1         2  
  1         54  
43 1     1   16 use Carp qw(confess croak);
  1         3  
  1         507  
44              
45             =pod
46              
47             =over 4
48              
49             =item $io = Net::FTPServer::DBeg1::IOBlob ('r', $dbh, $blob_id);
50              
51             =item $io = Net::FTPServer::DBeg1::IOBlob ('w', $dbh, $blob_id);
52              
53             Create an IO handle for reading or writing a PostgreSQL blob.
54              
55             =cut
56              
57             sub new
58             {
59 0     0 0   my $class = shift;
60 0           my $mode = shift;
61 0           my $dbh = shift;
62 0           my $blob_id = shift;
63              
64             # XXX For some reason PostgreSQL (6.4) fails when you call lo_open
65             # the first time. But if you retry a second time it succeeds. Therefore
66             # there is this hack. [RWMJ]
67              
68 0           my $blob_fd;
69              
70 0   0       for (my $retries = 0; !$blob_fd && $retries < 3; ++$retries)
71             {
72             $blob_fd = $dbh->func ($blob_id,
73             $mode eq 'r' ? $dbh->{pg_INV_READ} : $dbh->{pg_INV_WRITE},
74 0 0         'lo_open');
75             }
76              
77 0 0         die "failed to open blob $blob_id: ", $dbh->errstr
78             unless $blob_fd;
79              
80 0           my $self = {
81             mode => $mode,
82             dbh => $dbh,
83             blob_id => $blob_id,
84             blob_fd => $blob_fd
85             };
86 0           bless $self, $class;
87              
88 0           return $self;
89             }
90              
91             =item $io->getc ();
92              
93             Read 1 byte from the buffer and return it
94              
95             =cut
96              
97             sub getc
98             {
99 0     0 1   my $self = shift;
100 0           my $buffer;
101 0 0         if (defined $self->read ($buffer, 1)) {
102 0           return $buffer;
103             } else {
104 0           return undef;
105             }
106             }
107              
108             =item $io->read ($buffer, $nbytes, [$offset]);
109              
110             =item $io->sysread ($buffer, $nbytes, [$offset]);
111              
112             Read C<$nbytes> from the handle and place them in C<$buffer>
113             at offset C<$offset>.
114              
115             =cut
116              
117             sub read
118             {
119 0     0 1   my $self = shift;
120 0           my $nbytes = $_[1];
121 0   0       my $offset = $_[2] || 0;
122              
123 0           $self->{dbh}->func ($self->{blob_fd}, substr ($_[0], $offset), $nbytes, 'lo_read');
124              
125 0           return $nbytes;
126             }
127              
128             sub sysread
129             {
130 0     0 1   my $self = shift;
131 0           my $nbytes = $_[1];
132 0   0       my $offset = $_[2] || 0;
133              
134 0           $self->{dbh}->func ($self->{blob_fd}, substr ($_[0], $offset), $nbytes, 'lo_read');
135              
136 0           return $nbytes;
137             }
138              
139             =item $io->write ($buffer, $nbytes, [$offset]);
140              
141             =item $io->syswrite ($buffer, $nbytes, [$offset]);
142              
143             Write C<$nbytes> to the handle from C<$buffer> offset C<$offset>.
144              
145             =cut
146              
147             sub write
148             {
149 0     0 1   my $self = shift;
150 0           my $nbytes = $_[1];
151 0   0       my $offset = $_[2] || 0;
152              
153 0           my $buffer = substr $_[0], $offset, $nbytes;
154              
155 0           $self->{dbh}->func ($self->{blob_fd}, $buffer, length $buffer, 'lo_write');
156              
157 0           return $nbytes;
158             }
159              
160             sub syswrite
161             {
162 0     0 1   my $self = shift;
163 0           my $nbytes = $_[1];
164 0   0       my $offset = $_[2] || 0;
165              
166 0           my $buffer = substr $_[0], $offset, $nbytes;
167              
168 0           $self->{dbh}->func ($self->{blob_fd}, $buffer, length $buffer, 'lo_write');
169              
170 0           return $nbytes;
171             }
172              
173             =item $io->print ($buffer);
174              
175             =cut
176              
177             sub print
178             {
179 0     0 1   my $self = shift;
180 0           my $buffer = join "", @_;
181              
182 0           return $self->write ($buffer, length $buffer);
183             }
184              
185             =item $io->close;
186              
187             Close the IO handle.
188              
189             =cut
190              
191             sub close
192             {
193 0     0 1   my $self = shift;
194              
195 0 0         if ($self->{dbh})
196             {
197 0           $self->{dbh}->func ($self->{blob_fd}, 'lo_close');
198 0           delete $self->{dbh};
199             }
200              
201 0           return 1;
202             }
203              
204             sub DESTROY
205             {
206 0     0     shift->close;
207             }
208              
209             1 # So that the require or use succeeds.
210              
211             __END__