Обсуждение: create BLOB question

Поиск
Список
Период
Сортировка

create BLOB question

От
Jeremiah Jahn
Дата:
does some9one out there know how to create a new oid from scratch.
setBytes on 7.2 worked fine for me, but with the change to 7.3 I can't
seem to get a new oid number. I want to avoid any postgres specific
stuff. Correct me if I'm wrong, but It seems to me that the setBytes
goes with the bytea stuff and the BLOB stuff goes with the oid stuff. I
just can't seem to figure out how to insert a new oid/BLOB.

any help would be great,
thanx
-jj-
--
Support your local Search and Rescue unit -- get lost.
--
Jeremiah Jahn <jeremiah@cs.earlham.edu>


Re: create BLOB question

От
"David Wall"
Дата:
> does some9one out there know how to create a new oid from scratch.
> setBytes on 7.2 worked fine for me, but with the change to 7.3 I can't
> seem to get a new oid number. I want to avoid any postgres specific
> stuff. Correct me if I'm wrong, but It seems to me that the setBytes
> goes with the bytea stuff and the BLOB stuff goes with the oid stuff. I
> just can't seem to figure out how to insert a new oid/BLOB.
>
> any help would be great,

You will need to use the setBlob() call on prepared statement.  The trick is
that you'll need a wrapper that can take your byte array and pretend it's a
java.sql.Blob interface so that the driver can use it.  In my code, Oracle
does it different, with an empty_blob() being first created, and then
updated with the blob data (why, I'll never know!).

Below is a utility class that we use so that our mainline call, which has a
byte array, can just do the following:
            YoByteBlob myBlob = new YoByteBlob( myByteArray );
            if ( ! isOracle )
                stmt.setBlob(1,myBlob);


// Copyright (c) 2002 Yozons, Inc.  All rights reserved.
// This file is proprietary.
//
package com.yozons.jdbc;

import java.sql.SQLException;

/**
 * Screwy wrapper class so that we can insert a Blob into the database from
a byte array.
 * Includes more screwy stuff for Oracle specific updating of a blob (the
only way to insert a new blob).
 *
 * @author David Wall
 */
public class YoByteBlob
    implements java.sql.Blob
{
    byte[] bytes = null;

    /**
     * Creates a YoByteBlob using the specified byte array.
     */
    public YoByteBlob(byte[] b)
    {
        bytes = b;
    }

    // My own constructor for taking a Blob of input and returning as an
array
    public YoByteBlob(java.sql.Blob b)
    {
        java.io.InputStream is = null;
        try
        {
            is = b.getBinaryStream();
            bytes = new byte[(int)b.length()];
            is.read(bytes);
        }
        catch( java.sql.SQLException e )
        {
            bytes = null;
        }
        catch( java.io.IOException e )
        {
            bytes = null;
        }
        finally
        {
            try
            {
                if ( is != null )
                    is.close();
            }
            catch( Exception e ) {}
        }
    }

    public long length()
        throws java.sql.SQLException
    {
        return bytes.length;
    }

    // My own API call for simplicity
    public byte[] getBytes()
    {
        return bytes;
    }

    public byte[] getBytes(long pos, int length)
        throws java.sql.SQLException
    {
        if ( pos == 0 && length == bytes.length )
            return bytes;

        try
        {
            byte[] newbytes = new byte[length];
            System.arraycopy(bytes, (int)pos, newbytes, 0, length);
            return newbytes;
        }
        catch( Exception e )
        {
            throw new java.sql.SQLException("Could not get subset of
array");
        }
    }

    public java.io.InputStream getBinaryStream()
        throws java.sql.SQLException
    {
        return new java.io.ByteArrayInputStream(bytes);
    }

    public long position(byte[] pattern, long start)
        throws java.sql.SQLException
    {
        throw new java.sql.SQLException("Unsupported position() for blob");
    }

    public long position(java.sql.Blob pattern, long start)
        throws java.sql.SQLException
    {
        throw new java.sql.SQLException("Unsupported position() for blob");
    }


    /**
     * Routine used to put the "real" object into an Oracle database, which
requires
     * creating an empty blob, then retrieving it again and updating it from
there.
     */
    public void updateOracleBlob(java.sql.Blob b)
        throws java.sql.SQLException
    {
        java.io.OutputStream outstream = null;

        try
        {
            if ( b == null )
                throw new SQLException("YoByteBlob.updateOracleBlob() blob
was null");
            if ( ! (b instanceof oracle.sql.BLOB) )
                throw new SQLException("YoByteBlob.updateOracleBlob() blob
not an oracle.sql.BLOB object; is: " +
                                       b.getClass().getName() );
            if ( bytes == null )
                throw new SQLException("YoByteBlob.updateOracleBlob() no
blob bytes to write");

            oracle.sql.BLOB blob = (oracle.sql.BLOB)b;
            outstream            = blob.getBinaryOutputStream();

            int bufSize   = blob.getBufferSize();
            int pos       = 0;
            int remaining = bytes.length;
            while ( remaining > 0 )
            {
                int numOut = Math.min(bufSize,remaining);
                outstream.write(bytes, pos, numOut);
                pos       += numOut;
                remaining -= numOut;
            }
        }
        catch( java.io.IOException e )
        {
            throw new java.sql.SQLException("YoByteBlob.updateOracleBlob()
I/O failure: " + e.getMessage());
        }
        finally
        {
            try
            {
                if ( outstream != null )
                    outstream.close();
            }
            catch( java.io.IOException e )
            {
                throw new
java.sql.SQLException("YoByteBlob.updateOracleBlob() close I/O failure: " +
e.getMessage());
            }
        }
     }
}


Re: create BLOB question

От
Jeremiah Jahn
Дата:
So does setBytes() insert or overwrite the data starting at a position?




On Mon, 2003-02-10 at 15:28, David Wall wrote:
> > does some9one out there know how to create a new oid from scratch.
> > setBytes on 7.2 worked fine for me, but with the change to 7.3 I can't
> > seem to get a new oid number. I want to avoid any postgres specific
> > stuff. Correct me if I'm wrong, but It seems to me that the setBytes
> > goes with the bytea stuff and the BLOB stuff goes with the oid stuff. I
> > just can't seem to figure out how to insert a new oid/BLOB.
> >
> > any help would be great,
>
> You will need to use the setBlob() call on prepared statement.  The trick is
> that you'll need a wrapper that can take your byte array and pretend it's a
> java.sql.Blob interface so that the driver can use it.  In my code, Oracle
> does it different, with an empty_blob() being first created, and then
> updated with the blob data (why, I'll never know!).
>
> Below is a utility class that we use so that our mainline call, which has a
> byte array, can just do the following:
>             YoByteBlob myBlob = new YoByteBlob( myByteArray );
>             if ( ! isOracle )
>                 stmt.setBlob(1,myBlob);
>
>
> // Copyright (c) 2002 Yozons, Inc.  All rights reserved.
> // This file is proprietary.
> //
> package com.yozons.jdbc;
>
> import java.sql.SQLException;
>
> /**
>  * Screwy wrapper class so that we can insert a Blob into the database from
> a byte array.
>  * Includes more screwy stuff for Oracle specific updating of a blob (the
> only way to insert a new blob).
>  *
>  * @author David Wall
>  */
> public class YoByteBlob
>     implements java.sql.Blob
> {
>     byte[] bytes = null;
>
>     /**
>      * Creates a YoByteBlob using the specified byte array.
>      */
>     public YoByteBlob(byte[] b)
>     {
>         bytes = b;
>     }
>
>     // My own constructor for taking a Blob of input and returning as an
> array
>     public YoByteBlob(java.sql.Blob b)
>     {
>         java.io.InputStream is = null;
>         try
>         {
>             is = b.getBinaryStream();
>             bytes = new byte[(int)b.length()];
>             is.read(bytes);
>         }
>         catch( java.sql.SQLException e )
>         {
>             bytes = null;
>         }
>         catch( java.io.IOException e )
>         {
>             bytes = null;
>         }
>         finally
>         {
>             try
>             {
>                 if ( is != null )
>                     is.close();
>             }
>             catch( Exception e ) {}
>         }
>     }
>
>     public long length()
>         throws java.sql.SQLException
>     {
>         return bytes.length;
>     }
>
>     // My own API call for simplicity
>     public byte[] getBytes()
>     {
>         return bytes;
>     }
>
>     public byte[] getBytes(long pos, int length)
>         throws java.sql.SQLException
>     {
>         if ( pos == 0 && length == bytes.length )
>             return bytes;
>
>         try
>         {
>             byte[] newbytes = new byte[length];
>             System.arraycopy(bytes, (int)pos, newbytes, 0, length);
>             return newbytes;
>         }
>         catch( Exception e )
>         {
>             throw new java.sql.SQLException("Could not get subset of
> array");
>         }
>     }
>
>     public java.io.InputStream getBinaryStream()
>         throws java.sql.SQLException
>     {
>         return new java.io.ByteArrayInputStream(bytes);
>     }
>
>     public long position(byte[] pattern, long start)
>         throws java.sql.SQLException
>     {
>         throw new java.sql.SQLException("Unsupported position() for blob");
>     }
>
>     public long position(java.sql.Blob pattern, long start)
>         throws java.sql.SQLException
>     {
>         throw new java.sql.SQLException("Unsupported position() for blob");
>     }
>
>
>     /**
>      * Routine used to put the "real" object into an Oracle database, which
> requires
>      * creating an empty blob, then retrieving it again and updating it from
> there.
>      */
>     public void updateOracleBlob(java.sql.Blob b)
>         throws java.sql.SQLException
>     {
>         java.io.OutputStream outstream = null;
>
>         try
>         {
>             if ( b == null )
>                 throw new SQLException("YoByteBlob.updateOracleBlob() blob
> was null");
>             if ( ! (b instanceof oracle.sql.BLOB) )
>                 throw new SQLException("YoByteBlob.updateOracleBlob() blob
> not an oracle.sql.BLOB object; is: " +
>                                        b.getClass().getName() );
>             if ( bytes == null )
>                 throw new SQLException("YoByteBlob.updateOracleBlob() no
> blob bytes to write");
>
>             oracle.sql.BLOB blob = (oracle.sql.BLOB)b;
>             outstream            = blob.getBinaryOutputStream();
>
>             int bufSize   = blob.getBufferSize();
>             int pos       = 0;
>             int remaining = bytes.length;
>             while ( remaining > 0 )
>             {
>                 int numOut = Math.min(bufSize,remaining);
>                 outstream.write(bytes, pos, numOut);
>                 pos       += numOut;
>                 remaining -= numOut;
>             }
>         }
>         catch( java.io.IOException e )
>         {
>             throw new java.sql.SQLException("YoByteBlob.updateOracleBlob()
> I/O failure: " + e.getMessage());
>         }
>         finally
>         {
>             try
>             {
>                 if ( outstream != null )
>                     outstream.close();
>             }
>             catch( java.io.IOException e )
>             {
>                 throw new
> java.sql.SQLException("YoByteBlob.updateOracleBlob() close I/O failure: " +
> e.getMessage());
>             }
>         }
>      }
> }
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
--
Jeremiah Jahn <jeremiah@cs.earlham.edu>


Re: create BLOB question

От
"David Wall"
Дата:
> So does setBytes() insert or overwrite the data starting at a position?

What setBytes() are you referring to?  For bytea columns, I believe it can
be used in an insert and update just fine, but it's always assumed to work
on the entire array, starting at position 0.

David


Re: create BLOB question

От
Jeremiah Jahn
Дата:
I'm writing the BLOB wrapper.

3 methods have ambiguous implementations.

 public java.io.OutputStream setBinaryStream(long pos) throws SQLException{
 }
 public int setBytes(long pos,byte[] bytes)  throws SQLException{
 }
 public int setBytes(long pos,byte[] bytes,int offset,int len)  throws SQLException{
 }

If I already have an array of data. An I start writing to it at position
pos, does it overwrite the old data or insert into the array at that
point and move the old data down toward the end?


On Mon, 2003-02-10 at 17:54, David Wall wrote:
> > So does setBytes() insert or overwrite the data starting at a position?
>
> What setBytes() are you referring to?  For bytea columns, I believe it can
> be used in an insert and update just fine, but it's always assumed to work
> on the entire array, starting at position 0.
>
> David
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
--
Jeremiah Jahn <jeremiah@cs.earlham.edu>


Re: create BLOB question

От
Barry Lind
Дата:

Jeremiah Jahn wrote:
> I'm writing the BLOB wrapper.
>
> 3 methods have ambiguous implementations.
>
>  public java.io.OutputStream setBinaryStream(long pos) throws SQLException{
>  }
>  public int setBytes(long pos,byte[] bytes)  throws SQLException{
>  }
>  public int setBytes(long pos,byte[] bytes,int offset,int len)  throws SQLException{
>  }
>
> If I already have an array of data. An I start writing to it at position
> pos, does it overwrite the old data or insert into the array at that
> point and move the old data down toward the end?
>

My understanding is that it should overwrite the data at that point.

--Barry




Re: create BLOB question

От
Jeremiah Jahn
Дата:
When it's finished does it truncate the data?

I tried to find the actual implementation of the Blob.setBytes() in the
postgres code, but couldn't. Just a bunch of abstract classes and
things, none of which had code for these methods. Do you know here the
implementing code for these methods are?

-jj-

On Tue, 2003-02-11 at 10:42, Barry Lind wrote:
> Jeremiah Jahn wrote:
> > I'm writing the BLOB wrapper.
> >
> > 3 methods have ambiguous implementations.
> >
> >  public java.io.OutputStream setBinaryStream(long pos) throws SQLException{
> >  }
> >  public int setBytes(long pos,byte[] bytes)  throws SQLException{
> >  }
> >  public int setBytes(long pos,byte[] bytes,int offset,int len)  throws SQLException{
> >  }
> >
> > If I already have an array of data. An I start writing to it at position
> > pos, does it overwrite the old data or insert into the array at that
> > point and move the old data down toward the end?
> >
>
> My understanding is that it should overwrite the data at that point.
>
> --Barry
>
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
--
Jeremiah Jahn <jeremiah@cs.earlham.edu>


Re: create BLOB question

От
Barry Lind
Дата:

Jeremiah Jahn wrote:
> When it's finished does it truncate the data?

I would not expect it to.

>
> I tried to find the actual implementation of the Blob.setBytes() in the
> postgres code, but couldn't. Just a bunch of abstract classes and
> things, none of which had code for these methods. Do you know here the
> implementing code for these methods are?
>

There is no implementation of this method.  This is a new method in
jdbc3 and is not yet implemented.  The methods that are implemented are
in org.postgresql.jdbc2.AbstractJdbc2Blob, which uses the functionality
provided by org.postgresql.largeobject.LargeObject.  No work has been
done to implement the jdbc3 additional methods to the Blob interface.
So if you look at org.postgresql.jdbc3.AbstractJdbc3Blob.setBytes() you
will see that the implementation just throws a not implemented
exception.  All the functionality necessary to implement setBytes()
should be available in LargeObject.

--Barry