NAME
       DBIx::BLOB::Handle - Read Database Large Object Binaries
       from file handles

SYNOPSIS
       use DBI;

       use DBIx::BLOB::Handle;

       # use DBIx::BLOB::Handle qw( :INTO_STATEMENT );

       $dbh = DBI->connect('DBI:Oracle:ORCL','scott','tiger',
                           {RaiseError => 1, PrintError => 0 }
                              )

       or die 'Could not connect to database:' , DBI->errstr;

       $dbh->{LongTruncOk} = 1; # very important!

       $sql = 'select mylob from mytable where id = 1';

       $sth = $dbh->prepare($sql);

       $sth->execute;

       $sth->fetch;

       $fh = DBIx::BLOB::Handle->new($sth,0,4096);

       ...

       print while <$fh>;

       # print $fh->getlines;

       print STDERR 'Size of LOB was ' . $fh->tell . " bytes\n";

       ...

       # read default buffer size

       # fastest way to process a LOB

       print $chunk while read($fh,$chunk,undef);

       ...

       # fastest way to read a LOB into a scalar

       local $/;

       $blob = <$handle>;

       ...

       # or if we used the dangerous :INTO_STATEMENT pragma,

       # we could say:

       # $fh = $sth->blob_as_handle(0,4096);

       ...

       $sth->finish;

       $dbh->disconnect;

DESCRIPTION AND RATIONALE
       DBI has a blob_copy_to_file method which takes a file han-
       dle argument and copies a database large object binary
       (LOB) to this file handle. However, the method is undocu-
       mented and faulty. Constructing a similar method yourself
       is pretty simple but what if you wished to read the data
       and perform operations on it? You could use the DBI's
       blob_read method yourself to process chunks of data from
       the LOB or even dump its contents into a scalar, but maybe
       it would be nice to read the data line by line or piece by
       piece from a familiar old filehandle?!

       DBIx::BLOB::Handle constructs a tied filehandle that also
       extends from IO::Handle and IO::Selectable. It wraps DBI's
       blob_read method. By making LOB's available as a file han-
       dle to read from we can process the data in a familiar
       (perly) way.

       Additionally, by making the module respect $/ and $. then
       we can read lines of text data from a textual LOB (CLOB)
       and treat it just as we would any other file handle!

CONSTRUCTOR
       new
           $fh = DBIx::BLOB::Handle->new($sth,$column,$block-
           size);

           $fh = $statement->blob_as_handle($column,$blocksize);

       Constructs a new file handle from the given DBI statement,
       given the column number (zero based) of the LOB within the
       statement. The column number defaults to '0'. The block-
       size argument specifies how many bytes at a time should be
       read from the LOB and defaults to '4096'

       ...

       By 'use'ing the :INTO_STATEMENT pragma as follows;

       use DBIx::BLOB::Handle qw( :INTO_STATEMENT );

       DBIx::BLOB::Handle will install itself as a method of the
       DBI::st (statement) class. Thus you can create a file han-
       dle by calling

           $fh = $statement->blob_as_handle($column,$blocksize);

       which in turn calls new.

METHODS
       readline
           $line = $handle->getline;

           $line = scalar <$handle>;

           @lines = $handle->getlines;

           @lines = <$handle>;

           Read from the LOB. $handle->getline, or <$handle> in
           scalar context will return a line, according to the
           current definition of a line (everything up to the
           next value of $/); $handle->getlines or <$handle> in
           list context will return an array of lines.

           Note: the actual implementation is to do a read (see
           below) at the default blocksize. The data read back is
           then split to find the actual rows. Thus there is a
           trade off between number of network reads performed
           and the amount of storage on the client.

           Bug: Mixing reads and readlines on the same handle
           will screw everything up!  This is because the stored
           position within the blob is the position from the last
           read, not the number of bytes from the currently
           returned lines.

       getc
           $char = $handle->getc;

           $char = getc $handle;

           Returns the next byte from $handle. Returns undef if
           there are no more bytes to read. This is SLOW as it
           fetches one byte from the database each time. A future
           implementation might fetch the default (blocksize)
           number of bytes from the database and then return
           these as single characters. Thoughts anyone?

       read
           $handle->read($chunk,[$length], [$offset]);

           read $handle, $chunk, $length, [$offset];

           Read $length bytes from $handle into $chunk, starting
           at position $offset in $chunk (thus you can build up a
           scalar data structure). If $length is omitted then the
           default blocksize will be used. If $length is omitted
           then the bytes read will fill $chunk. Returns the num-
           ber of bytes read.

       seek
           $handle->seek($offset, $whence);

           seek $handle $offset, $whence;

           Positions the file pointer for $handle. The first
           position is 0, not 1. Units are bytes, not line num-
           bers; $whence specifies what file position $offset
           uses; 0, the beginning of the file; 1, the current
           position; or 2, the end of the file.

           Note: The behaviour currently differs from that of a
           standard file handle.  Seeking before the beginning or
           after then end of the handle will reset the handle
           position to the beginning or end respectively.

           Note: Seeking backwards for $handle is efficient
           because we don't have to do any further network traf-
           fic. Seeking forward means we have to do more reads
           from the blob as i am unaware of any (database inde-
           pendant) method to get the size of a LOB. Currently
           reads are NOT cached since we don't know the final
           size of the blob. Thus seeking to the end of the blob,
           and then reading it backward or reading the entire
           blob, seeking to position 0 and re-reading (as exam-
           ples) would result in double the amount of network
           traffic.

       tell
           $handle->tell;

           tell $handle;

           Gives the current position (in bytes, zero based)
           within the LOB

       eof $handle->eof;

           eof $handle;

       Returns true if we have finished reading from the LOB.

SEE ALSO
       Perls Filehandle functions, The Tied Handle interface, the
       IO::Handle manpage, the IO::Seekable manpage

BUGS
       Don't use the read method and the readline methods on the
       same handle.

       Otherwise please report them!

AUTHOR
       Mark Southern (mark_southern@merck.com)

COPYRIGHT
       Copyright (c) 2002, Merck & Co. Inc. All Rights Reserved.
       This module is free software. It may be used, redis-
       tributed and/or modified under the terms of the Perl
       Artistic License (see http://www.perl.com/perl/misc/Artis-
       tic.html)
