Class InlineBlob

java.lang.Object
org.firebirdsql.gds.ng.wire.InlineBlob
All Implemented Interfaces:
AutoCloseable, FbBlob, ExceptionListenable

@NullMarked public final class InlineBlob extends Object implements FbBlob
Implementation of FbBlob to hold an inline blob.

This blob may remain open on transaction end or database detach. However, this is considered an implementation detail which may change in point releases.

Since:
6.0.2
Author:
Mark Rotteveel
  • Constructor Details

    • InlineBlob

      public InlineBlob(FbDatabase database, long blobId, int transactionHandle, byte[] info, byte[] data)
      Creates an inline blob.
      Parameters:
      database - database that created this blob
      blobId - blob id
      transactionHandle - handle of the transaction for which this blob is valid
      info - blob info (cannot be null), if empty an array containing isc_info_end will be used
      data - actual blob data without segments (cannot be null)
  • Method Details

    • getBlobId

      public long getBlobId()
      Description copied from interface: FbBlob
      Returns the blob id.

      For output blobs, this will return FbBlob.NO_BLOB_ID (0L) if the blob wasn't opened yet, or if the blob is deferred opened (client-side only). The value FbBlob.NO_BLOB_ID is technically invalid, but Firebird will handle it as an empty blob (both for input and output).

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

      public int getTransactionHandle()
      Returns:
      the transaction handle this inline blob is valid for
    • getHandle

      public int getHandle()
      Returns the blob handle identifier.

      If the blob wasn't opened yet, this will return 0. If the blob was deferred opened (client-side only), this will return an invalid blob handle value (e.g. 0xFFFF, though this value is potentially protocol/implementation specific).

      An inline blob has no server-side counterpart, so we generate a value greater than 65535 as its handle.

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

      public FbDatabase getDatabase()
      Specified by:
      getDatabase in interface FbBlob
      Returns:
      The database connection that created this blob
    • open

      public void open() throws SQLException
      Description copied from interface: FbBlob
      Opens an existing input blob, or creates an output blob.
      Specified by:
      open in interface FbBlob
      Throws:
      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
    • isOpen

      public boolean isOpen()
      Specified by:
      isOpen in interface FbBlob
      Returns:
      true if this blob is currently open.
    • isEof

      public boolean isEof()
      Specified by:
      isEof in interface FbBlob
      Returns:
      true if this blob has reached the end or has been closed, always true for an open output blob.
    • close

      public void close()
      Description copied from interface: FbBlob
      Closes the blob.

      Closing an already closed blob is a no-op.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface FbBlob
    • cancel

      public void cancel()
      Description copied from interface: FbBlob
      Cancels an output blob (which means its contents will be thrown away).

      Calling cancel on an input blob will close it. Contrary to FbBlob.close(), calling cancel on an already closed (or cancelled) blob will throw an SQLException.

      Specified by:
      cancel in interface FbBlob
    • isOutput

      public 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 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.

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

      public int get(byte[] b, int off, int len) throws SQLException
      Description copied from interface: FbBlob
      Reads content from the blob into b starting at off for len bytes.

      Implementations must read the requested number of bytes (len), unless end-of-blob is reached before the requested number of bytes were read. The return value of this method is the actual number of bytes read.

      If the implementation cannot perform reads without additional allocation, it should use at most DatabaseConnectionProperties.getBlobBufferSize() as an internal buffer. If the implementation can perform reads without additional allocation, it is recommended it performs reads using (at most) FbBlob.getMaximumSegmentSize().

      Contrary to similar methods like InputStream.read(byte[], int, int), this method returns 0 when no bytes were read if end-of-blob is reached without reading any bytes, not -1.

      Given this method attempts to fulfill the entire request for len bytes, it may not always be efficient. For example, requests near multiples of the maximum segment size (or blob buffer size) may result in a final request for just a few bytes. This is not a problem if the entire blob is requested at once, but for intermediate buffering it might be better not to do that final request, and instead work with a smaller number of bytes than requested. For those cases, use FbBlob.get(byte[], int, int, float).

      Specified by:
      get in interface FbBlob
      Parameters:
      b - target byte array
      off - offset to start
      len - number of bytes
      Returns:
      actual number of bytes read; this will only be less than len when end-of-blob was reached
      Throws:
      SQLException - for database access errors, if off < 0, len < 0, or if off + len > b.length
    • get

      public int get(byte[] b, int off, int len, float minFillFactor) throws SQLException
      Description copied from interface: FbBlob
      Variant of FbBlob.get(byte[], int, int) to exert some control over the number of requests performed.

      This method will request segments until at least (int) (minFillFactor * len) bytes have been retrieved, or end-of-blob is reached. This method is intended as an alternative to FbBlob.get(byte[], int, int) where avoiding the potential inefficiencies of that method are preferred over getting all the requested len bytes.

      If the implementation cannot perform reads without additional allocation, it should use at most DatabaseConnectionProperties.getBlobBufferSize() as an internal buffer. If the implementation can perform reads without additional allocation, it is recommended it performs reads using (at most) FbBlob.getMaximumSegmentSize().

      Contrary to similar methods like InputStream.read(byte[], int, int), this method returns 0 when no bytes were read if end-of-blob is reached without reading any bytes, not -1.

      Specified by:
      get in interface FbBlob
      Parameters:
      b - target byte array
      off - offset to start
      len - number of bytes
      minFillFactor - minimum fill factor (0 < minFillFactor <= 1)
      Returns:
      actual number of bytes read, this method returns at least (int) (minFillFactor * len) bytes, unless end-of-blob is reached
      Throws:
      SQLException - for database access errors, if off < 0, len < 0, or if off + len > b.length, minFillFactor <= 0, or minFillFactor > 1 or minFillFactor is NaN
    • putSegment

      public void putSegment(byte[] segment) throws SQLException
      Description copied from interface: FbBlob
      Writes a segment of blob data.

      Implementations must handle segment lengths exceeding FbBlob.getMaximumSegmentSize() by batching. This method should either call put(segment, 0, segment.length), or produce the same effects as that call.

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

      Specified by:
      putSegment in interface FbBlob
      Parameters:
      segment - segment to write
      Throws:
      SQLException - if this is an input blob, the blob is closed, the transaction is not active, the segment is length 0, or a database connection error occurred
      See Also:
    • put

      public void put(byte[] b, int off, int len) throws SQLException
      Description copied from interface: FbBlob
      Writes content of b starting at off for length bytes to the blob.

      Implementations must write all bytes to the blob, using multiple round-trips if necessary.

      If the implementation cannot perform writes without additional allocation, it should use at most DatabaseConnectionProperties.getBlobBufferSize() as an internal buffer. If the implementation can perform writes without additional allocation, it is recommended it performs reads using (at most) FbBlob.getMaximumSegmentSize().

      Specified by:
      put in interface FbBlob
      Parameters:
      b - source byte array
      off - offset to start
      len - number of bytes
      Throws:
      SQLException - for database access errors, if off < 0, len < 0, or if off + len > b.length
    • seek

      public void seek(int offset, FbBlob.SeekMode seekMode) throws 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:
      SQLException - If the blob is closed, the transaction is not active, or a database error occurred.
    • getMaximumSegmentSize

      public int getMaximumSegmentSize()
      Description copied from interface: FbBlob
      The maximum segment size allowed by the protocol for FbBlob.getSegment(int) and FbBlob.putSegment(byte[]).

      This value is not the segment size (optionally) defined for the column.

      Specified by:
      getMaximumSegmentSize in interface FbBlob
      Returns:
      The maximum segment size allowed for get or put.
    • getBlobInfo

      public <T> T getBlobInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws 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
      infoProcessor - Implementation of InfoProcessor to transform the info response
      Returns:
      Transformed info response of type T
      Throws:
      SQLException - For errors retrieving or transforming the response.
    • length

      public long length()
      Description copied from interface: FbBlob
      Requests the blob length from the server.
      Specified by:
      length in interface FbBlob
      Returns:
      Length of the blob.
    • getBlobInfo

      public byte[] getBlobInfo(byte[] requestItems, int bufferLength) throws SQLException
      Request blob info.

      Unknown blob info items are ignored, and only known items are returned.

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

      public void addExceptionListener(ExceptionListener listener)
      Description copied from interface: ExceptionListenable
      Adds an exception listener to this object.

      Implementations use WeakReference.

      Specified by:
      addExceptionListener in interface ExceptionListenable
      Parameters:
      listener - Listener to register
    • removeExceptionListener

      public void removeExceptionListener(ExceptionListener listener)
      Description copied from interface: ExceptionListenable
      Removes an exception listener to this object.
      Specified by:
      removeExceptionListener in interface ExceptionListenable
      Parameters:
      listener - Listener to remove
    • copy

      public InlineBlob copy()
      Returns:
      a copy of this inline blob, it is initially closed.