All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tentackle.sql.Backend Maven / Gradle / Ivy

The newest version!
/*
 * Tentackle - https://tentackle.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.tentackle.sql;

import org.tentackle.sql.metadata.ColumnMetaData;
import org.tentackle.sql.metadata.DatabaseMetaDataTableHeader;
import org.tentackle.sql.metadata.IndexColumnMetaData;
import org.tentackle.sql.metadata.IndexMetaData;
import org.tentackle.sql.metadata.ModelMetaData;
import org.tentackle.sql.metadata.TableMetaData;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * A database backend.
* Defines the backend specifics.
* There is only one instance per database type.
* Implementations must not maintain any state except for the whole of all connections to the * specific kind of database. * * @author harald */ public interface Backend { /** WHERE string. */ String SQL_WHERE = " WHERE "; /** SELECT string. */ String SQL_SELECT = "SELECT "; /** SELECT * FROM string. */ String SQL_SELECT_ALL_FROM = "SELECT * FROM "; /** DELETE string. */ String SQL_DELETE = "DELETE "; /** UPDATE string. */ String SQL_UPDATE = "UPDATE "; /** INSERT INTO string. */ String SQL_INSERT_INTO = "INSERT INTO "; /** opening bracket. */ String SQL_LEFT_PARENTHESIS = " ("; /** closing bracket. */ String SQL_RIGHT_PARENTHESIS = ") "; /** dot all columns. */ String SQL_DOT_STAR = ".*"; /** (VALUES) string for insert. */ String SQL_INSERT_VALUES = SQL_RIGHT_PARENTHESIS + "VALUES" + SQL_LEFT_PARENTHESIS; /** SET string. */ String SQL_SET = " SET "; /** FROM string. */ String SQL_FROM = " FROM "; /** AND string. */ String SQL_AND = " AND "; /** OR string. */ String SQL_OR = " OR "; /** NOT string. */ String SQL_NOT = "NOT "; /** AND NOT string. */ String SQL_ANDNOT = SQL_AND + SQL_NOT; /** OR NOT string. */ String SQL_ORNOT = SQL_OR + SQL_NOT; /** comma separator. */ String SQL_COMMA = ","; /** ? string. */ String SQL_PAR = "?"; /** Array parameter (?). */ String SQL_ARRAY_PAR = "(?)"; /** = operator string. */ String SQL_EQUAL = "="; /** <> operator string. */ String SQL_NOTEQUAL = "<>"; /** < operator string. */ String SQL_LESS = "<"; /** > operator string. */ String SQL_GREATER = ">"; /** <= operator string. */ String SQL_LESSOREQUAL = "<="; /** >= operator string. */ String SQL_GREATEROREQUAL = ">="; /** LIKE operator string. */ String SQL_LIKE = " LIKE "; /** NOT LIKE operator string. */ String SQL_NOTLIKE = " NOT LIKE "; /** IN array operator string. */ String SQL_ARRAY_IN = "IN"; /** NOT IN array operator string. */ String SQL_ARRAY_NOT_IN = "NOT IN"; /** ANY array operator string. */ String SQL_ARRAY_ANY = "ANY"; /** ALL array operator string. */ String SQL_ARRAY_ALL = "ALL"; /** =0 string. */ String SQL_EQUAL_ZERO = SQL_EQUAL + "0"; /** <>0 string. */ String SQL_NOTEQUAL_ZERO = SQL_NOTEQUAL + "0"; /** Parameter ,? string. */ String SQL_COMMA_PAR = SQL_COMMA + SQL_PAR; /** Parameter ?, string. */ String SQL_PAR_COMMA = SQL_PAR + SQL_COMMA; /** Parameter =? string. */ String SQL_EQUAL_PAR = SQL_EQUAL + SQL_PAR; /** Parameter =?, string. */ String SQL_EQUAL_PAR_COMMA = SQL_EQUAL + SQL_PAR + SQL_COMMA; /** Parameter <>? string. */ String SQL_NOTEQUAL_PAR = SQL_NOTEQUAL + SQL_PAR; /** Parameter >? string. */ String SQL_GREATER_PAR = SQL_GREATER + SQL_PAR; /** Parameter ≥? string. */ String SQL_GREATEROREQUAL_PAR = SQL_GREATEROREQUAL + SQL_PAR; /** Parameter <? string. */ String SQL_LESS_PAR = SQL_LESS + SQL_PAR; /** Parameter <=? string. */ String SQL_LESSOREQUAL_PAR = SQL_LESSOREQUAL + SQL_PAR; /** Parameter LIKE ? string. */ String SQL_LIKE_PAR = SQL_LIKE + SQL_PAR; /** Parameter NOT LIKE ? string. */ String SQL_NOTLIKE_PAR = SQL_NOTLIKE + SQL_PAR; /** Parameter IN array operator string. */ String SQL_ARRAY_IN_PAR = " " + SQL_ARRAY_IN + SQL_ARRAY_PAR; /** Parameter NOT IN array operator string. */ String SQL_ARRAY_NOT_IN_PAR = " " + SQL_ARRAY_NOT_IN + SQL_ARRAY_PAR; /** Parameter ANY array operator string. */ String SQL_ARRAY_ANY_PAR = SQL_ARRAY_ANY + SQL_ARRAY_PAR; /** Parameter ALL array operator string. */ String SQL_ARRAY_ALL_PAR = SQL_ARRAY_ALL + SQL_ARRAY_PAR; /** '*' all string. */ String SQL_ALLSTAR = "*"; /** +1 string. */ String SQL_PLUS_ONE = "+1"; /** "WHERE 1=1" allows AND to be added. */ String SQL_WHEREALL = SQL_WHERE + "1=1"; /** "WHERE 1=0" to select nothing. */ String SQL_WHERENOTHING = SQL_WHERE + "1=0"; /** SQL_WHEREALL + AND will be replaced by... SQL_WHERE. */ String SQL_WHEREAND = SQL_WHEREALL + SQL_AND; /** SQL_WHEREALL + OR will be replaced by... SQL_WHERE. */ String SQL_WHEREOR = SQL_WHEREALL + SQL_OR; /** IS NULL string. */ String SQL_ISNULL = " IS NULL"; /** IS NOT NULL string. */ String SQL_ISNOTNULL = " IS NOT NULL"; /** ORDER BY string. */ String SQL_ORDERBY = " ORDER BY "; /** sort ASC string. */ String SQL_SORTASC = " ASC"; /** sort DESC string. */ String SQL_SORTDESC = " DESC"; /** GROUP BY string. */ String SQL_GROUPBY = " GROUP BY "; /** MAX function name. */ String SQL_MAX = "MAX"; /** MAX function name. */ String SQL_MIN = "MIN"; /** SQL EXISTS clause with SELECT 1 and opening left parenthesis. */ String SQL_EXISTS = "EXISTS (SELECT 1 FROM "; /** SQL ALTER TABLE intro. */ String SQL_ALTER_TABLE = "ALTER TABLE "; /** SQL ALTER INDEX intro. */ String SQL_ALTER_INDEX = "ALTER INDEX "; /** SQL ALTER COLUMN fragment. */ String SQL_ALTER_COLUMN = " ALTER COLUMN "; /** SQL IF EXISTS fragment. */ String SQL_IF_EXISTS = "IF EXISTS "; /** * Checks whether the backend belongs to the given jdbc url.
* If multiple backend implementations are provided for the same database type, * only one backend should match the URL. The others must be selected via name. * * @param url the jdbc url * @return true if matches */ boolean isMatchingUrl(String url); /** * Checks whether the backend belongs to the given name. * * @param name the backend's name * @return true if matches */ boolean isMatchingName(String name); /** * Returns whether this backend is deprecated and superseded by a newer implementation.
* Deprecated backends are omitted from {@link BackendFactory#getAllBackends()}. * * @return true if deprecated */ boolean isDeprecated(); /** * Verifies that the major and minor version of the connection's metadata is compatible with this backend.
* If the latest backend is not compatible, the URL may be post-fixed with a backend type for an older version, for example: *
   *   jdbc:oracle:thin:@//localhost:1521/xe|Oracle8
   * 
* *

* Throws {@link BackendException} if incompatible. * * @param databaseMajorVersion the major version * @param databaseMinorVersion the minor version * @see BackendInfo#BackendInfo(String, String, char[], String[]) */ void validateVersion(int databaseMajorVersion, int databaseMinorVersion); /** * Gets the name of the backend.
* * @return the name */ String getName(); /** * Gets the JDBC driver class name. * * @return the class name */ String getDriverClassName(); /** * Creates a jdbc connection. * * @param url the jdbc url * @param username the username * @param password the password * @return the created connection * @throws SQLException if connection could not be established */ Connection createConnection(String url, String username, char[] password) throws SQLException; /** * Gets the metadata from the backend. *

* Important: the connection of the metadata is open! * * @param backendInfo the backend info * @return the metadata, may be more than one if schemas set in backendInfo * @throws SQLException if failed */ DatabaseMetaData[] getMetaData(BackendInfo backendInfo) throws SQLException; /** * Gets all table headers for a given metadata. * * @param metaData the database metadata * @return the list of table headers * @throws SQLException if failed */ List getTableHeaders(DatabaseMetaData metaData) throws SQLException; /** * Checks whether this is a temporary name.
* Returns whether an entity-, attribute- or index-name is temporary and should not * be taken into account for migration or even used in the model.
* Depending on the backend, temporary names start with an underscore or some other * lead string. * * @param name the name * @return true temporary (invalid) name */ boolean isTemporaryName(String name); /** * Checks whether this a reserved table name for this backend.
* Applies only to tables. Not to be mixed up with {@link #getReservedWords()}.
* Useful to avoid conflicts with naming conventions for backend specific things, * such as snapshots. * * @param name the table name * @return true if reserved by backend */ boolean isReservedTableName(String name); /** * Checks whether this is a reserved schema name for this backend. * * @param name the schema name * @return true if reserved by backend */ boolean isReservedSchemaName(String name); /** * Creates a select statement string from an inner sql string. *

* {@code sqlBuilder} is anything as {@code [SELECT] FROM... WHERE... ORDER BY...}.
* It is decorated with a leading {@code SELECT}, if missing, plus optional clauses * like for the given parameters. * * @param sqlBuilder the sql builder, initially containing the inner sql without leading {@code SELECT}. * @param writeLock true select should write lock * @param limit the limit value, ≤ 0 if no limit clause * @param offset the offset value, ≤ 0 if no offset clause */ void buildSelectSql(StringBuilder sqlBuilder, boolean writeLock, int limit, int offset); /** * Creates a select statement string from an inner sql string. *

* Same as {@link #buildSelectSql(StringBuilder, boolean, int, int)}, but for strings. * * @param sql the sql without leading {@code SELECT}. * @param writeLock true select should write lock * @param limit the limit value, ≤ 0 if no limit clause * @param offset the offset value, ≤ 0 if no offset clause * @return the select statement */ String buildSelectSql(String sql, boolean writeLock, int limit, int offset); /** * Sets optional parameters before applying the original parameters. * * @param stmt the prepared statement * @param limit the limit value, ≤ 0 if no limit clause * @param offset the offset value, ≤ 0 if no offset clause * @return the next parameter index */ int setLeadingSelectParameters(BackendPreparedStatement stmt, int limit, int offset); /** * Sets optional parameters after applying the original parameters. * * @param stmt the prepared statement * @param index the first parameter index * @param limit the limit value, ≤ 0 if no limit clause * @param offset the offset value, ≤ 0 if no offset clause * @return the next parameter index */ int setTrailingSelectParameters(BackendPreparedStatement stmt, int index, int limit, int offset); /** * Gets the empty string.
* Some dbms (most famous: Oracle) handle empty strings as null. * In such cases the empty string (e.g. Oracle) may consist of a single blank, * or whatever. * * @return the empty string (never null) */ String getEmptyString(); /** * Gets the dummy select to keep/test connections alive.
* Most databases just require a "SELECT 1". * * @return the select string */ String getDummySelect(); /** * According to the JDBC-specs {@link java.sql.Connection#setAutoCommit}(true) * should commit, but some backends require an extra {@link java.sql.Connection#commit}. * * @return true if the database needs an extra commit */ boolean isExtraCommitRequired(); /** * Gets the keyword for the COALESCE function. * * @return the keyword */ String getCoalesceKeyword(); /** * Determines whether backend allows expressions referring to tables being updated. * * @return true if allowed */ boolean isExpressionReferringToTableBeingUpdatedSupported(); /** * True if backend provides locking-free sequences.
* Sequences must not take part in transactions, i.e. no read- or write-locks! * * @return true if database supports sequences */ boolean isSequenceSupported(); /** * Gets the string before the table alias.
* In most databases the " AS " is optional and some * don't accept it all. * * @return the as-string */ String sqlAsBeforeTableAlias(); /** * Returns whether backend requires an alias for a sub-select. * * @return true if sub-select needs an alias. */ boolean isAliasRequiredForSubSelect(); /** * Creates the SQL string to create a sequence. * * @param name the sequence name * @param start the optional start value, defaults to 1 * @param increment the optional increment, defaults to 1 * @return the SQL code */ String sqlCreateSequence(String name, Long start, Long increment); /** * Creates the SQL string to comment a sequence. * * @param name the sequence name * @param comment the comment * @return the SQL code */ String sqlCreateSequenceComment(String name, String comment); /** * Creates the SQL string to retrieve the next id from a sequence. * * @param name the name of the sequence * @return the SQL code */ String sqlNextFromSequence(String name); /** * Creates the SQL string to create a schema. * * @param name the schema name * @return the SQL code * @see #isSchemaSupported() */ String sqlCreateSchema(String name); /** * Create comment sql code that is interpreted as a comment by the backend. * * @param text any text, single or multiline * @return the comment, null if text was null */ String sqlComment(String text); /** * Creates a join clause. * * @param type the join type * @param joinedTableName the joined tablename * @param joinedTableAlias the joined table alias, null if none * @param join the join expression * @return the sql code */ String sqlJoin(JoinType type, String joinedTableName, String joinedTableAlias, String join); /** * Creates an sql function expression. *

* Example: *

   *  sqlFunction("max", CN_ID) --> "MAX(id)"
   * 
* * @param functionName the function name, will be translated to uppercase * @param expression the expression, may be null * @return the sql code */ String sqlFunction(String functionName, String expression); /** * Checks for the (postgres) bug that fetch-size is ignored if not within a new transaction. * * @return true if start tx */ boolean isTxRequiredForFetchsize(); /** * Determines whether exception is a constraint violation. * * @param ex the exception * @return true if constraint violation */ boolean isConstraintException(SQLException ex); /** * Determines whether exception is a communication error. * * @param ex the exception * @return true if comlink down or alike */ boolean isCommunicationLinkException(SQLException ex); /** * Determines whether exception is transient and retrying the transaction may succeed.
* Typical transient exceptions are thrown when a deadlock is detected or when serialized transaction isolation is used. *

* Other transient errors are not covered by this method (e.g. connection timeouts, etc...). * * @param ex the exception * @return true if retrying the transaction may succeed */ boolean isTransientTransactionException(SQLException ex); /** * Returns the maximum size for a given SQL-type.
* * @param sqlType the SQL-type * @return the maximum size, 0 if unlimited, -1 if type without size */ int getMaxSize(SqlType sqlType); /** * Returns the maximum scale for a given SQL-type and size.
* * @param sqlType the SQL-type * @param size the size, 0 if unlimited * @return the maximum scale, 0 if unlimited */ int getMaxScale(SqlType sqlType, int size); /** * Gets the default size if no size given in model. * * @param sqlType the SQL-type * @return the default size, 0 if no default size */ int getDefaultSize(SqlType sqlType); /** * Gets the default schema name.
* Some backends store the objects in a default schema, if no explicit schema is given. * * @return the default schema, null if none */ String getDefaultSchema(); /** * Gets the list of reserved words for this backend. * * @return the set of reserved words */ Set getReservedWords(); /** * Asserts that given string is a valid name and usage. * * @param nameType the type/usage of the name * @param name the name * @throws BackendException if invalid name */ void assertValidName(SqlNameType nameType, String name); /** * Gets the maximum allowed length for a name.
* This method is used by {@link #assertValidName(SqlNameType, String)}. * * @param nameType the type of the name * @return the length */ int getMaxNameLength(SqlNameType nameType); /** * Determines the unique id or name used by the backend for a given connection. *

* Useful to figure out the corresponding {@code ManagedConnection} from the backend's logfiles. * * @param connection the jdbc connection * @return the backend id, null if none */ String getBackendId(Connection connection); /** * Retrieves the metadata.
* * @param metaData the metadata for the whole database * @param schemas the optional schemas to filter tables, null if no filter * @param tableNames the tables of the model * @return the metadata, null if no such table */ ModelMetaData getModelMetaData(DatabaseMetaData[] metaData, String[] schemas, String... tableNames); /** * Creates a column meta data instance. * * @param tableMetaData the table metadata this column belongs to * @return the meta data */ ColumnMetaData createColumnMetaData(TableMetaData tableMetaData); /** * Creates a meta data instance. * * @param metaData the whole metadata * @param tableName the model's table name * @return the meta data */ TableMetaData createTableMetaData(ModelMetaData metaData, String tableName); /** * Creates an index meta data instance. * * @param tableMetaData the table metadata this index belongs to * @return the meta data */ IndexMetaData createIndexMetaData(TableMetaData tableMetaData); /** * Creates an index column meta data instance. * * @param indexMetaData the meta meta data this column belongs to * @return the meta data */ IndexColumnMetaData createIndexColumnMetaData(IndexMetaData indexMetaData); /** * Converts the java SQL-type to the database type name. * * @param sqlType the java sql type * @param size the column's size * @return the corresponding type string */ String sqlTypeToString(SqlType sqlType, int size); /** * Converts an sqltype, size and scale to a database type declaration. * * @param sqlType the SQL type * @param size the size * @param scale the scale * @return the type definition */ String columnTypeToString(SqlType sqlType, int size, int scale); /** * Converts an sqltype, size, scale, nullable and default value to a database type declaration. * * @param columnName the database column name * @param sqlType the JDBC sql type * @param size the optional size * @param scale the optional scale * @param nullable true if NULL, else NOT NULL * @param defaultValue the optional default value * @return the SQL code */ String columnTypeNullDefaultToString(String columnName, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue); /** * Converts a type and value to a literal string. * * @param sqlType the sql type * @param value the value * @return the constant */ String valueToLiteral(SqlType sqlType, Object value); /** * The all SQL statement separators. * * @return the separators, usually {@code ";"} */ String[] getStatementSeparators(); /** * The SQL statement separator used in generated code. * * @return the separator, usually {@code ";"} */ String getStatementSeparator(); /** * Gets all strings that begin a single line comment. * * @return the single line comment strings, usually {@code "--"} */ String[] getSingleLineComments(); /** * Gets the string to begin a single line comment in generated code. * * @return the single line comment string, usually {@code "--"} */ String getSingleLineComment(); /** * Gets all strings that begin a block comment. * * @return the strings to begin a block comment, usually {@code "/*"} */ String[] getBlockCommentBegins(); /** * Gets the string to begin a block comment in generated code. * * @return the string to begin a block comment, usually {@code "/*"} */ String getBlockCommentBegin(); /** * Gets all strings that end a block comment. * * @return the strings to end a block comment, usually {@code "*/"} */ String[] getBlockCommentEnds(); /** * Gets the string to end a block comment in generated code. * * @return the string to end a block comment, usually {@code "*/"} */ String getBlockCommentEnd(); /** * Generates the first line of a CREATE TABLE statement. * * @param tableName the tablename with optional schema separated by a dot * @param comment optional comment, null if none * @return the SQL code including the opening bracket */ String sqlCreateTableIntro(String tableName, String comment); /** * Generates the last line of a CREATE TABLE statement. * * @param tableName the tablename with optional schema separated by a dot * @param comment optional comment, null if none * @return the SQL code including the closing bracket */ String sqlCreateTableClosing(String tableName, String comment); /** * Generates SQL code to create the comment for a table.
* * @param tableName the table name * @param comment optional comment, null if none * @return the SQL code, empty string if comment is created via {@link #sqlCreateTableIntro} or {@link #sqlCreateTableClosing} */ String sqlCreateTableComment(String tableName, String comment); /** * Generates SQL code to alter the comment for a table.
* * @param tableName the table name * @param comment optional comment, null to clear * @return the SQL code */ String sqlAlterTableComment(String tableName, String comment); /** * Generates the attribute definition of a CREATE TABLE statement. * * @param columnName the database column name * @param comment optional comment, null if none * @param sqlType the JDBC sql type * @param size the optional size * @param scale the optional scale * @param nullable true if NULL, else NOT NULL * @param defaultValue the optional default value * @param primaryKey true if this is a primary key * @param withTrailingComma true if append a comma * @return the SQL code */ String sqlCreateColumn(String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue, boolean primaryKey, boolean withTrailingComma); /** * Checks whether the column's default corresponds to the model's default value. * * @param column the column to inspect * @param sqlType the sql type * @param defaultValue the model's default value * @return true if same */ boolean isDefaultEqual(ColumnMetaData column, SqlType sqlType, Object defaultValue); /** * Determines the best migration strategy. * * @param column old column meta data * @param columnName new column name * @param comment new comment * @param sqlType new sql type * @param size new size * @param scale new scale * @param nullable new nullable * @param defaultValue new default * @return the strategies in order to achieve the migration */ MigrationStrategy[] getMigrationStrategy(ColumnMetaData column, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue); /** * Generate sql code to rename a table. * * @param tableName the old tablename (with leading schema, if any) * @param newTableName the new tablename (without schema) * @return the SQL code */ String sqlRenameTable(String tableName, String newTableName); /** * Generates sql code to rename a column. * * @param tableName the tablename * @param oldColumnName the old column name * @param newColumnName the new column name * @return the SQL code, null if full spec sqlRenameAndAlterColumnType below is necessary */ String sqlRenameColumn(String tableName, String oldColumnName, String newColumnName); /** * Generates sql code to rename an index. * * @param tableName the tablename * @param oldIndexName the old column name * @param newIndexName the new column name * @return the SQL code, null if not supported by the backend, and we need to drop and create */ String sqlRenameIndex(String tableName, String oldIndexName, String newIndexName); /** * Generates sql code to rename a column. * * @param tableName the tablename * @param oldColumnName the old column name * @param newColumnName the new column name * @param comment optional comment, null if none * @param sqlType the JDBC sql type * @param size the optional size * @param scale the optional scale * @param nullable true if NULL, else NOT NULL * @param defaultValue the optional default value * @return the SQL code */ String sqlRenameAndAlterColumnType(String tableName, String oldColumnName, String newColumnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue); /** * Generates sql code to add a column. * * @param tableName the tablename * @param columnName the new column name * @param comment optional comment, null if none * @param sqlType the JDBC sql type * @param size the optional size * @param scale the optional scale * @param nullable true if NULL, else NOT NULL * @param defaultValue the optional default value * @return the SQL code */ String sqlAddColumn(String tableName, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue); /** * Generates sql code to drop a column. * * @param tableName the tablename * @param columnName the new column name * @return the SQL code */ String sqlDropColumn(String tableName, String columnName); /** * Generates sql code to change the datatype of a column. * * @param tableName the tablename * @param columnName the new column name * @param comment optional comment, null if none * @param sqlType the JDBC sql type * @param size the optional size * @param scale the optional scale * @param nullable true if NULL, else NOT NULL * @param defaultValue the optional default value * @return the SQL code */ String sqlAlterColumnType(String tableName, String columnName, String comment, SqlType sqlType, int size, int scale, boolean nullable, Object defaultValue); /** * Generates code to update a column to a non-null value. * * @param tableName the tablename * @param columnName the column name * @param sqlType the sql type * @param defaultValue the optional default value if defined in the model * @param migrated true if column is migrated, false if added * @return the SQL code */ String sqlUpdateToNotNull(String tableName, String columnName, SqlType sqlType, Object defaultValue, boolean migrated); /** * Generates sql code to change the null-constraint of a column. * * @param tableName the tablename * @param columnName the new column name * @param nullable true if NULL, else NOT NULL * @return the SQL code, null if need {@link #sqlAlterColumnType} */ String sqlAlterColumnNullConstraint(String tableName, String columnName, boolean nullable); /** * Generates sql code to change the default value a column. * * @param tableName the tablename * @param columnName the new column name * @param sqlType the JDBC sql type * @param defaultValue the optional default value * @return the SQL code, null if need {@link #sqlAlterColumnType} */ String sqlAlterColumnDefault(String tableName, String columnName, SqlType sqlType, Object defaultValue); /** * Generates SQL code to create the comment for an attribute.
* * @param tableName the table name * @param columnName the column name * @param comment optional comment, null if none * @return the SQL code, empty string if comment is created via {@link #sqlCreateColumn} */ String sqlCreateColumnComment(String tableName, String columnName, String comment); /** * Generates the CREATE INDEX statement. * * @param tableName the table name * @param indexName the name of the index * @param unique true if index is unique * @param filterCondition the filter condition (null if none) * @param columnNames the column names (with a leading '-' if descending). Simple function-based indexes are also supported. * @return the SQL code */ String sqlCreateIndex(String tableName, String indexName, boolean unique, String filterCondition, String... columnNames); /** * Generates the DROP INDEX statement. * * @param schemaName the optional schema, null if none * @param tableNameWithoutSchema the table name without the schema * @param indexName the name of the index * @return the SQL code */ String sqlDropIndex(String schemaName, String tableNameWithoutSchema, String indexName); /** * Generates the DROP TABLE statement. * * @param schemaName the optional schema, null if none * @param tableNameWithoutSchema the table name without the schema * @return the SQL code */ String sqlDropTable(String schemaName, String tableNameWithoutSchema); /** * Generates the ALTER TABLE statement to add a foreign key constraint. * * @param referencingTableName the referencing foreign table name * @param referencingColumnName the referencing foreign column name * @param referencedTableName the referenced primary table name * @param referencedColumnName the referenced primary column name * @param foreignKeyName the name of the foreign key * @param composite true if referencing table is a component of the referenced table * @return the SQL code */ String sqlCreateForeignKey(String referencingTableName, String referencingColumnName, String referencedTableName, String referencedColumnName, String foreignKeyName, boolean composite); /** * Generates the sql statement to drop a foreign key constraint. * * @param referencingTableName the referencing foreign table name * @param foreignKeyName the name of the foreign key * @return the SQL code */ String sqlDropForeignKey(String referencingTableName, String foreignKeyName); /** * Generates SQL code to alter the comment for an attribute.
* * @param tableName the table name * @param columnName the column name * @param comment optional comment, null to clear * @return the SQL code, null if {@link #sqlRenameAndAlterColumnType} must be used instead */ String sqlAlterColumnComment(String tableName, String columnName, String comment); /** * Generate SQL-code for joining a table to an existing select. * * @param type the join type * @param addColumns true if columns of joined table should be added to the result set * @param select the original select statement * @param joinSelect the select to join with the original sql or just a tablename * @param joinSelectIdAlias extra id alias to add to the joined select, null if none * @param joinAlias the alias of the joined select * @param join the join clause */ void sqlJoinSelects(JoinType type, boolean addColumns, StringBuilder select, String joinSelect, String joinSelectIdAlias, String joinAlias, String join); /** * Generate SQL-code for joining a table to an existing select. * * @param type the join type * @param addColumns true if columns of joined table should be added to the result set * @param select the original select statement * @param joinSelect the select to join with the original sql or just a tablename * @param joinSelectIdAlias extra id alias to add to the joined select, null if none * @param joinAlias the alias of the joined select * @param join the join clause * @return the select statement */ String sqlJoinSelects(JoinType type, boolean addColumns, String select, String joinSelect, String joinSelectIdAlias, String joinAlias, String join); /** * Converts the JDBC data type integer to a tentackle backend SqlTypes. *

* There may be more than one sqltype returned! * * @param jdbcType the jdbc data type * @param size the column size * @param scale the column's scale * @return the SqlTypes, empty array if no mapping available or no exact match (not generated by TT) * @see java.sql.Types */ SqlType[] jdbcTypeToSqlType(int jdbcType, int size, int scale); /** * Gets the table metadata for a given table name. * * @param modelMetaData the model the table belongs to * @param tableName the model's table name * @return the table data */ TableMetaData getTableMetaData(ModelMetaData modelMetaData, String tableName); /** * Converts a string to a string enclosed in single quotes. * * @param str the string * @return the quoted string */ String toQuotedString(String str); /** * Optimize SQL code.
* Replace WHERE 1=1 AND/OR to WHERE. * Any remaining WHERE 1=1 will be removed too. * If you don't want your statements getting optimized, use lowercase for those keywords. * * @param sql the original sql code * @return the optimized sql code */ String optimizeSql(String sql); /** * Returns whether the backend supports releasing savepoints explicitly. * If not, the savepoints are released when the transaction finishs. * * @return true if release is supported, else false */ boolean isReleaseSavepointSupported(); /** * Returns whether the backend support CLOB types.
* If not, it will be emulated as VARCHAR with the maximum possible size. * * @return true if supported, false if treat as varchar */ boolean isClobSupported(); /** * Returns whether the backend supports the {@link java.util.UUID} natively via JDBC setObject/getObject. * * @return true if supported, false if mapped to VARCHAR(36) */ boolean isUUIDSupported(); /** * Returns whether function based indexes are supported. * * @return true if supported */ boolean isFunctionBasedIndexSupported(); /** * Returns whether backend supports filtered indexes. * * @return true if supported, false if model will raise an error if filtered index is used */ boolean isFilteredIndexSupported(); /** * Some database support drop index/constraint/column {@code IF EXISTS}.
* This may be useful if migration scripts are generated against non-production databases * that contain test indexes etc...
* Notice, that those temporary DDL changes should better use the temporary prefix (see {@link #isTemporaryName(String)}) in * order to be ignored by the migrator. * * @param dropIfExists true if {@code IF EXISTS} should be used */ void setDropIfExistsEnabled(boolean dropIfExists); /** * Returns whether backend should add {@code IF EXISTS} for generated DROPs. * * @return true if {@code IF EXISTS} is turned on and supported, false if not supported or turned off */ boolean isDropIfExistsEnabled(); /** * Converts a backend specific type name to an internal name used by driver specific methods. * * @param sqlTypeName the original type used in SQL scripts * @return the JDBC internal name */ String toInternalType(String sqlTypeName); /** * Returns whether the backend supports given array operator. * * @param operator the array operator * @return true if supported */ boolean isArrayOperatorSupported(String operator); /** * Sets an array parameter in a prepared statement. * * @param statement the prepared statement * @param pos the parameter position (starting at 1) * @param type the element's SQL type * @param elements the elements to be converted to an array parameter * @param operator the array operator */ void setArray(PreparedStatement statement, int pos, SqlType type, Collection elements, String operator) throws SQLException; /** * Returns whether the backend supports schemas. * * @return true if supported * @see #sqlCreateSchema(String) */ boolean isSchemaSupported(); /** * Returns whether the backend supports posix-style escapes via backslash. * * @return true if supported */ boolean isPosixEscapeSyntaxSupported(); /** * Creates a script runner instance. * * @param connection the SQL-connection */ ScriptRunner createScriptRunner(Connection connection); /** * Returns whether the URL denotes an in-memory database.
* Used by test suites to decide whether to populate the database before running the tests. * * @param url the JDBC url * @return true if in-memory */ boolean isDatabaseInMemory(String url); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy