Module org.firebirdsql.jaybird
Package org.firebirdsql.gds.ng

# Class AbstractFbStatement

java.lang.Object
org.firebirdsql.gds.ng.AbstractFbStatement

All Implemented Interfaces:
  `AutoCloseable`, `FbStatement`, `ExceptionListenable`

Direct Known Subclasses:
  `AbstractFbWireStatement`

public abstract class AbstractFbStatement extends Object implements FbStatement

Since:
  3.0
Author:
  Mark Rotteveel

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final ExceptionListenerDispatcher`
  `exceptionListenerDispatcher`
  `protected final StatementListenerDispatcher`
  `statementListenerDispatcher`

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `AbstractFbStatement()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final void`
  `addExceptionListener(ExceptionListener listener)`
  Adds an exception listener to this object.
  `final void`
  `addStatementListener(StatementListener statementListener)`
  Registers a `StatementListener`.
  `void`
  `addWeakStatementListener(StatementListener statementListener)`
  Adds a `StatementListener` instance to this database using a weak reference.
  `void`
  `asyncFetchRows(int fetchSize)`
  Requests the server to perform an asynchronous fetch for `fetch size`.
  `protected final void`
  `checkFetchSize(int fetchSize)`
  Validates if `fetchSize` is positive, otherwise throws an exception.
  `protected final StatementState`
  `checkPrepareAllowed()`
  Checks if prepare is allowed, returning the current statement state.
  `protected final void`
  `checkStatementHasOpenCursor()`
  Checks if statement is valid with `checkStatementValid()` and then checks if the current statement state has an open cursor.
  `protected final void`
  `checkStatementValid()`
  Checks if this statement is not in `StatementState.CLOSED`, `StatementState.CLOSING`, `StatementState.NEW` or `StatementState.ERROR`, and throws an `SQLException` if it is.
  `protected final void`
  `checkStatementValid(StatementState ignoreState)`
  Performs the same check as `checkStatementValid()`, but considers `ignoreState` as valid.
  `void`
  `close()`
  Close and deallocate this statement.
  `final void`
  `closeCursor()`
  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`
  `createExecutionPlanProcessor()`
  `protected SqlCountProcessor`
  `createSqlCountProcessor()`
  `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 of `fetchScroll(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`
  `getAllowedTimeout()`
  `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 of `getCursorInfo(byte[], int)`.
  `protected final String`
  `getCursorName()`
  Gets the cursor name.
  `final String`
  `getExecutionPlan()`
  `final String`
  `getExplainedExecutionPlan()`
  `byte[]`
  `getParameterDescriptionInfoRequestItems()`
  `final RowDescriptor`
  `getParameterDescriptor()`
  `final RowDescriptor`
  `getRowDescriptor()`
  `SqlCountHolder`
  `getSqlCounts()`
  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[]`
  `getStatementInfoRequestItems()`
  `protected final WarningMessageCallback`
  `getStatementWarningCallback()`
  `long`
  `getTimeout()`
  Gets the current statement timeout for this statement.
  `FbTransaction`
  `getTransaction()`
  `protected final TransactionListener`
  `getTransactionListener()`
  Gets the `TransactionListener` instance for this statement.
  `final StatementType`
  `getType()`
  `final boolean`
  `hasFetched()`
  Has at least one fetch been executed on the current cursor?
  `protected final boolean`
  `hasFields()`
  `protected final boolean`
  `hasSingletonResult()`
  `protected final boolean`
  `isAfterLast()`
  `protected final boolean`
  `isBeforeFirst()`
  `protected boolean`
  `isPrepareAllowed(StatementState state)`
  Is a call to `FbStatement.prepare(String)` allowed for the supplied `StatementState`.
  `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 in `statementInfoResponse`.
  `protected final void`
  `queueRowData(RowValue rowData)`
  Queues row data for consumption
  `final void`
  `removeExceptionListener(ExceptionListener listener)`
  Removes an exception listener to this object.
  `final void`
  `removeStatementListener(StatementListener statementListener)`
  Removes a `StatementListener`.
  `protected final void`
  `reset()`
  Reset statement state, equivalent to calling `reset(boolean)` with `false`.
  `protected void`
  `reset(boolean resetAll)`
  Resets the statement for next execution.
  `protected final void`
  `resetAll()`
  Reset statement state and clear parameter description, equivalent to calling `reset(boolean)` with `true`.
  `protected final void`
  `setAfterLast()`
  Marks the cursor position as after-last.
  `protected final void`
  `setBeforeFirst()`
  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 of `setCursorName(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 statement
  `protected void`
  `setType(StatementType type)`
  Sets the StatementType
  `protected final OperationCloseHandle`
  `signalAsyncFetchComplete()`
  `protected final OperationCloseHandle`
  `signalAsyncFetchStart()`
  `protected final OperationCloseHandle`
  `signalExecute()`
  Signals the start of an execute for this statement.
  `protected final OperationCloseHandle`
  `signalFetch()`
  Signals the start of a fetch for this statement.
  `protected final void`
  `switchState(StatementState newState)`
  Sets the StatementState.
  `void`
  `unprepare()`
  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

    protected final StatementListenerDispatcher statementListenerDispatcher

  - ### exceptionListenerDispatcher

    protected final ExceptionListenerDispatcher exceptionListenerDispatcher

- ## Constructor Details

  - ### AbstractFbStatement

    protected AbstractFbStatement()

- ## Method Details

  - ### getTransactionListener

    protected final TransactionListener getTransactionListener()
    Gets the `TransactionListener` 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

    protected final WarningMessageCallback getStatementWarningCallback()

  - ### asyncFetchRows

    public void asyncFetchRows(int fetchSize) throws SQLException
    Description copied from interface: `FbStatement`
    Requests the server to perform an asynchronous fetch for `fetch 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` is `1` or the statement has a cursor name set
    - the current statement has a scrollable cursor (flag `CURSOR_TYPE_SCROLLABLE` set)
    - the connection property `asyncFetch` is `false`

    An asynchronous fetch can be completed explicitly by calling `FbStatement.fetchRows(int)`, or implicitly by other network operations.

    Specified by:
      `asyncFetchRows` in interface `FbStatement`
    Parameters:
      `fetchSize` - number of rows to fetch (must be greater than `0`)
    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 than `0`
    See Also:
      - `FbStatement.fetchRows(int)`

  - ### 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 interface `FbStatement`
    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

    protected final void checkFetchSize(int fetchSize) throws SQLException
    Validates if `fetchSize` is positive, otherwise throws an exception.
    Parameters:
      `fetchSize` - fetch size (must be positive)
    Throws:
      `SQLException` - if `fetchSize` is smaller than `1`
    Since:
      6

  - ### close

    public void close() throws SQLException
    Description copied from interface: `FbStatement`
    Close and deallocate this statement.
    Specified by:
      `close` in interface `AutoCloseable`
    Specified by:
      `close` in interface `FbStatement`
    Throws:
      `SQLException`

  - ### closeCursor

    public final void closeCursor() throws SQLException
    Description copied from interface: `FbStatement`
    Closes the cursor associated with this statement, leaving the statement itself allocated.

    Equivalent to calling `FbStatement.closeCursor(boolean)` with `false`.

    Specified by:
      `closeCursor` in interface `FbStatement`
    Throws:
      `SQLException`

  - ### closeCursor

    public final void closeCursor(boolean transactionEnd) throws SQLException
    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 interface `FbStatement`
    Parameters:
      `transactionEnd` - close is in response to a transaction end or another operation which will implicitly close the cursor
    Throws:
      `SQLException`

  - ### ensureClosedCursor

    public final void ensureClosedCursor(boolean transactionEnd) throws SQLException
    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 interface `FbStatement`
    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

    public void unprepare() throws SQLException
    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 (using `FbStatement.closeCursor()`).

    Specified by:
      `unprepare` in interface `FbStatement`
    Throws:
      `SQLException` - If a database access error occurs

  - ### getState

    public final StatementState getState()
    Specified by:
      `getState` in interface `FbStatement`
    Returns:
      The current state of this statement

  - ### switchState

    protected final void switchState(StatementState newState) throws SQLException
    Sets the StatementState.
    Parameters:
      `newState` - New state
    Throws:
      `SQLException` - When the state is changed to an illegal next state

  - ### forceState

    protected void forceState(StatementState newState)
    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:
      - `switchState(StatementState)`

  - ### getType

    public final StatementType getType()
    Specified by:
      `getType` in interface `FbStatement`
    Returns:
      The statement type

  - ### setType

    protected void setType(StatementType type)
    Sets the StatementType
    Parameters:
      `type` - New type

  - ### queueRowData

    protected final void queueRowData(RowValue rowData)
    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 the `StatementListener.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 the `StatementListener.afterLast(FbStatement)` event.

  - ### isAfterLast

    protected final boolean isAfterLast()

  - ### reset

    protected final void reset()
    Reset statement state, equivalent to calling `reset(boolean)` with `false`.

  - ### resetAll

    protected final void resetAll()
    Reset statement state and clear parameter description, equivalent to calling `reset(boolean)` with `true`.

  - ### reset

    protected void reset(boolean resetAll)
    Resets the statement for next execution. Implementation in derived class must lock on `FbStatement.withLock()` and call `super.reset(resetAll)`
    Parameters:
      `resetAll` - Also reset field and parameter info

  - ### isPrepareAllowed

    protected boolean isPrepareAllowed(StatementState state)
    Is a call to `FbStatement.prepare(String)` allowed for the supplied `StatementState`.
    Parameters:
      `state` - The statement state
    Returns:
      `true` call to `prepare` is allowed

  - ### checkPrepareAllowed

    protected final StatementState checkPrepareAllowed() throws SQLException
    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

    public final RowDescriptor getParameterDescriptor()
    Specified by:
      `getParameterDescriptor` in interface `FbStatement`
    Returns:
      descriptor of the parameters of this statement

  - ### setParameterDescriptor

    protected void setParameterDescriptor(RowDescriptor parameterDescriptor)
    Sets the parameter descriptor.
    Parameters:
      `parameterDescriptor` - Parameter descriptor

  - ### getRowDescriptor

    public final RowDescriptor getRowDescriptor()
    Specified by:
      `getRowDescriptor` in interface `FbStatement`
    Returns:
      descriptor of the row returned by this statement

  - ### setRowDescriptor

    protected void setRowDescriptor(RowDescriptor rowDescriptor)
    Sets the (result set) row descriptor.
    Parameters:
      `rowDescriptor` - Row descriptor

  - ### getStatementInfoRequestItems

    public byte[] getStatementInfoRequestItems()
    Returns:
      The (full) statement info request items.
    See Also:
      - `getParameterDescriptionInfoRequestItems()`

  - ### getParameterDescriptionInfoRequestItems

    public byte[] getParameterDescriptionInfoRequestItems()
    Returns:
      The `isc_info_sql_describe_vars` info request items.
    See Also:
      - `getStatementInfoRequestItems()`

  - ### fetchScroll

    public final void fetchScroll(FetchType fetchType, int fetchSize, int position) throws SQLException
    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 to `FbStatement.fetchRows(int)` and throws an `SQLFeatureNotSupported` 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` or `PRIOR`, and 80 rows are still in the local buffer, the server-side position is actually 80 rows ahead (or behind). The next fetch with `RELATIVE` will need to correct this in `position`, and a `PRIOR` after a `NEXT` or a `NEXT` after a `PRIOR` will need to reposition with `RELATIVE` or `ABSOLUTE`, 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`: if `FetchType.NEXT`, the fetch should be completed instead of performing a new fetch. For any other value, a `SQLException` should be thrown. Given `FbStatement.asyncFetchRows(int)` should be a no-op for scrollable cursors, this should not normally happen.

    Specified by:
      `fetchScroll` in interface `FbStatement`
    Parameters:
      `fetchType` - Fetch type
      `fetchSize` - Number of rows to fetch (must be `> 0`) (ignored by server for types other than `FetchType.NEXT` and `FetchType.PRIOR`)
      `position` - Absolute or relative position for the row to fetch (ignored by server for types other than `FetchType.ABSOLUTE` and `FetchType.RELATIVE`)
    Throws:
      `SQLFeatureNotSupportedException` - For types other than `FetchType.NEXT` if the protocol version or the implementation does not support scroll fetch
      `SQLException` - For database access errors, when called on a closed statement, when no cursor is open, when an async fetch is pending and `fetchType` is not `NEXT`, or for server-side error conditions
    See Also:
      - `FbStatement.supportsFetchScroll()`

  - ### fetchScrollImpl

    protected void fetchScrollImpl(FetchType fetchType, int fetchSize, int position) throws SQLException
    Implementation of `fetchScroll(FetchType, int, int)`.

    An implementation should not notify `exceptionListenerDispatcher`, as that is already handled in `fetchScroll(FetchType, int, int)`.

    The implementation of `fetchScroll(FetchType, int, int)` redirects `FetchType.NEXT` to `FbStatement.fetchRows(int)`. The implementation does need to handle `NEXT`, but only when actually implementing the other scroll direction.

    Throws:
      `SQLFeatureNotSupportedException` - If the protocol version or the implementation does not support scroll fetch (even for `NEXT`)
      `SQLException` - For database access errors, when called on a closed statement, when no cursor is open, or for serverside error conditions
    See Also:
      - `fetchScroll(FetchType, int, int)`
      - `FbStatement.supportsFetchScroll()`

  - ### getSqlInfo

    public final <T> T getSqlInfo(byte[] requestItems, int bufferLength, InfoProcessor<T> infoProcessor) throws SQLException
    Request statement info.
    Specified by:
      `getSqlInfo` in interface `FbStatement`
    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.

  - ### 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 interface `FbStatement`
    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
      `SQLFeatureNotSupportedException` - If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)
    See Also:
      - `FbStatement.supportsCursorInfo()`

  - ### getCursorInfo

    public final byte[] getCursorInfo(byte[] requestItems, int bufferLength) throws SQLException
    Description copied from interface: `FbStatement`
    Request cursor info.
    Specified by:
      `getCursorInfo` in interface `FbStatement`
    Parameters:
      `requestItems` - Array of info items to request
      `bufferLength` - Response buffer length to use
    Returns:
      Response buffer
    Throws:
      `SQLException` - For errors retrieving or transforming the response
      `SQLFeatureNotSupportedException` - If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)

  - ### getCursorInfoImpl

    protected byte[] getCursorInfoImpl(byte[] requestItems, int bufferLength) throws SQLException
    Implementation of `getCursorInfo(byte[], int)`.

    An implementation should not notify `exceptionListenerDispatcher`, as that is already handled in `getCursorInfo(byte[], int)`.

    Throws:
      `SQLException` - For errors retrieving or transforming the response
      `SQLFeatureNotSupportedException` - If requesting cursor info is not supported (Firebird 4.0 or earlier, or native implementation)
    See Also:
      - `getCursorInfo(byte[], int)`
      - `FbStatement.supportsCursorInfo()`

  - ### getExecutionPlan

    public final String getExecutionPlan() throws SQLException
    Specified by:
      `getExecutionPlan` in interface `FbStatement`
    Returns:
      The execution plan of the currently prepared statement
    Throws:
      `SQLException` - If this statement is closed.

  - ### getExplainedExecutionPlan

    public final String getExplainedExecutionPlan() throws SQLException
    Specified by:
      `getExplainedExecutionPlan` in interface `FbStatement`
    Returns:
      The detailed execution plan of the currently prepared statement
    Throws:
      `SQLException` - If this statement is closed.

  - ### createExecutionPlanProcessor

    protected ExecutionPlanProcessor createExecutionPlanProcessor()
    Returns:
      New instance of `ExecutionPlanProcessor` (or subclass) for this statement.

  - ### getSqlCounts

    public SqlCountHolder getSqlCounts() throws SQLException
    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 interface `FbStatement`
    Returns:
      The SQL counts of the last execution of this statement
    Throws:
      `SQLException` - If this statement is closed, or if this statement is in state `StatementState.CURSOR_OPEN` and not all rows have been fetched.

  - ### createSqlCountProcessor

    protected SqlCountProcessor createSqlCountProcessor()
    Returns:
      New instance of `SqlCountProcessor` (or subclass) for this statement.

  - ### free

    protected abstract void free(int option) throws SQLException
    Frees the currently allocated statement. Either close the cursor with `ISCConstants.DSQL_close` or drop the statement handle using `ISCConstants.DSQL_drop`.
    Parameters:
      `option` - Free option
    Throws:
      `SQLException`

  - ### validateParameters

    public final void validateParameters(RowValue parameters) throws SQLException
    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 interface `FbStatement`
    Parameters:
      `parameters` - Parameter values to validate
    Throws:
      `SQLException` - When the number or type of parameters does not match `FbStatement.getParameterDescriptor()`, or when a parameter has not been set.

  - ### addStatementListener

    public final void addStatementListener(StatementListener statementListener)
    Description copied from interface: `FbStatement`
    Registers a `StatementListener`.
    Specified by:
      `addStatementListener` in interface `FbStatement`
    Parameters:
      `statementListener` - The statement listener

  - ### addWeakStatementListener

    public void addWeakStatementListener(StatementListener statementListener)
    Description copied from interface: `FbStatement`
    Adds a `StatementListener` instance to this database using a weak reference.

    If the listener is already strongly referenced, this call will be ignored

    Specified by:
      `addWeakStatementListener` in interface `FbStatement`
    Parameters:
      `statementListener` - statement listener

  - ### removeStatementListener

    public final void removeStatementListener(StatementListener statementListener)
    Description copied from interface: `FbStatement`
    Removes a `StatementListener`.
    Specified by:
      `removeStatementListener` in interface `FbStatement`
    Parameters:
      `statementListener` - The statement listener

  - ### 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 interface `ExceptionListenable`
    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 interface `ExceptionListenable`
    Parameters:
      `listener` - Listener to remove

  - ### checkStatementValid

    protected final void checkStatementValid() throws SQLException
    Checks if this statement is not in `StatementState.CLOSED`, `StatementState.CLOSING`, `StatementState.NEW` or `StatementState.ERROR`, and throws an `SQLException` if it is.
    Throws:
      `SQLException` - when this statement is closed or in error state

  - ### checkStatementValid

    protected final void checkStatementValid(StatementState ignoreState) throws SQLException
    Performs the same check as `checkStatementValid()`, but considers `ignoreState` as valid.
    Parameters:
      `ignoreState` - the invalid state (see `checkStatementValid()` to ignore
    Throws:
      `SQLException` - when this statement is closed or in error state

  - ### checkStatementHasOpenCursor

    protected final void checkStatementHasOpenCursor() throws SQLException
    Checks if statement is valid with `checkStatementValid()` 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

    public FbTransaction getTransaction()
    Specified by:
      `getTransaction` in interface `FbStatement`
    Returns:
      Transaction currently associated with this statement

  - ### isValidTransactionClass

    protected abstract boolean isValidTransactionClass(Class<? extends FbTransaction> transactionClass)
    Method to decide if a transaction implementation class is valid for the statement implementation.

    Eg a `V10Statement` will only work with an `FbWireTransaction` implementation.

    Parameters:
      `transactionClass` - Class of the transaction
    Returns:
      `true` when the transaction class is valid for the statement implementation.

  - ### setTransaction

    public final void setTransaction(FbTransaction newTransaction) throws SQLException
    Description copied from interface: `FbStatement`
    Associates a transaction with this statement
    Specified by:
      `setTransaction` in interface `FbStatement`
    Parameters:
      `newTransaction` - The transaction
    Throws:
      `SQLException`

  - ### setTimeout

    public void setTimeout(long statementTimeout) throws SQLException
    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 interface `FbStatement`
    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

    public long getTimeout() throws SQLException
    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 interface `FbStatement`
    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:
      - `FbStatement.setTimeout(long)`

  - ### setCursorName

    public final void setCursorName(String cursorName) throws SQLException
    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 on `exceptionListenerDispatcher`. To override the behaviour of this method, implement/override `setCursorNameImpl(String)`.

    Specified by:
      `setCursorName` in interface `FbStatement`
    Parameters:
      `cursorName` - Name of the cursor
    Throws:
      `SQLException` - If this statement is closed, or if the cursor name is set and `cursorName` is different from the current cursor name

  - ### setCursorNameImpl

    protected abstract void setCursorNameImpl(String cursorName) throws SQLException
    Implementation of `setCursorName(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 and `cursorName` is different from the current cursor name

  - ### getCursorName

    protected final String getCursorName()
    Gets the cursor name.

    The cursor name is cleared by a new statement prepare.

    Returns:
      the current cursor name
    Since:
      6

  - ### getAllowedTimeout

    protected long getAllowedTimeout() throws SQLException
    Returns:
      The timeout value, or `0` if the timeout is larger than supported
    Throws:
      `SQLException` - If the statement is invalid

  - ### parseStatementInfo

    protected void parseStatementInfo(byte[] statementInfoResponse) throws SQLException
    Parse the statement info response in `statementInfoResponse`. If the response is truncated, a new request is done using `getStatementInfoRequestItems()`
    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

    protected final OperationCloseHandle signalExecute()
    Signals the start of an execute for this statement.
    Returns:
      `OperationCloseHandle` handle for the operation

  - ### signalFetch

    protected final OperationCloseHandle signalFetch()
    Signals the start of a fetch for this statement.
    Returns:
      `OperationCloseHandle` handle for the operation

  - ### signalAsyncFetchStart

    protected final OperationCloseHandle signalAsyncFetchStart()

  - ### signalAsyncFetchComplete

    protected final OperationCloseHandle signalAsyncFetchComplete()