Package org.firebirdsql.gds.ng.jna

## Class JnaBlob

- java.lang.Object
- - org.firebirdsql.gds.ng.AbstractFbBlob
  - - org.firebirdsql.gds.ng.jna.JnaBlob

All Implemented Interfaces:
  `java.lang.AutoCloseable`, `FbBlob`, `DatabaseListener`, `ExceptionListenable`, `TransactionListener`

    public class JnaBlob
    extends AbstractFbBlob
    implements FbBlob, DatabaseListener

Implementation of `FbBlob` for native client access.

Since:
  3.0
Author:
  Mark Rotteveel

### Nested Class Summary

### Nested classes/interfaces inherited from interface org.firebirdsql.gds.ng.FbBlob

`FbBlob.SeekMode`

### Field Summary

### Fields inherited from class org.firebirdsql.gds.ng.AbstractFbBlob

`exceptionListenerDispatcher`

### Fields inherited from interface org.firebirdsql.gds.ng.FbBlob

`NO_BLOB_ID`

### Constructor Summary

Constructors
`JnaBlob​(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer)` Creates a blob for output (writing to the database).
`JnaBlob​(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)` Creates a blob for input (reading from the database).

### Method Summary

All Methods Instance Methods Concrete Methods
`protected void` `cancelImpl()` Internal implementation of `AbstractFbBlob.cancel()`.
`protected void` `closeImpl()` Internal implementation of `AbstractFbBlob.close()`.
`long` `getBlobId()`
`byte[]` `getBlobInfo​(byte[] requestItems, int bufferLength)` Request blob info.
`JnaDatabase` `getDatabase()`
`int` `getHandle()`
`com.sun.jna.ptr.IntByReference` `getJnaHandle()`
`byte[]` `getSegment​(int sizeRequested)` Gets a segment of blob data.
`JnaTransaction` `getTransaction()`
`boolean` `isOutput()`
`void` `open()` Opens an existing input blob, or creates an output blob.
`void` `putSegment​(byte[] segment)` Writes a segment of blob data.
`protected void` `releaseResources()` Release Java resources held.
`void` `seek​(int offset, FbBlob.SeekMode seekMode)` Performs a seek on a blob with the specified `seekMode` and `offset`.

### Methods inherited from class org.firebirdsql.gds.ng.AbstractFbBlob

`addExceptionListener, cancel, checkBlobClosed, checkBlobOpen, checkDatabaseAttached, checkTransactionActive, clearDatabase, clearTransaction, close, createBlobLengthProcessor, detached, detaching, getBlobInfo, getBlobParameterBuffer, getMaximumSegmentSize, isEndingTransaction, isEof, isOpen, length, removeExceptionListener, resetEof, setEof, setOpen, transactionStateChanged, warningReceived, withLock`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.firebirdsql.gds.ng.listeners.DatabaseListener

`detached, detaching, warningReceived`

### Methods inherited from interface org.firebirdsql.gds.ng.listeners.ExceptionListenable

`addExceptionListener, removeExceptionListener`

### Methods inherited from interface org.firebirdsql.gds.ng.FbBlob

`cancel, close, getBlobInfo, getMaximumSegmentSize, isEof, isOpen, length`

### Constructor Detail

#### JnaBlob

    public JnaBlob​(JnaDatabase database,
                   JnaTransaction transaction,
                   BlobParameterBuffer blobParameterBuffer)

Creates a blob for output (writing to the database).

Parameters:
  `database` - database
  `transaction` - transaction
  `blobParameterBuffer` - blob parameter buffer

#### JnaBlob

    public JnaBlob​(JnaDatabase database,
                   JnaTransaction transaction,
                   BlobParameterBuffer blobParameterBuffer,
                   long blobId)

Creates a blob for input (reading from the database).

Parameters:
  `database` - database
  `transaction` - transaction
  `blobParameterBuffer` - blob parameter buffer
  `blobId` - blob id

### Method Detail

#### getDatabase

    public JnaDatabase getDatabase()

Specified by:
  `getDatabase` in interface `FbBlob`
Overrides:
  `getDatabase` in class `AbstractFbBlob`
Returns:
  The database connection that created this blob

#### getTransaction

    public JnaTransaction getTransaction()

Overrides:
  `getTransaction` in class `AbstractFbBlob`

#### getHandle

    public int getHandle()

Specified by:
  `getHandle` in interface `FbBlob`
Returns:
  The Firebird blob handle identifier

#### getJnaHandle

    public final com.sun.jna.ptr.IntByReference getJnaHandle()

#### getBlobId

    public final long getBlobId()

Specified by:
  `getBlobId` in interface `FbBlob`
Returns:
  The Firebird blob id

#### open

    public void open()
              throws java.sql.SQLException

Description copied from interface: `FbBlob`
Opens an existing input blob, or creates an output blob.

Specified by:
  `open` in interface `FbBlob`
Throws:
  `java.sql.SQLException` - If the blob is already open, this is a (closed) output blob and it already has a blobId, the transaction is not active, or a database connection error occurred

#### isOutput

    public final boolean isOutput()

Specified by:
  `isOutput` in interface `FbBlob`
Returns:
  `true` if this is an output blob (write only), `false` if this is an input blob (read only)

#### getSegment

    public byte[] getSegment​(int sizeRequested)
                      throws java.sql.SQLException

Description copied from interface: `FbBlob`
Gets a segment of blob data.

When `sizeRequested` exceeds `FbBlob.getMaximumSegmentSize()` it is silently reduced to the maximum segment size.

TODO: Consider allowing this and have the implementation handle longer segments by sending multiple (batched?) requests.

Specified by:
  `getSegment` in interface `FbBlob`
Parameters:
  `sizeRequested` - Requested segment size (> 0).
Returns:
  Retrieved segment (size may be less than requested)
Throws:
  `java.sql.SQLException` - If this is an output blob, the blob is closed, the transaction is not active, or a database connection error occurred.

#### putSegment

    public void putSegment​(byte[] segment)
                    throws java.sql.SQLException

Description copied from interface: `FbBlob`
Writes a segment of blob data.

Implementation must handle segment length exceeding `FbBlob.getMaximumSegmentSize()` by batching. TODO: reconsider and let caller handle that?

Passing a section that is length 0 will throw an `SQLException`.

Specified by:
  `putSegment` in interface `FbBlob`
Parameters:
  `segment` - Segment to write
Throws:
  `java.sql.SQLException` - If this is an input blob, the blob is closed, the transaction is not active, the segment is length 0 or longer than the maximum segment size, or a database connection error occurred.

#### seek

    public void seek​(int offset,
                     FbBlob.SeekMode seekMode)
              throws java.sql.SQLException

Description copied from interface: `FbBlob`
Performs a seek on a blob with the specified `seekMode` and `offset`.

Firebird only supports seek on stream blobs.

Specified by:
  `seek` in interface `FbBlob`
Parameters:
  `offset` - Offset of the seek, effect depends on value of `seekMode`
  `seekMode` - Value of `FbBlob.SeekMode`
Throws:
  `java.sql.SQLException` - If the blob is closed, the transaction is not active, or a database error occurred.

#### getBlobInfo

    public byte[] getBlobInfo​(byte[] requestItems,
                              int bufferLength)
                       throws java.sql.SQLException

Description copied from interface: `FbBlob`
Request blob info.

Specified by:
  `getBlobInfo` in interface `FbBlob`
Parameters:
  `requestItems` - Array of info items to request
  `bufferLength` - Response buffer length to use
Returns:
  Response buffer
Throws:
  `java.sql.SQLException`

#### closeImpl

    protected void closeImpl()
                      throws java.sql.SQLException

Description copied from class: `AbstractFbBlob`
Internal implementation of `AbstractFbBlob.close()`. The implementation does not need to check for attached database and active transaction, nor does it need to mark this blob as closed.

Specified by:
  `closeImpl` in class `AbstractFbBlob`
Throws:
  `java.sql.SQLException`

#### cancelImpl

    protected void cancelImpl()
                       throws java.sql.SQLException

Description copied from class: `AbstractFbBlob`
Internal implementation of `AbstractFbBlob.cancel()`. The implementation does not need to check for attached database and active transaction, nor does it need to mark this blob as closed.

Specified by:
  `cancelImpl` in class `AbstractFbBlob`
Throws:
  `java.sql.SQLException`

#### releaseResources

    protected void releaseResources()

Description copied from class: `AbstractFbBlob`
Release Java resources held. This should not communicate with the Firebird server.

Specified by:
  `releaseResources` in class `AbstractFbBlob`