Class JdbcConnection

  • All Implemented Interfaces:
    AutoCloseable

    @NotThreadSafe
    public class JdbcConnection
    extends Object
    implements AutoCloseable
    A utility that simplifies using a JDBC connection and executing transactions composed of multiple statements.
    Author:
    Randall Hauch
    • Constructor Detail

      • JdbcConnection

        public JdbcConnection​(Configuration config,
                              JdbcConnection.ConnectionFactory connectionFactory,
                              String openingQuoteCharacter,
                              String closingQuoteCharacter)
        Create a new instance with the given configuration and connection factory.
        Parameters:
        config - the configuration; may not be null
        connectionFactory - the connection factory; may not be null
      • JdbcConnection

        public JdbcConnection​(Configuration config,
                              JdbcConnection.ConnectionFactory connectionFactory,
                              Supplier<ClassLoader> classLoaderSupplier,
                              String openingQuoteCharacter,
                              String closingQuoteCharacter)
        Create a new instance with the given configuration and connection factory.
        Parameters:
        config - the configuration; may not be null
        connectionFactory - the connection factory; may not be null
      • JdbcConnection

        protected JdbcConnection​(Configuration config,
                                 JdbcConnection.ConnectionFactory connectionFactory,
                                 JdbcConnection.Operations initialOperations,
                                 Consumer<Configuration.Builder> adapter,
                                 String openingQuotingChar,
                                 String closingQuotingChar)
        Create a new instance with the given configuration and connection factory, and specify the operations that should be run against each newly-established connection.
        Parameters:
        config - the configuration; may not be null
        connectionFactory - the connection factory; may not be null
        initialOperations - the initial operations that should be run on each new connection; may be null
        adapter - the function that can be called to update the configuration with defaults
      • JdbcConnection

        protected JdbcConnection​(Configuration config,
                                 JdbcConnection.ConnectionFactory connectionFactory,
                                 JdbcConnection.Operations initialOperations,
                                 Consumer<Configuration.Builder> adapter,
                                 Supplier<ClassLoader> classLoaderSupplier,
                                 String openingQuotingChar,
                                 String closingQuotingChar)
        Create a new instance with the given configuration and connection factory, and specify the operations that should be run against each newly-established connection.
        Parameters:
        config - the configuration; may not be null
        connectionFactory - the connection factory; may not be null
        initialOperations - the initial operations that should be run on each new connection; may be null
        adapter - the function that can be called to update the configuration with defaults
        classLoaderSupplier - class loader supplier
        openingQuotingChar - the opening quoting character
        closingQuotingChar - the closing quoting character
    • Method Detail

      • patternBasedFactory

        public static JdbcConnection.ConnectionFactory patternBasedFactory​(String urlPattern,
                                                                           Field... variables)
        Create a JdbcConnection.ConnectionFactory that replaces variables in the supplied URL pattern. Variables include:
        • ${hostname}
        • ${port}
        • ${dbname}
        • ${username}
        • ${password}
        Parameters:
        urlPattern - the URL pattern string; may not be null
        variables - any custom or overridden configuration variables
        Returns:
        the connection factory
      • patternBasedFactory

        public static JdbcConnection.ConnectionFactory patternBasedFactory​(String urlPattern,
                                                                           String driverClassName,
                                                                           ClassLoader classloader,
                                                                           Field... variables)
        Create a JdbcConnection.ConnectionFactory that uses the specific JDBC driver class loaded with the given class loader, and obtains the connection URL by replacing the following variables in the URL pattern:
        • ${hostname}
        • ${port}
        • ${dbname}
        • ${username}
        • ${password}

        This method attempts to instantiate the JDBC driver class and use that instance to connect to the database.

        Parameters:
        urlPattern - the URL pattern string; may not be null
        driverClassName - the name of the JDBC driver class; may not be null
        classloader - the ClassLoader that should be used to load the JDBC driver class given by `driverClassName`; may be null if this class' class loader should be used
        variables - any custom or overridden configuration variables
        Returns:
        the connection factory
      • combineVariables

        private static Field[] combineVariables​(Field[] overriddenVariables,
                                                Field... defaultVariables)
      • config

        public JdbcConfiguration config()
        Obtain the configuration for this connection.
        Returns:
        the JDBC configuration; never null
      • connect

        public JdbcConnection connect()
                               throws SQLException
        Ensure a connection to the database is established.
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database
      • execute

        public JdbcConnection execute​(String... sqlStatements)
                               throws SQLException
        Execute a series of SQL statements as a single transaction.
        Parameters:
        sqlStatements - the SQL statements that are to be performed as a single transaction
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • execute

        public JdbcConnection execute​(JdbcConnection.Operations operations)
                               throws SQLException
        Execute a series of operations as a single transaction.
        Parameters:
        operations - the function that will be called with a newly-created Statement, and that performs one or more operations on that statement object
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
      • queryAndMap

        public <T> T queryAndMap​(String query,
                                 JdbcConnection.ResultSetMapper<T> mapper)
                          throws SQLException
        Execute a SQL query and map the result set into an expected type.
        Type Parameters:
        T - type returned by the mapper
        Parameters:
        query - the SQL query
        mapper - the function processing the query results
        Returns:
        the result of the mapper calculation
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • queryAndMap

        public <T> T queryAndMap​(String query,
                                 JdbcConnection.StatementFactory statementFactory,
                                 JdbcConnection.ResultSetMapper<T> mapper)
                          throws SQLException
        Execute a SQL query and map the result set into an expected type.
        Type Parameters:
        T - type returned by the mapper
        Parameters:
        query - the SQL query
        statementFactory - the function that should be used to create the statement from the connection; may not be null
        mapper - the function processing the query results
        Returns:
        the result of the mapper calculation
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • prepareQuery

        public JdbcConnection prepareQuery​(String preparedQueryString)
                                    throws SQLException
        Executes a SQL query, preparing it if encountering it for the first time.
        Parameters:
        preparedQueryString - the prepared query string
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
      • prepareQueryAndMap

        public <T> T prepareQueryAndMap​(String preparedQueryString,
                                        JdbcConnection.StatementPreparer preparer,
                                        JdbcConnection.ResultSetMapper<T> mapper)
                                 throws SQLException
        Execute a SQL prepared query and map the result set into an expected type..
        Type Parameters:
        T - type returned by the mapper
        Parameters:
        preparedQueryString - the prepared query string
        preparer - the function that supplied arguments to the prepared statement; may not be null
        mapper - the function processing the query results
        Returns:
        the result of the mapper calculation
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • prepareUpdate

        public JdbcConnection prepareUpdate​(String stmt,
                                            JdbcConnection.StatementPreparer preparer)
                                     throws SQLException
        Execute a SQL update via a prepared statement.
        Parameters:
        stmt - the statement string
        preparer - the function that supplied arguments to the prepared stmt; may be null
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • prepareQuery

        public JdbcConnection prepareQuery​(String preparedQueryString,
                                           List<?> parameters,
                                           JdbcConnection.ParameterResultSetConsumer resultConsumer)
                                    throws SQLException
        Execute a SQL prepared query.
        Parameters:
        preparedQueryString - the prepared query string
        parameters - the list of values for parameters in the query; may not be null
        resultConsumer - the consumer of the query results
        Returns:
        this object for chaining methods together
        Throws:
        SQLException - if there is an error connecting to the database or executing the statements
        See Also:
        execute(Operations)
      • print

        public void print​(ResultSet resultSet)
      • delimiter

        private String delimiter​(int columnCount,
                                 int[] columnSizes)
      • parseSqlStatementString

        protected List<String> parseSqlStatementString​(String statements)
      • readAllCatalogNames

        public Set<String> readAllCatalogNames()
                                        throws SQLException
        Get the names of all of the catalogs.
        Returns:
        the set of catalog names; never null but possibly empty
        Throws:
        SQLException - if an error occurs while accessing the database metadata
      • readAllSchemaNames

        public Set<String> readAllSchemaNames​(Predicate<String> filter)
                                       throws SQLException
        Get the names of all of the schemas, optionally applying a filter.
        Parameters:
        filter - a Predicate to test each schema name; may be null in which case all schema names are returned
        Returns:
        the set of catalog names; never null but possibly empty
        Throws:
        SQLException - if an error occurs while accessing the database metadata
      • readAllTableNames

        public Set<TableId> readAllTableNames​(String[] tableTypes)
                                       throws SQLException
        Get the identifiers of all available tables.
        Parameters:
        tableTypes - the set of table types to include in the results, which may be null for all table types
        Returns:
        the set of TableIds; never null but possibly empty
        Throws:
        SQLException - if an error occurs while accessing the database metadata
      • readTableNames

        public Set<TableId> readTableNames​(String databaseCatalog,
                                           String schemaNamePattern,
                                           String tableNamePattern,
                                           String[] tableTypes)
                                    throws SQLException
        Get the identifiers of the tables.
        Parameters:
        databaseCatalog - the name of the catalog, which is typically the database name; may be an empty string for tables that have no catalog, or null if the catalog name should not be used to narrow the list of table identifiers
        schemaNamePattern - the pattern used to match database schema names, which may be "" to match only those tables with no schema or null if the schema name should not be used to narrow the list of table identifiers
        tableNamePattern - the pattern used to match database table names, which may be null to match all table names
        tableTypes - the set of table types to include in the results, which may be null for all table types
        Returns:
        the set of TableIds; never null but possibly empty
        Throws:
        SQLException - if an error occurs while accessing the database metadata
      • connectionString

        public String connectionString​(String urlPattern)
        Returns a JDBC connection string using the current configuration and url.
        Parameters:
        urlPattern - a String representing a JDBC connection with variables that will be replaced
        Returns:
        a String where the variables in urlPattern are replaced with values from the configuration
      • username

        public String username()
        Returns the username for this connection
        Returns:
        a String, never null
      • database

        public String database()
        Returns the database name for this connection
        Returns:
        a String, never null
      • resolveNativeType

        protected int resolveNativeType​(String typeName)
        Provides a native type for the given type name. There isn't a standard way to obtain this information via JDBC APIs so this method exists to allow database specific information to be set in addition to the JDBC Type.
        Parameters:
        typeName - the name of the type whose native type we are looking for
        Returns:
        A type constant for the specific database or -1.
      • resolveJdbcType

        protected int resolveJdbcType​(int metadataJdbcType,
                                      int nativeType)
        Resolves the supplied metadata JDBC type to a final JDBC type.
        Parameters:
        metadataJdbcType - the JDBC type from the underlying driver's metadata lookup
        nativeType - the database native type or -1 for unknown
        Returns:
        the resolved JDBC type
      • readSchema

        public void readSchema​(Tables tables,
                               String databaseCatalog,
                               String schemaNamePattern,
                               Tables.TableFilter tableFilter,
                               Tables.ColumnNameFilter columnFilter,
                               boolean removeTablesNotFoundInJdbc)
                        throws SQLException
        Create definitions for each tables in the database, given the catalog name, schema pattern, table filter, and column filter.
        Parameters:
        tables - the set of table definitions to be modified; may not be null
        databaseCatalog - the name of the catalog, which is typically the database name; may be null if all accessible databases are to be processed
        schemaNamePattern - the pattern used to match database schema names, which may be "" to match only those tables with no schema or null to process all accessible tables regardless of database schema name
        tableFilter - used to determine for which tables are to be processed; may be null if all accessible tables are to be processed
        columnFilter - used to determine which columns should be included as fields in its table's definition; may be null if all columns for all tables are to be included
        removeTablesNotFoundInJdbc - true if this method should remove from tables any definitions for tables that are not found in the database metadata, or false if such tables should be left untouched
        Throws:
        SQLException - if an error occurs while accessing the database metadata
      • resolveCatalogName

        protected String resolveCatalogName​(String catalogName)
      • overrideColumn

        protected ColumnEditor overrideColumn​(ColumnEditor column)
        Allow implementations an opportunity to adjust the current state of the ColumnEditor that has been seeded with data from the column metadata from the JDBC driver. In some cases, the data from the driver may be misleading and needs some adjustments.
        Parameters:
        column - the column editor, should not be null
        Returns:
        the adjusted column editor instance
      • isTableUniqueIndexIncluded

        protected boolean isTableUniqueIndexIncluded​(String indexName,
                                                     String columnName)
        Allows the connector implementation to determine if a table's unique index should be include when resolving a table's unique indices.
        Parameters:
        indexName - the index name
        columnName - the column name
        Returns:
        true if the index is to be included; false otherwise.
      • cleanupPreparedStatement

        private void cleanupPreparedStatement​(PreparedStatement statement)
      • executeWithoutCommitting

        public JdbcConnection executeWithoutCommitting​(String... statements)
                                                throws SQLException
        Executes a series of statements without explicitly committing the connection.
        Parameters:
        statements - a series of statements to execute
        Returns:
        this object so methods can be chained together; never null
        Throws:
        SQLException - if anything fails
      • isNullable

        protected static boolean isNullable​(int jdbcNullable)
      • quotedTableIdString

        public String quotedTableIdString​(TableId tableId)
        Converts a table id into a string with all components of the id quoted so non-alphanumeric characters are properly handled.
        Parameters:
        tableId -
        Returns:
        formatted string
      • quotedColumnIdString

        public String quotedColumnIdString​(String columnName)
        Prepares qualified column names with appropriate quote character as per the specific database's rules.