- All Implemented Interfaces:
AutoCloseable
,FbStatement
,ExceptionListenable
- Direct Known Subclasses:
AbstractFbWireStatement
- Since:
- 3.0
- Author:
- Mark Rotteveel
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final ExceptionListenerDispatcher
protected final StatementListenerDispatcher
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionfinal void
addExceptionListener
(ExceptionListener listener) Adds an exception listener to this object.final void
addStatementListener
(StatementListener statementListener) Registers aStatementListener
.void
addWeakStatementListener
(StatementListener statementListener) Adds aStatementListener
instance to this database using a weak reference.void
asyncFetchRows
(int fetchSize) Requests the server to perform an asynchronous fetch forfetch size
.protected final void
checkFetchSize
(int fetchSize) Validates iffetchSize
is positive, otherwise throws an exception.protected final StatementState
Checks if prepare is allowed, returning the current statement state.protected final void
Checks if statement is valid withcheckStatementValid()
and then checks if the current statement state has an open cursor.protected final void
Checks if this statement is not inStatementState.CLOSED
,StatementState.CLOSING
,StatementState.NEW
orStatementState.ERROR
, and throws anSQLException
if it is.protected final void
checkStatementValid
(StatementState ignoreState) Performs the same check ascheckStatementValid()
, but considersignoreState
as valid.void
close()
Close and deallocate this statement.final void
Closes the cursor associated with this statement, leaving the statement itself allocated.final void
closeCursor
(boolean transactionEnd) Closes the cursor associated with this statement, leaving the statement itself allocated.protected ExecutionPlanProcessor
protected SqlCountProcessor
final void
ensureClosedCursor
(boolean transactionEnd) Ensures that the statement cursor is closed.final void
fetchScroll
(FetchType fetchType, int fetchSize, int position) Requests this statement to fetch rows using the specified fetch type.protected void
fetchScrollImpl
(FetchType fetchType, int fetchSize, int position) Implementation offetchScroll(FetchType, int, int)
.protected void
forceState
(StatementState newState) Forces the statement to the specified state without throwing an exception if this is not a valid transition.protected abstract void
free
(int option) Frees the currently allocated statement.protected long
final byte[]
getCursorInfo
(byte[] requestItems, int bufferLength) Request cursor info.final <T> T
getCursorInfo
(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) Request cursor info.protected byte[]
getCursorInfoImpl
(byte[] requestItems, int bufferLength) Implementation ofgetCursorInfo(byte[], int)
.protected final String
Gets the cursor name.final String
final String
byte[]
final RowDescriptor
final RowDescriptor
Retrieves the SQL counts for the last execution of this statement.final <T> T
getSqlInfo
(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) Request statement info.final StatementState
getState()
byte[]
protected final WarningMessageCallback
long
Gets the current statement timeout for this statement.protected final TransactionListener
Gets theTransactionListener
instance for this statement.final StatementType
getType()
final boolean
Has at least one fetch been executed on the current cursor?protected final boolean
protected final boolean
protected final boolean
protected final boolean
protected boolean
isPrepareAllowed
(StatementState state) Is a call toFbStatement.prepare(String)
allowed for the suppliedStatementState
.protected abstract boolean
isValidTransactionClass
(Class<? extends FbTransaction> transactionClass) Method to decide if a transaction implementation class is valid for the statement implementation.protected void
parseStatementInfo
(byte[] statementInfoResponse) Parse the statement info response instatementInfoResponse
.protected final void
queueRowData
(RowValue rowData) Queues row data for consumptionfinal void
removeExceptionListener
(ExceptionListener listener) Removes an exception listener to this object.final void
removeStatementListener
(StatementListener statementListener) Removes aStatementListener
.protected final void
reset()
Reset statement state, equivalent to callingreset(boolean)
withfalse
.protected void
reset
(boolean resetAll) Resets the statement for next execution.protected final void
resetAll()
Reset statement state and clear parameter description, equivalent to callingreset(boolean)
withtrue
.protected final void
Marks the cursor position as after-last.protected final void
Marks the cursor position as before-first.final void
setCursorName
(String cursorName) Sets the named cursor name for this statement.protected abstract void
setCursorNameImpl
(String cursorName) Implementation ofsetCursorName(String)
.protected void
setParameterDescriptor
(RowDescriptor parameterDescriptor) Sets the parameter descriptor.protected void
setRowDescriptor
(RowDescriptor rowDescriptor) Sets the (result set) row descriptor.void
setTimeout
(long statementTimeout) Sets the statement timeout.final void
setTransaction
(FbTransaction newTransaction) Associates a transaction with this statementprotected void
setType
(StatementType type) Sets the StatementTypeprotected final OperationCloseHandle
protected final OperationCloseHandle
protected final OperationCloseHandle
Signals the start of an execute for this statement.protected final OperationCloseHandle
Signals the start of a fetch for this statement.protected final void
switchState
(StatementState newState) Sets the StatementState.void
Attempts to unprepare the currently prepared statement.final void
validateParameters
(RowValue parameters) Validates if the number of parameters matches the expected number and types, and if all values have been set.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.FbStatement
batchCancel, batchExecute, clearCursorFlag, createBatchParameterBuffer, deferredBatchCreate, deferredBatchRelease, deferredBatchSend, emptyRowDescriptor, execute, fetchRows, getDatabase, getDefaultSqlInfoSize, getHandle, getMaxSqlInfoSize, getSqlInfo, isCursorFlagSet, prepare, setCursorFlag, supportBatchUpdates, supportsCursorInfo, supportsFetchScroll, withLock
-
Field Details
-
statementListenerDispatcher
-
exceptionListenerDispatcher
-
-
Constructor Details
-
AbstractFbStatement
protected AbstractFbStatement()
-
-
Method Details
-
getTransactionListener
Gets theTransactionListener
instance for this statement.This method should only be called by this object itself. Subclasses may provide their own transaction listener, but the instance returned by this method should be the same for the lifetime of this
FbStatement
.- Returns:
- The transaction listener instance for this statement.
-
getStatementWarningCallback
-
asyncFetchRows
Description copied from interface:FbStatement
Requests the server to perform an asynchronous fetch forfetch size
.Asynchronous fetching is an optional feature. If an implementation does not support asynchronous fetching, it should return immediately and do nothing. Although this interface provides a default implementation which does nothing, implementations should override it, to throw an exception when called on a closed statement.
For implementations which do support async fetching, this call should not do anything if one of the following is true:
- an asynchronous fetch is already pending
fetchSize
is1
or the statement has a cursor name set- the current statement has a scrollable cursor (flag
CURSOR_TYPE_SCROLLABLE
set) - the connection property
asyncFetch
isfalse
An asynchronous fetch can be completed explicitly by calling
FbStatement.fetchRows(int)
, or implicitly by other network operations.- Specified by:
asyncFetchRows
in interfaceFbStatement
- Parameters:
fetchSize
- number of rows to fetch (must be greater than0
)- Throws:
SQLException
- for database access errors, when called on a closed statement, when no cursor is open or when the fetch size is not greater than0
- See Also:
-
hasFetched
public final boolean hasFetched()Description copied from interface:FbStatement
Has at least one fetch been executed on the current cursor?- Specified by:
hasFetched
in interfaceFbStatement
- Returns:
true
if at least one fetch has been executed on the current cursor,false
otherwise (including if nothing has been executed, or the current statement has no cursor)
-
checkFetchSize
Validates iffetchSize
is positive, otherwise throws an exception.- Parameters:
fetchSize
- fetch size (must be positive)- Throws:
SQLException
- iffetchSize
is smaller than1
- Since:
- 6
-
close
Description copied from interface:FbStatement
Close and deallocate this statement.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceFbStatement
- Throws:
SQLException
-
closeCursor
Description copied from interface:FbStatement
Closes the cursor associated with this statement, leaving the statement itself allocated.Equivalent to calling
FbStatement.closeCursor(boolean)
withfalse
.- Specified by:
closeCursor
in interfaceFbStatement
- Throws:
SQLException
-
closeCursor
Description copied from interface:FbStatement
Closes the cursor associated with this statement, leaving the statement itself allocated.When this method is called in preparation of a commit, rollback or another operation which will close the cursor (see
transactionEnd
), then implementations may opt to not close the cursor on the server as the server closes the cursor automatically, or the statement as a whole is closed by the implementation.- Specified by:
closeCursor
in interfaceFbStatement
- Parameters:
transactionEnd
- close is in response to a transaction end or another operation which will implicitly close the cursor- Throws:
SQLException
-
ensureClosedCursor
Description copied from interface:FbStatement
Ensures that the statement cursor is closed. Resets a statement, so it is ready to be reused for re-execute or prepare.- Specified by:
ensureClosedCursor
in interfaceFbStatement
- Parameters:
transactionEnd
- Close is in response to a transaction end- Throws:
SQLException
- If this statement is closed or the cursor could not be closed.
-
unprepare
Description copied from interface:FbStatement
Attempts to unprepare the currently prepared statement.For Firebird versions that do not support
DSQL_unprepare
, the implementation should attempt to close the cursor (usingFbStatement.closeCursor()
).- Specified by:
unprepare
in interfaceFbStatement
- Throws:
SQLException
- If a database access error occurs
-
getState
- Specified by:
getState
in interfaceFbStatement
- Returns:
- The current state of this statement
-
switchState
Sets the StatementState.- Parameters:
newState
- New state- Throws:
SQLException
- When the state is changed to an illegal next state
-
forceState
Forces the statement to the specified state without throwing an exception if this is not a valid transition.Does nothing if current state is CLOSED.
- Parameters:
newState
- New state- See Also:
-
getType
- Specified by:
getType
in interfaceFbStatement
- Returns:
- The statement type
-
setType
Sets the StatementType- Parameters:
type
- New type
-
queueRowData
Queues row data for consumption- Parameters:
rowData
- Row data
-
setBeforeFirst
protected final void setBeforeFirst()Marks the cursor position as before-first.All registered
StatementListener
instances are notified for theStatementListener.beforeFirst(FbStatement)
event. -
isBeforeFirst
protected final boolean isBeforeFirst() -
setAfterLast
protected final void setAfterLast()Marks the cursor position as after-last.All registered
StatementListener
instances are notified for theStatementListener.afterLast(FbStatement)
event. -
isAfterLast
protected final boolean isAfterLast() -
reset
protected final void reset()Reset statement state, equivalent to callingreset(boolean)
withfalse
. -
resetAll
protected final void resetAll()Reset statement state and clear parameter description, equivalent to callingreset(boolean)
withtrue
. -
reset
protected void reset(boolean resetAll) Resets the statement for next execution. Implementation in derived class must lock onFbStatement.withLock()
and callsuper.reset(resetAll)
- Parameters:
resetAll
- Also reset field and parameter info
-
isPrepareAllowed
Is a call toFbStatement.prepare(String)
allowed for the suppliedStatementState
.- Parameters:
state
- The statement state- Returns:
true
call toprepare
is allowed
-
checkPrepareAllowed
Checks if prepare is allowed, returning the current statement state.This method checks if the current transaction is active, and if the current statement state allows preparing a new statement.
- Returns:
- statement state
- Throws:
SQLException
- if there is no active transaction, or the current state does not allow statement prepare- Since:
- 6
-
getParameterDescriptor
- Specified by:
getParameterDescriptor
in interfaceFbStatement
- Returns:
- descriptor of the parameters of this statement
-
setParameterDescriptor
Sets the parameter descriptor.- Parameters:
parameterDescriptor
- Parameter descriptor
-
getRowDescriptor
- Specified by:
getRowDescriptor
in interfaceFbStatement
- Returns:
- descriptor of the row returned by this statement
-
setRowDescriptor
Sets the (result set) row descriptor.- Parameters:
rowDescriptor
- Row descriptor
-
getStatementInfoRequestItems
public byte[] getStatementInfoRequestItems()- Returns:
- The (full) statement info request items.
- See Also:
-
getParameterDescriptionInfoRequestItems
public byte[] getParameterDescriptionInfoRequestItems()- Returns:
- The
isc_info_sql_describe_vars
info request items. - See Also:
-
fetchScroll
Description copied from interface:FbStatement
Requests this statement to fetch rows using the specified fetch type.The default implementation only supports
FetchType.NEXT
by redirecting toFbStatement.fetchRows(int)
and throws anSQLFeatureNotSupported
for other types.The caller is responsible for tracking and correcting for server-side positional state, taking into account any rows already fetched. For example, if 100 rows have been fetched with
NEXT
orPRIOR
, and 80 rows are still in the local buffer, the server-side position is actually 80 rows ahead (or behind). The next fetch withRELATIVE
will need to correct this inposition
, and aPRIOR
after aNEXT
or aNEXT
after aPRIOR
will need to reposition withRELATIVE
orABSOLUTE
, or know how many rows to ignore from the fetched batch.If an asynchronous fetch is pending, the behaviour depends on the value of
fetchType
: ifFetchType.NEXT
, the fetch should be completed instead of performing a new fetch. For any other value, aSQLException
should be thrown. GivenFbStatement.asyncFetchRows(int)
should be a no-op for scrollable cursors, this should not normally happen.- Specified by:
fetchScroll
in interfaceFbStatement
- Parameters:
fetchType
- Fetch typefetchSize
- Number of rows to fetch (must be> 0
) (ignored by server for types other thanFetchType.NEXT
andFetchType.PRIOR
)position
- Absolute or relative position for the row to fetch (ignored by server for types other thanFetchType.ABSOLUTE
andFetchType.RELATIVE
)- Throws:
SQLFeatureNotSupportedException
- For types other thanFetchType.NEXT
if the protocol version or the implementation does not support scroll fetchSQLException
- For database access errors, when called on a closed statement, when no cursor is open, when an async fetch is pending andfetchType
is notNEXT
, or for server-side error conditions- See Also:
-
fetchScrollImpl
protected void fetchScrollImpl(FetchType fetchType, int fetchSize, int position) throws SQLException Implementation offetchScroll(FetchType, int, int)
.An implementation should not notify
exceptionListenerDispatcher
, as that is already handled infetchScroll(FetchType, int, int)
.The implementation of
fetchScroll(FetchType, int, int)
redirectsFetchType.NEXT
toFbStatement.fetchRows(int)
. The implementation does need to handleNEXT
, but only when actually implementing the other scroll direction.- Throws:
SQLFeatureNotSupportedException
- If the protocol version or the implementation does not support scroll fetch (even forNEXT
)SQLException
- For database access errors, when called on a closed statement, when no cursor is open, or for serverside error conditions- See Also:
-
getSqlInfo
public final <T> T getSqlInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws SQLException Request statement info.- Specified by:
getSqlInfo
in interfaceFbStatement
- 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:
SQLException
- For errors retrieving or transforming the response.
-
getCursorInfo
public final <T> T getCursorInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws SQLException Description copied from interface:FbStatement
Request cursor info.- Specified by:
getCursorInfo
in interfaceFbStatement
- 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:
SQLException
- For errors retrieving or transforming the responseSQLFeatureNotSupportedException
- If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)- See Also:
-
getCursorInfo
Description copied from interface:FbStatement
Request cursor info.- Specified by:
getCursorInfo
in interfaceFbStatement
- Parameters:
requestItems
- Array of info items to requestbufferLength
- Response buffer length to use- Returns:
- Response buffer
- Throws:
SQLException
- For errors retrieving or transforming the responseSQLFeatureNotSupportedException
- If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)
-
getCursorInfoImpl
Implementation ofgetCursorInfo(byte[], int)
.An implementation should not notify
exceptionListenerDispatcher
, as that is already handled ingetCursorInfo(byte[], int)
.- Throws:
SQLException
- For errors retrieving or transforming the responseSQLFeatureNotSupportedException
- If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)- See Also:
-
getExecutionPlan
- Specified by:
getExecutionPlan
in interfaceFbStatement
- Returns:
- The execution plan of the currently prepared statement
- Throws:
SQLException
- If this statement is closed.
-
getExplainedExecutionPlan
- Specified by:
getExplainedExecutionPlan
in interfaceFbStatement
- Returns:
- The detailed execution plan of the currently prepared statement
- Throws:
SQLException
- If this statement is closed.
-
createExecutionPlanProcessor
- Returns:
- New instance of
ExecutionPlanProcessor
(or subclass) for this statement.
-
getSqlCounts
Description copied from interface:FbStatement
Retrieves the SQL counts for the last execution of this statement.The retrieved SQL counts are also notified to all registered
StatementListener
s.In general the
FbStatement
will (should) retrieve and notify listeners of the SQL counts automatically at times where it is relevant (eg after executing a statement that does not produce multiple rows, or after fetching all rows).- Specified by:
getSqlCounts
in interfaceFbStatement
- Returns:
- The SQL counts of the last execution of this statement
- Throws:
SQLException
- If this statement is closed, or if this statement is in stateStatementState.CURSOR_OPEN
and not all rows have been fetched.
-
createSqlCountProcessor
- Returns:
- New instance of
SqlCountProcessor
(or subclass) for this statement.
-
free
Frees the currently allocated statement. Either close the cursor withISCConstants.DSQL_close
or drop the statement handle usingISCConstants.DSQL_drop
.- Parameters:
option
- Free option- Throws:
SQLException
-
validateParameters
Description copied from interface:FbStatement
Validates if the number of parameters matches the expected number and types, and if all values have been set.- Specified by:
validateParameters
in interfaceFbStatement
- Parameters:
parameters
- Parameter values to validate- Throws:
SQLException
- When the number or type of parameters does not matchFbStatement.getParameterDescriptor()
, or when a parameter has not been set.
-
addStatementListener
Description copied from interface:FbStatement
Registers aStatementListener
.- Specified by:
addStatementListener
in interfaceFbStatement
- Parameters:
statementListener
- The statement listener
-
addWeakStatementListener
Description copied from interface:FbStatement
Adds aStatementListener
instance to this database using a weak reference.If the listener is already strongly referenced, this call will be ignored
- Specified by:
addWeakStatementListener
in interfaceFbStatement
- Parameters:
statementListener
- statement listener
-
removeStatementListener
Description copied from interface:FbStatement
Removes aStatementListener
.- Specified by:
removeStatementListener
in interfaceFbStatement
- Parameters:
statementListener
- The statement listener
-
addExceptionListener
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
Description copied from interface:ExceptionListenable
Removes an exception listener to this object.- Specified by:
removeExceptionListener
in interfaceExceptionListenable
- Parameters:
listener
- Listener to remove
-
checkStatementValid
Checks if this statement is not inStatementState.CLOSED
,StatementState.CLOSING
,StatementState.NEW
orStatementState.ERROR
, and throws anSQLException
if it is.- Throws:
SQLException
- when this statement is closed or in error state
-
checkStatementValid
Performs the same check ascheckStatementValid()
, but considersignoreState
as valid.- Parameters:
ignoreState
- the invalid state (seecheckStatementValid()
to ignore- Throws:
SQLException
- when this statement is closed or in error state
-
checkStatementHasOpenCursor
Checks if statement is valid withcheckStatementValid()
and then checks if the current statement state has an open cursor.- Throws:
SQLException
- when this statement is closed or in error state, or has no open cursor- Since:
- 6
-
getTransaction
- Specified by:
getTransaction
in interfaceFbStatement
- Returns:
- Transaction currently associated with this statement
-
isValidTransactionClass
Method to decide if a transaction implementation class is valid for the statement implementation.Eg a
V10Statement
will only work with anFbWireTransaction
implementation.- Parameters:
transactionClass
- Class of the transaction- Returns:
true
when the transaction class is valid for the statement implementation.
-
setTransaction
Description copied from interface:FbStatement
Associates a transaction with this statement- Specified by:
setTransaction
in interfaceFbStatement
- Parameters:
newTransaction
- The transaction- Throws:
SQLException
-
setTimeout
Description copied from interface:FbStatement
Sets the statement timeout.The statement timeout value is ignored in implementations that do not support timeouts. If the provided timeout value is greater than supported (eg greater than â€4294967295‬ milliseconds on Firebird 4), the implementation should behave as if zero (
0
) was set, but still report the original value.The configured timeout only affects subsequent executes on this statement. The timeout includes time spent between reading from the result set.
- Specified by:
setTimeout
in interfaceFbStatement
- Parameters:
statementTimeout
- Timeout value in milliseconds- Throws:
SQLException
- If the value is less than zero, this statement is closed, or a database access error occurs
-
getTimeout
Description copied from interface:FbStatement
Gets the current statement timeout for this statement.This method will only return the current statement timeout value for this method, it will not consider attachment or connection level timeouts. This is an implementation decision that might change in a point release.
- Specified by:
getTimeout
in interfaceFbStatement
- Returns:
- The configured timeout in milliseconds; read the documentation in
FbStatement.setTimeout(long)
- Throws:
SQLException
- If this statement is closed, or a database access error occurs- See Also:
-
setCursorName
Sets the named cursor name for this statement.This method takes out a lock, and checks statement validity, then calls
setCursorNameImpl(String)
, and stores the cursor name on successful completion. Any exceptions will be notified onexceptionListenerDispatcher
. To override the behaviour of this method, implement/overridesetCursorNameImpl(String)
.- Specified by:
setCursorName
in interfaceFbStatement
- Parameters:
cursorName
- Name of the cursor- Throws:
SQLException
- If this statement is closed, or if the cursor name is set andcursorName
is different from the current cursor name
-
setCursorNameImpl
Implementation ofsetCursorName(String)
.The caller of this method will take out the lock, check statement validity and call
exceptionListenerDispatcher
for exceptions, so implementations of this method do not need to do so.- Parameters:
cursorName
- Name of the cursor- Throws:
SQLException
- If this statement is closed, or if the cursor name is set andcursorName
is different from the current cursor name
-
getCursorName
Gets the cursor name.The cursor name is cleared by a new statement prepare.
- Returns:
- the current cursor name
- Since:
- 6
-
getAllowedTimeout
- Returns:
- The timeout value, or
0
if the timeout is larger than supported - Throws:
SQLException
- If the statement is invalid
-
parseStatementInfo
Parse the statement info response instatementInfoResponse
. If the response is truncated, a new request is done usinggetStatementInfoRequestItems()
- Parameters:
statementInfoResponse
- Statement info response- Throws:
SQLException
-
hasSingletonResult
protected final boolean hasSingletonResult()- Returns:
true
if this is a stored procedure (or other singleton result producing statement) with at least 1 output field
-
hasFields
protected final boolean hasFields()- Returns:
true
if this statement has at least one output field (either singleton or result set)
-
signalExecute
Signals the start of an execute for this statement.- Returns:
OperationCloseHandle
handle for the operation
-
signalFetch
Signals the start of a fetch for this statement.- Returns:
OperationCloseHandle
handle for the operation
-
signalAsyncFetchStart
-
signalAsyncFetchComplete
-