Class AbstractFbBlob
- java.lang.Object
-
- org.firebirdsql.gds.ng.AbstractFbBlob
-
- All Implemented Interfaces:
java.lang.AutoCloseable
,FbBlob
,DatabaseListener
,ExceptionListenable
,TransactionListener
- Direct Known Subclasses:
AbstractFbWireBlob
,JnaBlob
public abstract class AbstractFbBlob extends java.lang.Object implements FbBlob, TransactionListener, DatabaseListener
- Since:
- 3.0
- Author:
- Mark Rotteveel
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected static class
AbstractFbBlob.BlobState
State of the blob.-
Nested classes/interfaces inherited from interface org.firebirdsql.gds.ng.FbBlob
FbBlob.SeekMode
-
-
Field Summary
Fields Modifier and Type Field Description protected ExceptionListenerDispatcher
exceptionListenerDispatcher
-
Fields inherited from interface org.firebirdsql.gds.ng.FbBlob
NO_BLOB_ID
-
-
Constructor Summary
Constructors Modifier Constructor Description protected
AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description void
addExceptionListener(ExceptionListener listener)
Adds an exception listener to this object.void
cancel()
Cancels an output blob (which means its contents will be thrown away).protected abstract void
cancelImpl()
Internal implementation ofcancel()
.protected void
checkBlobClosed()
protected void
checkBlobOpen()
Checks if the blob is open.protected void
checkDatabaseAttached()
protected void
checkTransactionActive()
protected void
clearDatabase()
protected void
clearDeferredException()
Clears the deferred exception.protected void
clearTransaction()
void
close()
Closes the blob.protected abstract void
closeImpl()
Internal implementation ofclose()
.protected BlobLengthProcessor
createBlobLengthProcessor()
void
detached(FbDatabase database)
Called when thedatabase
connection has been detachedvoid
detaching(FbDatabase database)
Called before thedatabase
will be detached.protected void
errorOccurred(java.sql.SQLException e)
int
get(byte[] b, int off, int len)
Reads content from the blob intob
starting atoff
forlen
bytes.int
get(byte[] b, int off, int len, float minFillFactor)
Variant ofFbBlob.get(byte[], int, int)
to exert some control over the number of requests performed.protected abstract int
get(byte[] b, int off, int len, int minLen)
Default implementation forget(byte[], int, int)
andget(byte[], int, int, float)
.<T> T
getBlobInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor)
Request blob info.protected BlobParameterBuffer
getBlobParameterBuffer()
FbDatabase
getDatabase()
protected byte[]
getKnownBlobInfoItems()
The known blob info items for the connected server as a blob info request buffer.int
getMaximumSegmentSize()
The maximum segment size allowed by the protocol forFbBlob.getSegment(int)
andFbBlob.putSegment(byte[])
.protected AbstractFbBlob.BlobState
getState()
The current blob state.protected FbTransaction
getTransaction()
protected boolean
isEndingTransaction()
boolean
isEof()
boolean
isOpen()
long
length()
Requests the blob length from the server.void
putSegment(byte[] segment)
Writes a segment of blob data.protected void
registerDeferredException(java.sql.SQLException deferredException)
Registers an exception as a deferred exception.protected abstract void
releaseResources()
Release Java resources held.void
removeExceptionListener(ExceptionListener listener)
Removes an exception listener to this object.protected void
resetEof()
Resets the eof state of the blob to false (not eof).protected void
setEof()
Marks this blob as EOF (End of file).protected void
setState(AbstractFbBlob.BlobState newState)
Sets the state of the blob to the specified value.protected void
throwAndClearDeferredException()
If a deferred exception is registered it is cleared and thrown.void
transactionStateChanged(FbTransaction transaction, TransactionState newState, TransactionState previousState)
Signals that the transaction state changed.protected void
transferDeferredExceptionTo(java.sql.SQLException target)
If a deferred exception is registered, it is cleared and set as a next exception ontarget
.protected void
validateBufferLength(byte[] b, int off, int len)
Validates requested offset (off
) and length (len
) against the array (b
).void
warningReceived(FbDatabase database, java.sql.SQLWarning warning)
Called when a warning was received for thedatabase
connection.protected LockCloseable
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.FbBlob
getBlobId, getBlobInfo, getHandle, getSegment, isOutput, open, put, seek
-
-
-
-
Field Detail
-
exceptionListenerDispatcher
protected final ExceptionListenerDispatcher exceptionListenerDispatcher
-
-
Constructor Detail
-
AbstractFbBlob
protected AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) throws java.sql.SQLException
- Throws:
java.sql.SQLException
-
-
Method Detail
-
isOpen
public final boolean isOpen()
-
isEof
public final boolean isEof()
-
setEof
protected final void setEof()
Marks this blob as EOF (End of file).For an output blob this is a no-op (as those are never end of file, unless explicitly closed)
-
resetEof
protected final void resetEof()
Resets the eof state of the blob to false (not eof).This method should only be called by subclasses of this class.
-
setState
protected final void setState(AbstractFbBlob.BlobState newState)
Sets the state of the blob to the specified value.This method should only be called by subclasses of this class.
- Parameters:
newState
- new value of state- Since:
- 5.0.7
-
getState
protected final AbstractFbBlob.BlobState getState()
The current blob state.- Returns:
- current blob state
- Since:
- 5.0.7
-
close
public final void close() throws java.sql.SQLException
Description copied from interface:FbBlob
Closes the blob.Closing an already closed blob is a no-op.
-
closeImpl
protected abstract void closeImpl() throws java.sql.SQLException
Internal implementation ofclose()
. The implementation does not need to check for attached database and active transaction, nor does it need to mark this blob as closed.- Throws:
java.sql.SQLException
-
cancel
public final void cancel() throws java.sql.SQLException
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 anSQLException
.
-
cancelImpl
protected abstract void cancelImpl() throws java.sql.SQLException
Internal implementation ofcancel()
. The implementation does not need to check for attached database and active transaction, nor does it need to mark this blob as closed.- Throws:
java.sql.SQLException
-
putSegment
public void putSegment(byte[] segment) throws java.sql.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 callput(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 interfaceFbBlob
- 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 a database connection error occurred- See Also:
FbBlob.put(byte[], int, int)
-
get
public final int get(byte[] b, int off, int len) throws java.sql.SQLException
Description copied from interface:FbBlob
Reads content from the blob intob
starting atoff
forlen
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 returns0
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, useFbBlob.get(byte[], int, int, float)
.- Specified by:
get
in interfaceFbBlob
- Parameters:
b
- target byte arrayoff
- offset to startlen
- number of bytes- Returns:
- actual number of bytes read; this will only be less than
len
when end-of-blob was reached - Throws:
java.sql.SQLException
- for database access errors, ifoff < 0
,len < 0
, or ifoff + len > b.length
-
get
public final int get(byte[] b, int off, int len, float minFillFactor) throws java.sql.SQLException
Description copied from interface:FbBlob
Variant ofFbBlob.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 toFbBlob.get(byte[], int, int)
where avoiding the potential inefficiencies of that method are preferred over getting all the requestedlen
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 returns0
when no bytes were read if end-of-blob is reached without reading any bytes, not-1
.- Specified by:
get
in interfaceFbBlob
- Parameters:
b
- target byte arrayoff
- offset to startlen
- number of bytesminFillFactor
- 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:
java.sql.SQLException
- for database access errors, ifoff < 0
,len < 0
, or ifoff + len > b.length
,minFillFactor <= 0
, orminFillFactor > 1
orminFillFactor is NaN
-
get
protected abstract int get(byte[] b, int off, int len, int minLen) throws java.sql.SQLException
Default implementation forget(byte[], int, int)
andget(byte[], int, int, float)
.- Parameters:
b
- target byte arrayoff
- offset to startlen
- number of bytesminLen
- minimum number of bytes to fill (must be0 < minLen <= len
iflen != 0
- Returns:
- actual number of bytes read; is
0
iflen == 0
, will only be less thanminLen
if end-of-blob is reached - Throws:
java.sql.SQLException
- for database access errors, ifoff < 0
,len < 0
, or ifoff + len > b.length
, orlen != 0 && (minLen <= 0 || minLen > len)
-
releaseResources
protected abstract void releaseResources()
Release Java resources held. This should not communicate with the Firebird server.
-
registerDeferredException
protected final void registerDeferredException(java.sql.SQLException deferredException)
Registers an exception as a deferred exception.This should only be used for exceptions from deferred response that need to be thrown.
- Parameters:
deferredException
- deferred exception- Since:
- 5.0.7
-
clearDeferredException
protected final void clearDeferredException()
Clears the deferred exception.- Since:
- 5.0.7
-
throwAndClearDeferredException
protected final void throwAndClearDeferredException() throws java.sql.SQLException
If a deferred exception is registered it is cleared and thrown.- Throws:
java.sql.SQLException
- the current deferred exception, if any- Since:
- 5.0.7
-
transferDeferredExceptionTo
protected final void transferDeferredExceptionTo(java.sql.SQLException target)
If a deferred exception is registered, it is cleared and set as a next exception ontarget
.- Parameters:
target
- the target exception to add the deferred exception to (notnull
)- Throws:
java.lang.NullPointerException
- if there is a deferred exception, andtarget == null
- Since:
- 5.0.7
-
withLock
protected final LockCloseable withLock()
- See Also:
FbAttachment.withLock()
-
transactionStateChanged
public void transactionStateChanged(FbTransaction transaction, TransactionState newState, TransactionState previousState)
Description copied from interface:TransactionListener
Signals that the transaction state changed.- Specified by:
transactionStateChanged
in interfaceTransactionListener
- Parameters:
transaction
-FbTransaction
that changed state
-
detaching
public void detaching(FbDatabase database)
Description copied from interface:DatabaseListener
Called before thedatabase
will be detached.This event is intended for cleanup action, implementer should take care that no exceptions are thrown from this method.
- Specified by:
detaching
in interfaceDatabaseListener
- Parameters:
database
- The database object that is detaching
-
detached
public void detached(FbDatabase database)
Description copied from interface:DatabaseListener
Called when thedatabase
connection has been detached- Specified by:
detached
in interfaceDatabaseListener
- Parameters:
database
- The database object that was detached
-
warningReceived
public void warningReceived(FbDatabase database, java.sql.SQLWarning warning)
Description copied from interface:DatabaseListener
Called when a warning was received for thedatabase
connection.In implementation it is possible that some warnings are not sent to listeners on the database, but only to listeners on specific connection derived objects (like an
FbStatement
implementation).- Specified by:
warningReceived
in interfaceDatabaseListener
- Parameters:
database
- Database receiving the warningwarning
- Warning
-
isEndingTransaction
protected final boolean isEndingTransaction()
- Returns:
true
if the transaction is committing, rolling back or preparing
-
checkTransactionActive
protected final void checkTransactionActive() throws java.sql.SQLException
- Throws:
java.sql.SQLException
- when no transaction is set, or the transaction state is notTransactionState.ACTIVE
-
checkDatabaseAttached
protected final void checkDatabaseAttached() throws java.sql.SQLException
- Throws:
java.sql.SQLException
- when no database is set, or the database is not attached
-
checkBlobOpen
protected void checkBlobOpen() throws java.sql.SQLException
Checks if the blob is open.NOTE: Subclasses may perform additional side effects, like queuing a server-side open for a deferred open blob.
- Throws:
java.sql.SQLException
- when the blob is closed.
-
checkBlobClosed
protected void checkBlobClosed() throws java.sql.SQLException
- Throws:
java.sql.SQLException
- When the blob is open.
-
getTransaction
protected FbTransaction getTransaction()
-
clearTransaction
protected final void clearTransaction()
-
getDatabase
public FbDatabase getDatabase()
- Specified by:
getDatabase
in interfaceFbBlob
- Returns:
- The database connection that created this blob
-
getBlobInfo
public <T> T getBlobInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws java.sql.SQLException
Description copied from interface:FbBlob
Request blob info.- Specified by:
getBlobInfo
in interfaceFbBlob
- Parameters:
requestItems
- Array of info items to requestbufferLength
- Response buffer length to useinfoProcessor
- Implementation ofInfoProcessor
to transform the info response- Returns:
- Transformed info response of type T
- Throws:
java.sql.SQLException
- For errors retrieving or transforming the response.
-
getKnownBlobInfoItems
protected byte[] getKnownBlobInfoItems()
The known blob info items for the connected server as a blob info request buffer.- Returns:
- the known blob info items (possibly empty under implementation-specific circumstances)
- Since:
- 7
-
length
public long length() throws java.sql.SQLException
Description copied from interface:FbBlob
Requests the blob length from the server.
-
errorOccurred
protected final void errorOccurred(java.sql.SQLException e)
NotifiesExceptionListenerDispatcher.errorOccurred(SQLException)
.If there is a registered deferred exception, it is set as a next exception on
e
before notification.- Parameters:
e
- exception to notify to exception listeners
-
addExceptionListener
public final void addExceptionListener(ExceptionListener listener)
Description copied from interface:ExceptionListenable
Adds an exception listener to this object.Implementations use
WeakReference
.- Specified by:
addExceptionListener
in interfaceExceptionListenable
- Parameters:
listener
- Listener to register
-
removeExceptionListener
public final void removeExceptionListener(ExceptionListener listener)
Description copied from interface:ExceptionListenable
Removes an exception listener to this object.- Specified by:
removeExceptionListener
in interfaceExceptionListenable
- Parameters:
listener
- Listener to remove
-
clearDatabase
protected final void clearDatabase()
-
getBlobParameterBuffer
protected BlobParameterBuffer getBlobParameterBuffer()
- Returns:
- The blob parameter buffer of this blob.
-
createBlobLengthProcessor
protected BlobLengthProcessor createBlobLengthProcessor()
- Returns:
- New instance of
BlobLengthProcessor
for this blob.
-
getMaximumSegmentSize
public int getMaximumSegmentSize()
Description copied from interface:FbBlob
The maximum segment size allowed by the protocol forFbBlob.getSegment(int)
andFbBlob.putSegment(byte[])
.This value is not the segment size (optionally) defined for the column.
- Specified by:
getMaximumSegmentSize
in interfaceFbBlob
- Returns:
- The maximum segment size allowed for get or put.
-
validateBufferLength
protected final void validateBufferLength(byte[] b, int off, int len) throws java.sql.SQLException
Validates requested offset (off
) and length (len
) against the array (b
).- Parameters:
b
- arrayoff
- position in arraylen
- length fromoff
- Throws:
java.sql.SQLException
- ifoff < 0
,len < 0
, or ifoff + len > b.length
- Since:
- 5.0.7
-
-