Class AbstractDatabaseProvider

java.lang.Object
org.litebridgedb.db.spi.impl.AbstractDatabaseProvider
All Implemented Interfaces:
DatabaseProvider
Direct Known Subclasses:
H2DatabaseProvider, OracleDatabaseProvider

public abstract class AbstractDatabaseProvider extends Object implements DatabaseProvider
An abstract implementation of the DatabaseProvider interface that provides a framework for interacting with a database by managing SQL queries, metadata retrieval, and type conversions. This class serves as a base for specific database implementations, handling common functionality while leaving database-specific details to subclasses.

This class includes utility methods for preparing and executing SQL statements, fetching table metadata, and performing insert, update, and select operations. It uses a caching mechanism for table metadata to improve efficiency and ensures type conversion using a pluggable TypeConverter.

  • Constructor Details

    • AbstractDatabaseProvider

      public AbstractDatabaseProvider(TypeConverter typeConverter)
  • Method Details

    • tableMetaData

      public TableMetaData tableMetaData(Table table, ConnectionProvider connectionProvider) throws SQLException
      Description copied from interface: DatabaseProvider
      Retrieve metadata for the specified table.
      Specified by:
      tableMetaData in interface DatabaseProvider
      Parameters:
      table - the Table object representing the table for which metadata is to be retrieved.
      connectionProvider - the ConnectionProvider used to get a database connection.
      Returns:
      a TableMetaData object containing metadata information about the specified table, including its columns, primary key, and other details.
      Throws:
      SQLException - if any SQL error occurs while retrieving the metadata.
    • insert

      public InsertResult insert(Insert insert, ConnectionProvider connectionProvider) throws SQLException
      Description copied from interface: DatabaseProvider
      Execute an INSERT operation in the database using the provided Insert statement.
      Specified by:
      insert in interface DatabaseProvider
      Parameters:
      insert - the Insert statement containing the table, columns, and rows to insert.
      connectionProvider - the ConnectionProvider used to get a database connection.
      Returns:
      an InsertResult containing the number of rows affected and any generated keys.
      Throws:
      SQLException - if any SQL error occurs during the execution of the insert operation.
    • update

      public UpdateResult update(Update update, ConnectionProvider connectionProvider) throws SQLException
      Description copied from interface: DatabaseProvider
      Execute an UPDATE operation in the database using the provided Update statement.
      Specified by:
      update in interface DatabaseProvider
      Parameters:
      update - the Update statement containing the table, columns, and rows to update.
      connectionProvider - the ConnectionProvider used to get a database connection.
      Returns:
      an UpdateResult containing the number of rows affected.
      Throws:
      SQLException - if any SQL error occurs during the execution of the update operation.
    • select

      public List<Row> select(Select select, ConnectionProvider connectionProvider) throws SQLException
      Description copied from interface: DatabaseProvider
      Execute a SELECT operation in the database using the provided Select statement.
      Specified by:
      select in interface DatabaseProvider
      Parameters:
      select - the Select statement containing information about the table, columns, joins, conditions, ordering, and optional limits for the query.
      connectionProvider - the ConnectionProvider used to get a database connection.
      Returns:
      a List of Row objects representing the results of the SELECT operation.
      Throws:
      SQLException - if any SQL error occurs during the execution of the SELECT operation.
    • delete

      public UpdateResult delete(Delete delete, ConnectionProvider connectionProvider) throws SQLException
      Specified by:
      delete in interface DatabaseProvider
      Throws:
      SQLException
    • getTypeConverter

      public TypeConverter getTypeConverter()
      Description copied from interface: DatabaseProvider
      Retrieve the TypeConverter instance associated with the database provider.

      The TypeConverter is used for converting objects between different types, typically for database data type conversions and mapping domain-specific representations.

      Specified by:
      getTypeConverter in interface DatabaseProvider
      Returns:
      the TypeConverter instance for handling data type conversions
    • toSql

      public String toSql(Select select)
      Specified by:
      toSql in interface DatabaseProvider
    • createSequenceNextValueForDirectInsert

      protected String createSequenceNextValueForDirectInsert(String sequence)
      Generate a SQL fragment to retrieve the next value from a sequence for direct use in an INSERT or UPDATE statement, e.g. to generate "INSERT INTO LB.ACCOUNT(ACCOUNT_ID, ACCOUNT_NAME) VALUES (NEXT VALUE FOR sequence_name, ?)", this method returns "NEXT VALUE FOR sequence_name".
      Parameters:
      sequence - the name of the database sequence to generate the next value from
      Returns:
      a formatted SQL string representing the next sequence value for direct insertion
    • prepareSql

      protected AbstractDatabaseProvider.PreparedSql prepareSql(Insert insert, ConnectionProvider connectionProvider) throws SQLException
      Prepare a SQL INSERT statement along with its bind values for execution.

      This method constructs the SQL query string based on the provided Insert object, which contains the table's metadata, columns, and rows to be inserted. The bind values are derived from the rows and included in the returned AbstractDatabaseProvider.PreparedSql.

      Parameters:
      insert - the Insert object containing the table metadata, columns, and rows for the SQL INSERT operation
      Returns:
      a AbstractDatabaseProvider.PreparedSql object containing the generated SQL query string and the list of bind values
      Throws:
      SQLException
    • prepareSql

      protected AbstractDatabaseProvider.PreparedSql prepareSql(Update update, ConnectionProvider connectionProvider) throws SQLException
      Prepare a SQL UPDATE statement along with its bind values for execution.

      This method constructs the SQL query string based on the provided Update object, which contains the table's metadata, column-value pairs, and conditions for the WHERE clause. It ensures proper formatting of the SQL query and converts values as needed using a type converter. The resulting SQL query and its associated bind values are encapsulated in a AbstractDatabaseProvider.PreparedSql object.

      Parameters:
      update - the Update object containing table metadata, column-value pairs for the SET clause, and conditions for the WHERE clause to specify target rows.
      Returns:
      a AbstractDatabaseProvider.PreparedSql object containing the generated SQL query string and the list of bind values.
      Throws:
      SQLException
    • createMathOperation

      protected String createMathOperation(ColumnMetaData column, MathOperation mathOperation)
    • prepareSql

      protected AbstractDatabaseProvider.PreparedSql prepareSql(Delete delete, ConnectionProvider connectionProvider) throws SQLException
      Throws:
      SQLException
    • createJoin

      protected String createJoin(Join join)
      Create a SQL JOIN clause based on the provided Join object.

      The join clause is constructed by specifying the target table, optional schema, and any associated conditions for the join operation. Conditional logic is applied to determine the join type (e.g., ON or USING) and format the resulting SQL string.

      Parameters:
      join - the Join object containing the target table information and the list of conditions defining the join relationship
      Returns:
      a String representing the constructed SQL join clause
    • createCondition

      protected String createCondition(Condition condition, @Nullable Select select)
      Generate a SQL condition string based on the given Condition. This method constructs the SQL fragment by combining the column, operator, and value (if applicable) for the provided condition.
      Parameters:
      condition - the Condition object specifying the column, operator, and value for the SQL condition
      Returns:
      a String representing the constructed SQL condition fragment
    • appendTable

      protected StringBuilder appendTable(StringBuilder sql, Table table)
    • appendTable

      protected StringBuilder appendTable(StringBuilder sql, TableMetaData table)
    • appendTable

      protected StringBuilder appendTable(StringBuilder sql, String schema, String table)
    • createColumnIdentifier

      protected String createColumnIdentifier(Column column, boolean includeColumnAlias, @Nullable Select select)
    • mapOperator

      protected String mapOperator(Operator operator)
      Map an Operator enum to its corresponding string representation used in logical or database operations.
      Parameters:
      operator - the Operator enum to be mapped
      Returns:
      the string representation of the provided Operator
    • executeSqlInsert

      protected InsertResult executeSqlInsert(AbstractDatabaseProvider.PreparedSql preparedSql, TableMetaData tableMetaData, boolean returnGeneratedKeys, ConnectionProvider connectionProvider) throws SQLException
      Execute a SQL INSERT operation using the provided prepared SQL statement and table metadata.

      This method executes the prepared statement, retrieves any generated primary key values, and wraps the results in an InsertResult object.

      Parameters:
      preparedSql - the AbstractDatabaseProvider.PreparedSql object containing the SQL query string and bind values to be executed
      tableMetaData - the TableMetaData object containing the metadata of the target table, including primary key information
      returnGeneratedKeys - a boolean indicating whether the statement should return generated keys. Pass true to configure the statement to return generated keys, or false otherwise.
      Returns:
      an InsertResult object encapsulating the number of affected rows and a list of generated keys (if any)
      Throws:
      SQLException - if an error occurs while executing the SQL insert or retrieving the generated keys
    • getGeneratedPrimaryKeyColumns

      protected List<ColumnMetaData> getGeneratedPrimaryKeyColumns(TableMetaData tableMetaData)
    • extractGeneratedKeys

      protected Map<ColumnMetaData,Object> extractGeneratedKeys(TableMetaData tableMetaData, PreparedStatement preparedStatement) throws SQLException
      Throws:
      SQLException
    • executeSqlUpdate

      protected UpdateResult executeSqlUpdate(AbstractDatabaseProvider.PreparedSql preparedSql, TableMetaData tableMetaData, ConnectionProvider connectionProvider) throws SQLException
      Execute a SQL UPDATE operation using the provided prepared SQL statement and table metadata.

      This method performs the execution of a prepared update statement and wraps the number of affected rows in an UpdateResult object.

      Parameters:
      preparedSql - the AbstractDatabaseProvider.PreparedSql object containing the SQL query string and bind values to be executed
      connectionProvider - the ConnectionProvider used to obtain a database connection.
      Returns:
      an UpdateResult object encapsulating the number of rows affected by the update operation
      Throws:
      SQLException - if an error occurs while executing the SQL update
    • transformAlias

      protected @Nullable String transformAlias(@Nullable String dbAlias)
    • getColumnNames

      protected List<ColumnMetaData> getColumnNames(Table table, DatabaseMetaData databaseMetaData) throws SQLException
      Throws:
      SQLException
    • getPrimaryKeyColumnNames

      protected List<String> getPrimaryKeyColumnNames(Table table, DatabaseMetaData databaseMetaData) throws SQLException
      Throws:
      SQLException
    • verifySchemaAndTableExists

      protected static void verifySchemaAndTableExists(Table table, DatabaseMetaData databaseMetaData) throws SQLException
      Throws:
      SQLException
    • prepareStatement

      protected PreparedStatement prepareStatement(AbstractDatabaseProvider.PreparedSql preparedSql, boolean returnGeneratedKeys, TableMetaData tableMetaData, ConnectionProvider connectionProvider) throws SQLException
      Prepare a PreparedStatement object based on the provided SQL and bind values.

      Optionally, the statement can be configured to return generated keys.

      Parameters:
      preparedSql - the AbstractDatabaseProvider.PreparedSql object containing the SQL query and associated bind values.
      returnGeneratedKeys - a boolean indicating whether the statement should return generated keys. Pass true to configure the statement to return generated keys, or false otherwise.
      tableMetaData - Meta-data for the current table
      connectionProvider - the ConnectionProvider used to obtain a database connection.
      Returns:
      a PreparedStatement that is ready to be executed based on the provided SQL and bind values.
      Throws:
      SQLException - if a database access error occurs or the preparation of the SQL statement fails.
    • createPreparedStatementUsingConnection

      protected PreparedStatement createPreparedStatementUsingConnection(AbstractDatabaseProvider.PreparedSql preparedSql, boolean returnGeneratedKeys, TableMetaData tableMetaData, ManagedConnection connection) throws SQLException
      Throws:
      SQLException
    • getLogger

      protected org.slf4j.Logger getLogger()
      Return the logger instance for this database provider.
      Returns:
      the logger instance
    • prepareRow

      protected AbstractDatabaseProvider.PreparedRow prepareRow(RowValue rowValue, ConnectionProvider connectionProvider) throws SQLException
      Prepare a row for insertion based on the provided row value. This includes processing column values, converting them to a suitable format, and generating value specifiers and bind values for the prepared row. Handles nullable columns, auto-increment columns, and sequence-based value generation as necessary.
      Parameters:
      rowValue - the row value object containing the column definitions and their values
      Returns:
      a PreparedRow instance containing processed value specifiers and bind values
      Throws:
      IllegalArgumentException - if a non-nullable column without an auto-increment or sequence value is attempted to be set to NULL
      SQLException
    • fetchTableMetaData

      protected TableMetaData fetchTableMetaData(Table table, ConnectionProvider connectionProvider) throws SQLException
      Retrieve metadata for the specified table, including its primary keys and columns.

      This executes a database query to fetch database metadata.

      Parameters:
      table - the table for which metadata is being fetched, containing schema, catalog, and table name details
      Returns:
      a TableMetaData object containing details about the table's structure, primary keys, and column metadata
      Throws:
      SQLException - if an error occurs while fetching database metadata
    • quoteIdentifier

      protected @Nullable String quoteIdentifier(@Nullable String identifier)
    • createAlias

      protected String createAlias(String alias)
    • appendLimitClause

      protected void appendLimitClause(Limit limit, StringBuilder sql)
    • ensureColumnMetaData

      protected ColumnMetaData ensureColumnMetaData(Column column, ConnectionProvider connectionProvider) throws SQLException
      Throws:
      SQLException