Class DatabaseAccessor

  • All Implemented Interfaces:
    java.lang.Cloneable, Accessor

    public class DatabaseAccessor
    extends DatasourceAccessor
    INTERNAL: DatabaseAccessor is private to EclipseLink. It encapsulates low level database operations (such as executing SQL and reading data by row). Database accessor defines a protocol by which EclipseLink may invoke these operations.

    DatabaseAccessor also defines a single reference through which all configuration dependent behavior may be invoked.

    DabaseAccessor implements the following behavior.

    • Connect and disconnect from the database.
    • Execute SQL statements on the database, returning results.
    • Handle auto-commit and transactions.
    DatabaseAccessor dispatches the following protocols to its platform reference.
    • Provision of database platform specific type names.
    DatabaseAccessor dispatches the following protocols to the schema object.
    • Creation and deletion of schema objects.
    Since:
    TOPLink/Java 1.0
    See Also:
    DatabasePlatform
    • Field Detail

      • shouldUseDynamicStatements

        public static boolean shouldUseDynamicStatements
        PERF: Backdoor to disabling dynamic statements. Reverts to old prepared statement usage if set.
      • statementCache

        protected java.util.Map<java.lang.String,​java.sql.Statement> statementCache
        Stores statement handles for common used prepared statements.
      • metaData

        protected java.sql.DatabaseMetaData metaData
        Cache of the connection's java.sql.DatabaseMetaData
      • activeBatchWritingMechanism

        protected BatchWritingMechanism activeBatchWritingMechanism
        This attribute will be used to store the currently active Batch Mechanism
      • dynamicSQLMechanism

        protected DynamicSQLBatchWritingMechanism dynamicSQLMechanism
        These two attributes store the available BatchWritingMechanisms. We sacrifice a little space to prevent the work involved in recreating these objects each time a different type of SQL statement is executed. Depending on user behavior we may want to review this.
      • dynamicStatement

        protected java.sql.Statement dynamicStatement
        PERF: Cache the statement object for dynamic SQL execution.
      • isDynamicStatementInUse

        protected boolean isDynamicStatementInUse
    • Constructor Detail

      • DatabaseAccessor

        public DatabaseAccessor()
      • DatabaseAccessor

        public DatabaseAccessor​(java.lang.Object connection)
        Create a database accessor with the given connection.
    • Method Detail

      • getLOBWriter

        public LOBValueWriter getLOBWriter()
        Return the LOBValueWriter instance. Lazily initialize the instance. Bug 2804663.
        See Also:
        LOBValueWriter
      • allocateDynamicStatement

        public java.sql.Statement allocateDynamicStatement​(java.sql.Connection connection)
                                                    throws java.sql.SQLException
        Allocate a statement for dynamic SQL execution. Either return the cached dynamic statement, or a new statement. This statement must be released after execution.
        Throws:
        java.sql.SQLException
      • isDynamicStatementInUse

        public boolean isDynamicStatementInUse()
        Return the cached statement for dynamic SQL execution is in use. Used to handle concurrency for the dynamic statement, this method must only be called from within a synchronized method/block.
      • setIsDynamicStatementInUse

        public void setIsDynamicStatementInUse​(boolean isDynamicStatementInUse)
        Set if the cached statement for dynamic SQL execution is in use. Used to handle concurrency for the dynamic statement.
      • buildConnectLog

        protected void buildConnectLog​(AbstractSession session)
        If logging is turned on and the JDBC implementation supports meta data then display connection info.
        Specified by:
        buildConnectLog in class DatasourceAccessor
      • buildSortedFields

        public java.util.Vector buildSortedFields​(java.util.Vector fields,
                                                  java.sql.ResultSet resultSet,
                                                  AbstractSession session)
                                           throws DatabaseException
        Return the field sorted in the correct order corresponding to the result set. This is used for cursored selects where custom sql was provided. If the fields passed in are null, this means that the field are not known and should be built from the column names. This case occurs for DataReadQuery's.
        Throws:
        DatabaseException
      • checkTransactionIsolation

        protected void checkTransactionIsolation​(AbstractSession session)
                                          throws DatabaseException
        Check to see if the transaction isolation needs to be set for the newly created connection. This must be done outside of a transaction. Exceptions are caught and re-thrown as EclipseLink exceptions.
        Throws:
        DatabaseException
      • clearStatementCache

        public void clearStatementCache​(AbstractSession session)
        Flush the statement cache. Each statement must first be closed.
      • closeStatement

        public void closeStatement​(java.sql.Statement statement,
                                   AbstractSession session,
                                   DatabaseCall call)
                            throws java.sql.SQLException
        INTERNAL: Closes a PreparedStatement (which is supposed to close it's current resultSet). Factored out to simplify coding and handle exceptions.
        Throws:
        java.sql.SQLException
      • cursorRetrieveNextRow

        public AbstractRecord cursorRetrieveNextRow​(java.util.Vector fields,
                                                    java.sql.ResultSet resultSet,
                                                    AbstractSession session)
                                             throws DatabaseException
        Advance the result set and return a Record populated with values from the next valid row in the result set. Intended solely for cursored stream support.
        Throws:
        DatabaseException
      • cursorRetrievePreviousRow

        public AbstractRecord cursorRetrievePreviousRow​(java.util.Vector fields,
                                                        java.sql.ResultSet resultSet,
                                                        AbstractSession session)
                                                 throws DatabaseException
        Advance the result set and return a DatabaseRow populated with values from the next valid row in the result set. Intended solely for scrollable cursor support.
        Throws:
        DatabaseException
      • closeConnection

        public void closeConnection()
        Close the accessor's connection. This is used only for external connection pooling when it is intended for the connection to be reconnected in the future.
        Specified by:
        closeConnection in interface Accessor
        Overrides:
        closeConnection in class DatasourceAccessor
      • executeBatchedStatement

        protected void executeBatchedStatement​(java.sql.PreparedStatement statement,
                                               AbstractSession session)
                                        throws DatabaseException
        Execute the EclipseLink dynamically batched/concatenated statement.
        Throws:
        DatabaseException
      • basicExecuteCall

        public java.lang.Object basicExecuteCall​(Call call,
                                                 AbstractRecord translationRow,
                                                 AbstractSession session)
                                          throws DatabaseException
        Execute the call. The execution can differ slightly depending on the type of call. The call may be parameterized where the arguments are in the translation row. The row will be empty if there are no parameters.
        Specified by:
        basicExecuteCall in class DatasourceAccessor
        Returns:
        depending of the type either the row count, row or vector of rows.
        Throws:
        DatabaseException
      • basicExecuteCall

        public java.lang.Object basicExecuteCall​(Call call,
                                                 AbstractRecord translationRow,
                                                 AbstractSession session,
                                                 boolean batch)
                                          throws DatabaseException
        Execute the call. The execution can differ slightly depending on the type of call. The call may be parameterized where the arguments are in the translation row. The row will be empty if there are no parameters.
        Returns:
        depending of the type either the row count, row or vector of rows.
        Throws:
        DatabaseException
      • processResultSet

        public java.lang.Object processResultSet​(java.sql.ResultSet resultSet,
                                                 DatabaseCall call,
                                                 java.sql.Statement statement,
                                                 AbstractSession session)
                                          throws java.sql.SQLException
        Fetch all the rows from the result set.
        Throws:
        java.sql.SQLException
      • buildThreadCursoredResult

        protected java.util.Vector buildThreadCursoredResult​(DatabaseCall dbCall,
                                                             java.sql.ResultSet resultSet,
                                                             java.sql.Statement statement,
                                                             java.sql.ResultSetMetaData metaData,
                                                             AbstractSession session)
        This allows for the rows to be fetched concurrently to the objects being built. This code is not currently publicly supported.
      • execute

        public boolean execute​(DatabaseCall call,
                               java.sql.Statement statement,
                               AbstractSession session)
                        throws java.sql.SQLException
        Execute the statement.
        Throws:
        java.sql.SQLException
      • executeSelect

        public java.sql.ResultSet executeSelect​(DatabaseCall call,
                                                java.sql.Statement statement,
                                                AbstractSession session)
                                         throws java.sql.SQLException
        Execute the statement.
        Throws:
        java.sql.SQLException
      • fetchRow

        protected AbstractRecord fetchRow​(java.util.Vector fields,
                                          java.sql.ResultSet resultSet,
                                          java.sql.ResultSetMetaData metaData,
                                          AbstractSession session)
                                   throws DatabaseException
        Return a new DatabaseRow.

        Populate the row from the data in cursor. The fields representing the results and the order of the results are stored in fields.

        NOTE: Make sure that the field name is set. An empty field name placeholder is used in the sortFields() method when the number of fields defined does not match the number of column names available on the database. PERF: This method must be highly optimized.

        Throws:
        DatabaseException
      • fetchRow

        public AbstractRecord fetchRow​(java.util.Vector fields,
                                       DatabaseField[] fieldsArray,
                                       java.sql.ResultSet resultSet,
                                       java.sql.ResultSetMetaData metaData,
                                       AbstractSession session)
                                throws DatabaseException
        Return a new DatabaseRow.

        Populate the row from the data in cursor. The fields representing the results and the order of the results are stored in fields.

        NOTE: Make sure that the field name is set. An empty field name placeholder is used in the sortFields() method when the number of fields defined does not match the number of column names available on the database. PERF: This method must be highly optimized.

        Throws:
        DatabaseException
      • getActiveBatchWritingMechanism

        public BatchWritingMechanism getActiveBatchWritingMechanism​(AbstractSession session)
        INTERNAL: This method is used internally to return the active batch writing mechanism to batch the statement
      • getColumnInfo

        public java.util.Vector getColumnInfo​(java.lang.String catalog,
                                              java.lang.String schema,
                                              java.lang.String tableName,
                                              java.lang.String columnName,
                                              AbstractSession session)
                                       throws DatabaseException
        Get a description of table columns available in a catalog.

        Only column descriptions matching the catalog, schema, table and column name criteria are returned. They are ordered by TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.

        Each column description has the following columns:

        1. TABLE_CAT String => table catalog (may be null)
        2. TABLE_SCHEM String => table schema (may be null)
        3. TABLE_NAME String => table name
        4. COLUMN_NAME String => column name
        5. DATA_TYPE short => SQL type from java.sql.Types
        6. TYPE_NAME String => Data source dependent type name
        7. COLUMN_SIZE int => column size. For char or date types this is the maximum number of characters, for numeric or decimal types this is precision.
        8. BUFFER_LENGTH is not used.
        9. DECIMAL_DIGITS int => the number of fractional digits
        10. NUM_PREC_RADIX int => Radix (typically either 10 or 2)
        11. NULLABLE int => is NULL allowed?
          • columnNoNulls - might not allow NULL values
          • columnNullable - definitely allows NULL values
          • columnNullableUnknown - nullability unknown
        12. REMARKS String => comment describing column (may be null)
        13. COLUMN_DEF String => default value (may be null)
        14. SQL_DATA_TYPE int => unused
        15. SQL_DATETIME_SUB int => unused
        16. CHAR_OCTET_LENGTH int => for char types the maximum number of bytes in the column
        17. ORDINAL_POSITION int => index of column in table (starting at 1)
        18. IS_NULLABLE String => "NO" means column definitely does not allow NULL values; "YES" means the column might allow NULL values. An empty string means nobody knows.
        Specified by:
        getColumnInfo in interface Accessor
        Overrides:
        getColumnInfo in class DatasourceAccessor
        Parameters:
        catalog - a catalog name; "" retrieves those without a catalog; null means drop catalog name from the selection criteria
        schemaPattern - a schema name pattern; "" retrieves those without a schema
        tableNamePattern - a table name pattern
        columnNamePattern - a column name pattern
        Returns:
        a Vector of DatabaseRows.
        Throws:
        DatabaseException
      • getColumnNames

        protected java.util.Vector getColumnNames​(java.sql.ResultSet resultSet,
                                                  AbstractSession session)
                                           throws java.sql.SQLException
        Return the column names from a result sets meta data as a vector of DatabaseFields. This is required for custom SQL execution only, as generated SQL already knows the fields returned.
        Throws:
        java.sql.SQLException
      • getConnectionMetaData

        public java.sql.DatabaseMetaData getConnectionMetaData()
                                                        throws java.sql.SQLException
        return the cached metaData
        Throws:
        java.sql.SQLException
      • getObject

        public java.lang.Object getObject​(java.sql.ResultSet resultSet,
                                          DatabaseField field,
                                          java.sql.ResultSetMetaData metaData,
                                          int columnNumber,
                                          DatabasePlatform platform,
                                          boolean optimizeData,
                                          AbstractSession session)
                                   throws DatabaseException
        Return an object retrieved from resultSet with the getObject() method. Optimize the get for certain type to avoid double conversion. NOTE: This method handles a virtual machine error thrown when retrieving times & dates from Oracle or Sybase.
        Throws:
        DatabaseException
      • getObjectThroughOptimizedDataConversion

        protected java.lang.Object getObjectThroughOptimizedDataConversion​(java.sql.ResultSet resultSet,
                                                                           DatabaseField field,
                                                                           int type,
                                                                           int columnNumber,
                                                                           DatabasePlatform platform,
                                                                           AbstractSession session)
                                                                    throws java.sql.SQLException
        Handle the conversion into java optimally through calling the direct type API. If the type is not one that can be optimized return null.
        Throws:
        java.sql.SQLException
      • hasStatementCache

        protected boolean hasStatementCache()
        Return if the accessor has any cached statements. This should be used to avoid lazy instantiation of the cache.
      • getStatementCache

        protected java.util.Map<java.lang.String,​java.sql.Statement> getStatementCache()
        The statement cache stores a fixed sized number of prepared statements.
      • getTableInfo

        public java.util.Vector getTableInfo​(java.lang.String catalog,
                                             java.lang.String schema,
                                             java.lang.String tableName,
                                             java.lang.String[] types,
                                             AbstractSession session)
                                      throws DatabaseException
        Get a description of tables available in a catalog.

        Only table descriptions matching the catalog, schema, table name and type criteria are returned. They are ordered by TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.

        Each table description has the following columns:

        1. TABLE_CAT String => table catalog (may be null)
        2. TABLE_SCHEM String => table schema (may be null)
        3. TABLE_NAME String => table name
        4. TABLE_TYPE String => table type. Typical types are "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
        5. REMARKS String => explanatory comment on the table

        Note: Some databases may not return information for all tables.

        Specified by:
        getTableInfo in interface Accessor
        Overrides:
        getTableInfo in class DatasourceAccessor
        Parameters:
        catalog - a catalog name; "" retrieves those without a catalog; null means drop catalog name from the selection criteria
        schemaPattern - a schema name pattern; "" retrieves those without a schema
        tableNamePattern - a table name pattern
        types - a list of table types to include; null returns all types
        Returns:
        a Vector of DatabaseRows.
        Throws:
        DatabaseException
      • isDatasourceConnected

        public boolean isDatasourceConnected()
        Return true if the receiver is currently connected to a data source. Return false otherwise.
        Specified by:
        isDatasourceConnected in class DatasourceAccessor
      • isInBatchWritingMode

        protected boolean isInBatchWritingMode​(AbstractSession session)
        Return the batch writing mode.
      • prepareStatement

        public java.sql.Statement prepareStatement​(DatabaseCall call,
                                                   AbstractSession session)
                                            throws java.sql.SQLException
        Prepare the SQL statement for the call. First check if the statement is cached before building a new one. Currently the SQL string is used as the cache key, this may have to be switched if it becomes a performance problem.
        Throws:
        java.sql.SQLException
      • prepareStatement

        public java.sql.Statement prepareStatement​(DatabaseCall call,
                                                   AbstractSession session,
                                                   boolean unwrapConnection)
                                            throws java.sql.SQLException
        Prepare the SQL statement for the call. First check if the statement is cached before building a new one.
        Parameters:
        unwrapConnection - boolean flag set to true to unwrap the connection before preparing the statement in the case of a parameterized call.
        Throws:
        java.sql.SQLException
      • prepareStatement

        public java.sql.PreparedStatement prepareStatement​(java.lang.String sql,
                                                           AbstractSession session,
                                                           boolean callable)
                                                    throws java.sql.SQLException
        Prepare the SQL statement for the call. First check if the statement is cached before building a new one.
        Throws:
        java.sql.SQLException
      • processExceptionForCommError

        public DatabaseException processExceptionForCommError​(AbstractSession session,
                                                              java.sql.SQLException exception,
                                                              Call call)
        This method is used to process an SQL exception and determine if the exception should be passed on for further processing. If the Exception was communication based then a DatabaseException will be return. If the method did not process the message of it was not a comm failure then null will be returned.
      • reconnect

        protected void reconnect​(AbstractSession session)
        Attempt to save some of the cost associated with getting a fresh connection. Assume the DatabaseDriver has been cached, if appropriate. Note: Connections that are participating in transactions will not be refreshed.^M Added for bug 3046465 to ensure the statement cache is cleared
        Overrides:
        reconnect in class DatasourceAccessor
      • releaseStatement

        public void releaseStatement​(java.sql.Statement statement,
                                     java.lang.String sqlString,
                                     DatabaseCall call,
                                     AbstractSession session)
                              throws java.sql.SQLException
        Release the statement through closing it or putting it back in the statement cache.
        Throws:
        java.sql.SQLException
      • resetStatementFromCall

        protected void resetStatementFromCall​(java.sql.Statement statement,
                                              DatabaseCall call)
                                       throws java.sql.SQLException
        Reset the Query Timeout, Max Rows, Resultset fetch size on the Statement if the DatabaseCall has values which differ from the default settings. For Bug 5709179 - reset settings on cached statements
        Throws:
        java.sql.SQLException
      • setActiveBatchWritingMechanismToParameterizedSQL

        public void setActiveBatchWritingMechanismToParameterizedSQL()
        INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
      • setActiveBatchWritingMechanismToDynamicSQL

        public void setActiveBatchWritingMechanismToDynamicSQL()
        INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
      • setActiveBatchWritingMechanism

        public void setActiveBatchWritingMechanism​(BatchWritingMechanism mechanism)
        INTERNAL: This method is used to set the active Batch Mechanism on the accessor.
      • setStatementCache

        protected void setStatementCache​(java.util.Hashtable statementCache)
        The statement cache stores a fixed sized number of prepared statements.
      • sortFields

        protected java.util.Vector sortFields​(java.util.Vector fields,
                                              java.util.Vector columnNames)
        This method will sort the fields in correct order based on the column names.
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • isBlob

        public static boolean isBlob​(int type)
        Return if the JDBC type is a binary type such as blob.
      • isClob

        public static boolean isClob​(int type)
        Return if the JDBC type is a large character type such as clob.
      • writesCompleted

        public void writesCompleted​(AbstractSession session)
        This method will be called after a series of writes have been issued to mark where a particular set of writes has completed. It will be called from commitTransaction and may be called from writeChanges. Its main purpose is to ensure that the batched statements have been executed
        Specified by:
        writesCompleted in interface Accessor
        Overrides:
        writesCompleted in class DatasourceAccessor