public class SQLServerDatabaseProvider extends DatabaseProvider
DatabaseProvider.RenderFieldOptions, DatabaseProvider.SqlListener
logger, quoteRef, sqlLogger, typeManager
Constructor and Description |
---|
SQLServerDatabaseProvider(DisposableDataSource dataSource) |
SQLServerDatabaseProvider(DisposableDataSource dataSource,
String schema) |
Modifier and Type | Method and Description |
---|---|
protected Set<String> |
getReservedWords()
Retrieves the set of all reserved words for the underlying database.
|
ResultSet |
getTables(Connection conn)
Returns a result set of all of the tables (and associated
meta) in the database.
|
Object |
handleBlob(ResultSet res,
Class<?> type,
String field) |
<T extends RawEntity<K>,K> |
insertReturningKey(EntityManager manager,
Connection conn,
Class<T> entityType,
Class<K> pkType,
String pkField,
boolean pkIdentity,
String table,
DBParam... params)
Generates an INSERT statement to be used to create a new row in the
database, returning the primary key value.
|
Object |
parseValue(int type,
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. |
protected SQLAction |
renderAlterTableAddColumnStatement(NameConverters nameConverters,
DDLTable table,
DDLField field)
Generates the database-specific DDL statement for adding a column,
but not including any corresponding sequences, triggers, etc.
|
protected Iterable<SQLAction> |
renderAlterTableChangeColumn(NameConverters nameConverters,
DDLTable table,
DDLField oldField,
DDLField field)
Generates the database-specific DDL statements required to change
the given column from its old specification to the given DDL value.
|
protected SQLAction |
renderAlterTableChangeColumnStatement(NameConverters nameConverters,
DDLTable table,
DDLField oldField,
DDLField field,
DatabaseProvider.RenderFieldOptions options)
Generates the database-specific DDL statement only for altering a table and
changing a column.
|
protected SQLAction |
renderAlterTableDropKey(DDLForeignKey key)
Generates the database-specific DDL statement required to remove a
foreign key from a table.
|
protected String |
renderAutoIncrement()
Generates the DDL fragment required to specify an INTEGER field as
auto-incremented.
|
protected SQLAction |
renderCreateIndex(IndexNameConverter indexNameConverter,
DDLIndex index)
Generates the database-specific DDL statement required to create
a new index.
|
protected SQLAction |
renderDropIndex(IndexNameConverter indexNameConverter,
DDLIndex index)
Generates the database-specific DDL statement required to drop
an index.
|
protected String |
renderFieldDefault(DDLTable table,
DDLField field) |
protected DatabaseProvider.RenderFieldOptions |
renderFieldOptionsInAlterColumn() |
String |
renderMetadataQuery(String tableName)
Render "SELECT * FROM
|
protected String |
renderPrimaryKey(String tableName,
String pkFieldName) |
protected String |
renderQueryLimit(Query query)
Renders the LIMIT portion of the query in the database-specific SQL
dialect.
|
protected String |
renderQuerySelect(Query query,
TableNameConverter converter,
boolean count)
Renders the SELECT portion of a given
Query instance in the
manner required by the database-specific SQL implementation. |
protected String |
renderUnique(UniqueNameConverter uniqueNameConverter,
DDLTable table,
DDLField field)
Renders the
UNIQUE constraint as defined by the
database-specific DDL syntax. |
void |
setQueryResultSetProperties(ResultSet res,
Query query)
Allows the provider to set database-specific options on a
ResultSet instance prior to its use by the library. |
_getFunctionNameForField, _getTriggerNameForField, _renderDropFunctionForField, _renderDropSequenceForField, _renderDropTriggerForField, _renderFunctionForField, _renderSequenceForField, _renderTriggerForField, addSqlListener, commitTransaction, convertTypeToString, dispose, executeInsertReturningKey, executeUpdate, executeUpdateForAction, executeUpdatesForActions, findForeignKeysForField, getConnection, getDateFormat, getImportedKeys, getIndexes, getMaxIDLength, getSchema, getSequences, getTypeManager, handleUpdateError, hasIndex, hasIndex, insertBatch, isCaseSensitive, isNumericType, isSchemaNotEmpty, loadQuoteString, onSql, preparedStatement, preparedStatement, preparedStatement, processID, processID, processOnClause, processOrderClause, processTableName, processWhereClause, putBoolean, putNull, querySelectFields, queryTableName, quote, quoteTableName, removeSqlListener, renderAccessories, renderAccessoriesForField, renderAction, renderAlterTableAddColumn, renderAlterTableAddKey, renderAlterTableDropColumn, renderAlterTableDropColumnStatement, renderAppend, renderConstraintsForTable, renderCreateCompositeIndex, renderDate, renderDropAccessories, renderDropAccessoriesForField, renderDropColumnActions, renderDropTableStatement, renderField, renderFields, renderFieldType, renderForeignKey, renderInsert, renderQuery, renderQueryGroupBy, renderQueryHaving, renderQueryJoins, renderQueryOrderBy, renderQueryWhere, renderTable, renderValue, rollbackTransaction, setPostConnectionProperties, setQueryStatementProperties, shorten, shouldQuoteID, shouldQuoteTableName, startTransaction, withSchema
public SQLServerDatabaseProvider(DisposableDataSource dataSource)
public SQLServerDatabaseProvider(DisposableDataSource dataSource, String schema)
public String renderMetadataQuery(String tableName)
DatabaseProvider
renderMetadataQuery
in class DatabaseProvider
public void setQueryResultSetProperties(ResultSet res, Query query) throws SQLException
DatabaseProvider
ResultSet
instance prior to its use by the library.
This allows for features such as row offsetting even on
databases that don't support it (such as Oracle, Derby,
etc).setQueryResultSetProperties
in class DatabaseProvider
res
- The ResultSet
to modify.query
- The query instance which was run to produce
the result set.SQLException
public ResultSet getTables(Connection conn) throws SQLException
DatabaseProvider
Returns a result set of all of the tables (and associated
meta) in the database. The fields of the result set must
correspond with those specified in the
DatabaseMetaData#getTables(String, String, String, String[])
method. In fact, the default implementation merely calls
this method passing (null, null, "", null)
.
For databases (such as PostgreSQL) where this is unsuitable,
different parameters can be specified to the getTables
method in the override, or an entirely new implementation
written, as long as the result set corresponds in fields to
the JDBC spec.
getTables
in class DatabaseProvider
conn
- The connection to use in retrieving the database tables.SQLException
DatabaseMetaData.getTables(String, String, String, String[])
public Object parseValue(int type, String value)
DatabaseProvider
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)
parseValue
in class DatabaseProvider
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.protected Iterable<SQLAction> renderAlterTableChangeColumn(NameConverters nameConverters, DDLTable table, DDLField oldField, DDLField field)
DatabaseProvider
Generates the database-specific DDL statements required to change the given column from its old specification to the given DDL value. This method will also generate the appropriate statements to remove old triggers and functions, as well as add new ones according to the requirements of the new field definition.
The default implementation of this method functions in the manner specified by the MySQL database. Some databases will have to perform more complicated actions (such as dropping and re-adding the field) in order to satesfy the same use-case. Such databases should print a warning to stderr to ensure that the end-developer is aware of such restrictions.
Thus, the specification for this method allows for data loss. Nevertheless, if the database supplies a mechanism to accomplish the task without data loss, it should be applied.
For maximum flexibility, the default implementation of this method
only deals with the dropping and addition of functions and triggers.
The actual generation of the ALTER TABLE statement is done in the
DatabaseProvider.renderAlterTableChangeColumnStatement(net.java.ao.schema.NameConverters, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField, net.java.ao.schema.ddl.DDLField, net.java.ao.DatabaseProvider.RenderFieldOptions)
method.
renderAlterTableChangeColumn
in class DatabaseProvider
table
- The table containing the column to change.oldField
- The old column definition.field
- The new column definition (defining the resultant DDL). @return An array of DDL statements to be executed.#getTriggerNameForField(net.java.ao.schema.TriggerNameConverter, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField)
,
#getFunctionNameForField(net.java.ao.schema.TriggerNameConverter, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField)
,
#renderFunctionForField(net.java.ao.schema.TriggerNameConverter, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField)
,
#renderTriggerForField(net.java.ao.schema.TriggerNameConverter, net.java.ao.schema.SequenceNameConverter, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField)
protected SQLAction renderCreateIndex(IndexNameConverter indexNameConverter, DDLIndex index)
DatabaseProvider
null
returned.renderCreateIndex
in class DatabaseProvider
index
- The index to create. This single instance contains all
of the data necessary to create the index, thus no separate
parameters (such as a DDLTable
) are required.protected SQLAction renderDropIndex(IndexNameConverter indexNameConverter, DDLIndex index)
DatabaseProvider
null
returned.renderDropIndex
in class DatabaseProvider
index
- The index to drop. This single instance contains all
of the data necessary to drop the index, thus no separate
parameters (such as a DDLTable
) are required.null
.protected String renderUnique(UniqueNameConverter uniqueNameConverter, DDLTable table, DDLField field)
DatabaseProvider
UNIQUE
constraint as defined by the
database-specific DDL syntax. This method is a delegate of other, more
complex methods such as DatabaseProvider.renderField(net.java.ao.schema.NameConverters, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField, net.java.ao.DatabaseProvider.RenderFieldOptions)
. The default
implementation just returns UNIQUE
. Implementations may
override this method to return an empty String
if the database
in question does not support the constraint.renderUnique
in class DatabaseProvider
UNIQUE
.protected DatabaseProvider.RenderFieldOptions renderFieldOptionsInAlterColumn()
renderFieldOptionsInAlterColumn
in class DatabaseProvider
protected String renderQuerySelect(Query query, TableNameConverter converter, boolean count)
DatabaseProvider
Renders the SELECT portion of a given Query
instance in the
manner required by the database-specific SQL implementation. Usually,
this is as simple as "SELECT id FROM table"
or "SELECT DISTINCT
* FROM table"
. However, some databases require the limit and offset
parameters to be specified as part of the SELECT clause. For example,
on HSQLDB, a Query for the "id" field limited to 10 rows would render
SELECT like this: SELECT TOP 10 id FROM table
.
There is usually no need to call this method directly. Under normal
operations it functions as a delegate for DatabaseProvider.renderQuery(Query, TableNameConverter, boolean)
.
renderQuerySelect
in class DatabaseProvider
query
- The Query instance from which to determine the SELECT properties.converter
- The name converter to allow conversion of the query entity
interface into a proper table name.count
- Whether or not the query should be rendered as a SELECT COUNT(*)
.public Object handleBlob(ResultSet res, Class<?> type, String field) throws SQLException
handleBlob
in class DatabaseProvider
SQLException
protected String renderQueryLimit(Query query)
DatabaseProvider
Renders the LIMIT portion of the query in the database-specific SQL dialect. There is wide variety in database implementations of this particular SQL clause. In fact, many database do not support it at all.
Unfortunately, we live in the real world of proprietary database implementations that requires us to use database specific keywords or semantics to achieve these outcomes. Appropriate methods should be overridden in such cases.
An example return value: " LIMIT 10,2"
There is usually no need to call this method directly. Under normal
operations it functions as a delegate for DatabaseProvider.renderQuery(Query, TableNameConverter, boolean)
.
renderQueryLimit
in class DatabaseProvider
query
- The Query instance from which to determine the LIMIT properties.protected String renderPrimaryKey(String tableName, String pkFieldName)
renderPrimaryKey
in class DatabaseProvider
protected String renderAutoIncrement()
DatabaseProvider
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
.
renderAutoIncrement
in class DatabaseProvider
protected String renderFieldDefault(DDLTable table, DDLField field)
renderFieldDefault
in class DatabaseProvider
protected SQLAction renderAlterTableChangeColumnStatement(NameConverters nameConverters, DDLTable table, DDLField oldField, DDLField field, DatabaseProvider.RenderFieldOptions options)
DatabaseProvider
DatabaseProvider.renderAlterTableChangeColumn(net.java.ao.schema.NameConverters, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField, net.java.ao.schema.ddl.DDLField)
method,
for which it is a primary delegate. The default implementation of this
method functions according to the MySQL specification.renderAlterTableChangeColumnStatement
in class DatabaseProvider
table
- The table containing the column to change.oldField
- The old column definition.field
- The new column definition (defining the resultant DDL).DatabaseProvider.renderField(net.java.ao.schema.NameConverters, net.java.ao.schema.ddl.DDLTable, net.java.ao.schema.ddl.DDLField, net.java.ao.DatabaseProvider.RenderFieldOptions)
protected SQLAction renderAlterTableAddColumnStatement(NameConverters nameConverters, DDLTable table, DDLField field)
DatabaseProvider
renderAlterTableAddColumnStatement
in class DatabaseProvider
table
- The table which should receive the new column.field
- The column to add to the specified table.protected SQLAction renderAlterTableDropKey(DDLForeignKey key)
DatabaseProvider
null
value returned. This method assumes that the
DatabaseProvider.renderForeignKey(DDLForeignKey)
method properly names
the foreign key according to the DDLForeignKey.getFKName()
method.renderAlterTableDropKey
in class DatabaseProvider
key
- The foreign key to be removed. As this instance contains
all necessary data (such as domestic table, field, etc), no
additional parameters are required.null
.public <T extends RawEntity<K>,K> K insertReturningKey(EntityManager manager, Connection conn, Class<T> entityType, Class<K> pkType, String pkField, boolean pkIdentity, String table, DBParam... params) throws SQLException
DatabaseProvider
Generates an INSERT statement to be used to create a new row in the
database, returning the primary key value. This method also invokes
the delegate method, #executeInsertReturningKey(EntityManager, java.sql.Connection, Class, String, String, DBParam...)
passing the appropriate parameters and query. This method is required
because some databases do not support the JDBC parameter
RETURN_GENERATED_KEYS
(such as HSQLDB and PostgreSQL).
Also, some databases (such as MS SQL Server) require odd tricks to
support explicit value passing to auto-generated fields. This method
should take care of any extra queries or odd SQL generation required
to implement both auto-generated primary key returning, as well as
explicit primary key value definition.
Overriding implementations of this method should be sure to use the
Connection
instance passed to the method, not a new
instance generated using the DatabaseProvider.getConnection()
method. This is
because this method is in fact a delegate invoked by EntityManager
as part of the entity creation process and may be part of a transaction,
a bulk creation or some more complicated operation. Both optimization
and usage patterns on the API dictate that the specified connection
instance be used. Implementations may assume that the given connection
instance is never null
.
The default implementation of this method should be sufficient for any
fully compliant ANSI SQL database with a properly implemented JDBC
driver. Note that this method should not not actually execute
the SQL it generates, but pass it on to the #executeInsertReturningKey(EntityManager, java.sql.Connection, Class, String, String, DBParam...)
method, allowing for functional delegation and better extensibility.
However, this method may execute any additional statements required to
prepare for the INSERTion (as in the case of MS SQL Server which requires
some config parameters to be set on the database itself prior to INSERT).
insertReturningKey
in class DatabaseProvider
manager
- The EntityManager
which was used to dispatch
the INSERT in question.conn
- The connection to be used in the eventual execution of the
generated SQL statement.entityType
- The Java class of the entity.pkType
- The Java type of the primary key value. Can be used to
perform a linear search for a specified primary key value in the
params
list. The return value of the method must be of
the same type.pkField
- The database field which is the primary key for the
table in question. Can be used to perform a linear search for a
specified primary key value in the params
list.pkIdentity
- Flag indicating whether or not the primary key field
is auto-incremented by the database (IDENTITY field).table
- The name of the table into which the row is to be INSERTed.params
- A varargs array of parameters to be passed to the
INSERT statement. This may include a specified value for the
primary key.SQLException
- If the INSERT fails in the delegate method, or
if any additional statements fail with an exception.#executeInsertReturningKey(EntityManager, java.sql.Connection, Class, String, String, DBParam...)
protected Set<String> getReservedWords()
DatabaseProvider
Set
instance returned from this
method should guarentee O(1) lookup times, otherwise ORM performance
will suffer greatly.getReservedWords
in class DatabaseProvider
Copyright © 2007–2021 Atlassian. All rights reserved.