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 ([email protected])

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)