net.java.ao
Class DatabaseProvider

java.lang.Object
  extended by net.java.ao.DatabaseProvider
Direct Known Subclasses:
ClientDerbyDatabaseProvider, EmbeddedDerbyDatabaseProvider, HSQLDatabaseProvider, MySQLDatabaseProvider, OracleDatabaseProvider, PoolProvider, PostgreSQLDatabaseProvider, SQLServerDatabaseProvider

public abstract class DatabaseProvider
extends java.lang.Object

The superclass parent of all DatabaseProvider implementations. Various implementations allow for an abstraction around database-specific functionality (such as DDL). DatabaseProvider(s) also handle the creation of new Connection instances and fully encapsulate the raw JDBC driver. Any database-specific code should be placed in the database provider, rather than embedded within the API logic.

This superclass contains a base-line, default implementation of most database-specific methods, thus requiring a minimum of work to implement a new database provider. For the sake of sanity (read: mine), this base-line implementation is basically specific to MySQL. Thus any DatabaseProvider implementations are really specifying the differences between the database in question and MySQL. To fully utilize the default implementations provided in this class, this fact should be kept in mind.

This class also handles the implementation details required to ensure that only one active Connection instance is available per thread. This is in fact a very basic (and naive) form of connection pooling. It should not be relied upon for performance reasons. Instead, a third-party connection pool should be available in the classpath, enabling the use of one of the PoolProvider implementations. The purpose of the thread-locked connection pooling in this class is to satisfy transactions with external SQL statements.

Author:
Daniel Spiewak

Constructor Summary
protected DatabaseProvider(java.lang.String uri, java.lang.String username, java.lang.String password)
          The base constructor for DatabaseProvider.
 
Method Summary
protected  boolean considerPrecision(DDLField field)
           
protected  java.lang.String convertTypeToString(DatabaseType<?> type)
           
 void dispose()
           
protected  int executeInsertReturningKeys(java.sql.Connection conn, java.lang.String sql, DBParam... params)
           
 java.sql.Connection getConnection()
           
protected  java.sql.Connection getConnectionImpl()
           
protected  java.lang.String getDateFormat()
           
abstract  java.lang.Class<? extends java.sql.Driver> getDriverClass()
          Returns the JDBC Driver class which corresponds to the database being abstracted.
protected  java.lang.String getFunctionNameForField(DDLTable table, DDLField field)
           
static DatabaseProvider getInstance(java.lang.String uri, java.lang.String username, java.lang.String password)
           
static DatabaseProvider getInstance(java.lang.String uri, java.lang.String username, java.lang.String password, boolean enablePooling)
           
 java.lang.String getPassword()
           
 java.sql.ResultSet getTables(java.sql.Connection conn)
           
protected  java.lang.String getTriggerNameForField(DDLTable table, DDLField field)
           
 java.lang.String getURI()
           
 java.lang.String getUsername()
           
 int insertReturningKeys(java.sql.Connection conn, java.lang.String table, DBParam... params)
           
protected  boolean isNumericType(int type)
           
 java.lang.Object parseValue(int type, java.lang.String value)
          Parses the database-agnostic String value relevant to the specified SQL type in int form (as defined by Types and returns the Java value which corresponds.
 java.lang.String[] renderAction(DDLAction action)
          Top level delegating method for the process of rendering a database-agnostic DDLAction into the database-specific DDL statement(s).
protected  java.lang.String[] renderAlterTableAddColumn(DDLTable table, DDLField field)
           
protected  java.lang.String renderAlterTableAddKey(DDLForeignKey key)
           
protected  java.lang.String[] renderAlterTableChangeColumn(DDLTable table, DDLField oldField, DDLField field)
           
protected  java.lang.String[] renderAlterTableDropColumn(DDLTable table, DDLField field)
           
protected  java.lang.String renderAlterTableDropKey(DDLForeignKey key)
           
protected  java.lang.String renderAppend()
           
protected abstract  java.lang.String renderAutoIncrement()
          Generates the DDL fragment required to specify an INTEGER field as auto-incremented.
protected  java.lang.String renderCalendar(java.util.Calendar calendar)
           
protected  java.lang.String renderConstraintsForTable(DDLTable table)
           
protected  java.lang.String[] renderDropFunctions(DDLTable table)
           
protected  java.lang.String renderDropTable(DDLTable table)
           
protected  java.lang.String[] renderDropTriggers(DDLTable table)
           
protected  java.lang.String renderField(DDLField field)
           
protected  java.lang.String renderFieldType(DDLField field)
           
protected  java.lang.String renderForeignKey(DDLForeignKey key)
           
protected  java.lang.String renderFunction(DatabaseFunction func)
           
protected  java.lang.String renderFunctionForField(DDLTable table, DDLField field)
           
protected  java.lang.String[] renderFunctions(DDLTable table)
           
protected  java.lang.String renderOnUpdate(DDLField field)
           
 java.lang.String renderQuery(Query query, TableNameConverter converter, boolean count)
          Top level delegating method for rendering a database-agnostic Query object into its (potentially) database-specific query statement.
protected  java.lang.String renderQueryGroupBy(Query query)
           
protected  java.lang.String renderQueryJoins(Query query, TableNameConverter converter)
           
protected  java.lang.String renderQueryLimit(Query query)
           
protected  java.lang.String renderQueryOrderBy(Query query)
           
protected  java.lang.String renderQuerySelect(Query query, TableNameConverter converter, boolean count)
           
protected  java.lang.String renderQueryWhere(Query query)
           
protected  java.lang.String renderTable(DDLTable table)
           
protected  java.lang.String renderTriggerForField(DDLTable table, DDLField field)
           
protected  java.lang.String[] renderTriggers(DDLTable table)
           
protected  java.lang.String renderUnique()
           
protected  java.lang.String renderValue(java.lang.Object value)
           
protected  void setPostConnectionProperties(java.sql.Connection conn)
           
 void setQueryResultSetProperties(java.sql.ResultSet res, Query query)
           
 void setQueryStatementProperties(java.sql.Statement stmt, Query query)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DatabaseProvider

protected DatabaseProvider(java.lang.String uri,
                           java.lang.String username,
                           java.lang.String password)

The base constructor for DatabaseProvider. Initializes the JDBC uri, username and password values as specified.

Subclasses should implement a public constructor of this form, however it is not mandatory.

Parameters:
uri - The JDBC URI which corresponds to the database being abstracted.
username - The database username (note: for implementations which do not make use of this field, null is permitted).
password - The database password (note: for implementations which do not make use of this field, null is permitted).
Method Detail

getDriverClass

public abstract java.lang.Class<? extends java.sql.Driver> getDriverClass()
                                                                   throws java.lang.ClassNotFoundException

Returns the JDBC Driver class which corresponds to the database being abstracted. This should be implemented in such a way as to initialize and register the driver with JDBC. For most drivers, this requires code in the following form:

public Class<? extends Driver> getDriverClass() {
     return (Class<? extends Driver>) Class.forName("com.mysql.jdbc.Driver");
 }

The following does not fire the driver's static initializer and thus will (usually) not work:

public Class<? extends Driver> getDriverClass() {
     return com.mysql.jdbc.Driver.class;
 }

If the driver is not on the classpath, a ClassNotFoundException can and should be thrown (certain auto-magic configuration sections of ActiveObjects depend upon this under certain circumstances).

Throws:
java.lang.ClassNotFoundException

renderAutoIncrement

protected abstract java.lang.String renderAutoIncrement()

Generates the DDL fragment required to specify an INTEGER field as auto-incremented. For databases which do not support such flags (which is just about every database exception MySQL), "" is an acceptable return value. This method should never return null as it would cause the field rendering method to throw a NullPointerException.

This method is abstract (as opposed to the other methods which are either defined against MySQL or simply empty) because of the vast differences in rendering auto-incremented fields across different databases. Also, it seemed like a terribly good idea at the time and I haven't found a compelling reason to change it.


renderAction

public java.lang.String[] renderAction(DDLAction action)
Top level delegating method for the process of rendering a database-agnostic DDLAction into the database-specific DDL statement(s). It is doubtful that any implementations will have to override this method as the default implementation is database-agnostic.

Parameters:
action - The database-agnostic action to render.
See Also:
renderTable(DDLTable), renderFunctions(DDLTable), renderTriggers(DDLTable), renderDropTriggers(DDLTable), renderDropFunctions(DDLTable), renderDropTable(DDLTable), renderAlterTableAddColumn(DDLTable, DDLField), renderAlterTableChangeColumn(DDLTable, DDLField, DDLField), renderAlterTableDropColumn(DDLTable, DDLField), renderAlterTableAddKey(DDLForeignKey), renderAlterTableDropKey(DDLForeignKey)

renderQuery

public java.lang.String renderQuery(Query query,
                                    TableNameConverter converter,
                                    boolean count)

Top level delegating method for rendering a database-agnostic Query object into its (potentially) database-specific query statement. This method invokes the various renderQuery* methods to construct its output, thus it is doubtful that any subclasses will have to override it. Rather, one of the delegate methods should be considered.

An example of a database-specific query rendering would be the following Query:

Query.select().from(Person.class).limit(10)

On MySQL, this would render to SELECT id FROM people LIMIT 10 However, on SQL Server, this same Query would render as SELECT TOP 10 id FROM people

Parameters:
query - The database-agnostic Query object to be rendered in a potentially database-specific way.
converter - Used to convert Entity classes into table names.
count - If true, render the Query as a SELECT COUNT(*) rather than a standard field-data query.
See Also:
renderQuerySelect(Query, TableNameConverter, boolean), renderQueryJoins(Query, TableNameConverter), renderQueryWhere(Query), renderQueryGroupBy(Query), renderQueryOrderBy(Query), renderQueryLimit(Query)

parseValue

public java.lang.Object parseValue(int type,
                                   java.lang.String value)

Parses the database-agnostic String value relevant to the specified SQL type in int form (as defined by Types and returns the Java value which corresponds. This method is completely database-agnostic, as are all of all of its delegate methods.

WARNING: This method is being considered for removal to another class (perhaps TypeManager?) as it is not a database-specific function and thus confuses the purpose of this class. Do not rely upon it heavily. (better yet, don't rely on it at all from external code. It's not designed to be part of the public API)

Parameters:
type - The JDBC integer type of the database field against which to parse the value.
value - The database-agnostic String value to parse into a proper Java object with respect to the specified SQL type.

setQueryStatementProperties

public void setQueryStatementProperties(java.sql.Statement stmt,
                                        Query query)
                                 throws java.sql.SQLException
Throws:
java.sql.SQLException

setQueryResultSetProperties

public void setQueryResultSetProperties(java.sql.ResultSet res,
                                        Query query)
                                 throws java.sql.SQLException
Throws:
java.sql.SQLException

getTables

public java.sql.ResultSet getTables(java.sql.Connection conn)
                             throws java.sql.SQLException
Throws:
java.sql.SQLException

renderQuerySelect

protected java.lang.String renderQuerySelect(Query query,
                                             TableNameConverter converter,
                                             boolean count)

renderQueryJoins

protected java.lang.String renderQueryJoins(Query query,
                                            TableNameConverter converter)

renderQueryWhere

protected java.lang.String renderQueryWhere(Query query)

renderQueryGroupBy

protected java.lang.String renderQueryGroupBy(Query query)

renderQueryOrderBy

protected java.lang.String renderQueryOrderBy(Query query)

renderQueryLimit

protected java.lang.String renderQueryLimit(Query query)

getURI

public java.lang.String getURI()

getUsername

public java.lang.String getUsername()

getPassword

public java.lang.String getPassword()

getConnection

public final java.sql.Connection getConnection()
                                        throws java.sql.SQLException
Throws:
java.sql.SQLException

getConnectionImpl

protected java.sql.Connection getConnectionImpl()
                                         throws java.sql.SQLException
Throws:
java.sql.SQLException

dispose

public void dispose()

setPostConnectionProperties

protected void setPostConnectionProperties(java.sql.Connection conn)
                                    throws java.sql.SQLException
Throws:
java.sql.SQLException

renderConstraintsForTable

protected java.lang.String renderConstraintsForTable(DDLTable table)

renderForeignKey

protected java.lang.String renderForeignKey(DDLForeignKey key)

convertTypeToString

protected java.lang.String convertTypeToString(DatabaseType<?> type)

renderTable

protected java.lang.String renderTable(DDLTable table)

renderDropTable

protected java.lang.String renderDropTable(DDLTable table)

renderDropFunctions

protected java.lang.String[] renderDropFunctions(DDLTable table)

renderDropTriggers

protected java.lang.String[] renderDropTriggers(DDLTable table)

renderFunctions

protected java.lang.String[] renderFunctions(DDLTable table)

renderTriggers

protected java.lang.String[] renderTriggers(DDLTable table)

renderAlterTableAddColumn

protected java.lang.String[] renderAlterTableAddColumn(DDLTable table,
                                                       DDLField field)

renderAlterTableChangeColumn

protected java.lang.String[] renderAlterTableChangeColumn(DDLTable table,
                                                          DDLField oldField,
                                                          DDLField field)

renderAlterTableDropColumn

protected java.lang.String[] renderAlterTableDropColumn(DDLTable table,
                                                        DDLField field)

renderAlterTableAddKey

protected java.lang.String renderAlterTableAddKey(DDLForeignKey key)

renderAlterTableDropKey

protected java.lang.String renderAlterTableDropKey(DDLForeignKey key)

renderAppend

protected java.lang.String renderAppend()

renderField

protected java.lang.String renderField(DDLField field)

renderValue

protected java.lang.String renderValue(java.lang.Object value)

renderCalendar

protected java.lang.String renderCalendar(java.util.Calendar calendar)

renderUnique

protected java.lang.String renderUnique()

getDateFormat

protected java.lang.String getDateFormat()

renderFieldType

protected java.lang.String renderFieldType(DDLField field)

renderFunction

protected java.lang.String renderFunction(DatabaseFunction func)

renderOnUpdate

protected java.lang.String renderOnUpdate(DDLField field)

considerPrecision

protected boolean considerPrecision(DDLField field)

getTriggerNameForField

protected java.lang.String getTriggerNameForField(DDLTable table,
                                                  DDLField field)

renderTriggerForField

protected java.lang.String renderTriggerForField(DDLTable table,
                                                 DDLField field)

getFunctionNameForField

protected java.lang.String getFunctionNameForField(DDLTable table,
                                                   DDLField field)

renderFunctionForField

protected java.lang.String renderFunctionForField(DDLTable table,
                                                  DDLField field)

insertReturningKeys

public int insertReturningKeys(java.sql.Connection conn,
                               java.lang.String table,
                               DBParam... params)
                        throws java.sql.SQLException
Throws:
java.sql.SQLException

executeInsertReturningKeys

protected int executeInsertReturningKeys(java.sql.Connection conn,
                                         java.lang.String sql,
                                         DBParam... params)
                                  throws java.sql.SQLException
Throws:
java.sql.SQLException

isNumericType

protected boolean isNumericType(int type)

getInstance

public static final DatabaseProvider getInstance(java.lang.String uri,
                                                 java.lang.String username,
                                                 java.lang.String password)

getInstance

public static final DatabaseProvider getInstance(java.lang.String uri,
                                                 java.lang.String username,
                                                 java.lang.String password,
                                                 boolean enablePooling)