liquibase.database.core.H2Database Maven / Gradle / Ivy
package liquibase.database.core;
import liquibase.database.DatabaseConnection;
import liquibase.database.AbstractDatabase;
import liquibase.exception.DatabaseException;
import liquibase.exception.DateParseException;
import liquibase.statement.DatabaseFunction;
import liquibase.util.ISODateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Date;
import java.util.Arrays;
import java.util.List;
public class H2Database extends AbstractDatabase {
private static String START_CONCAT = "CONCAT(";
private static String END_CONCAT = ")";
private static String SEP_CONCAT = ", ";
public H2Database() {
this.databaseFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP()"));
}
public String getTypeName() {
return "h2";
}
public String getDefaultDriver(String url) {
if (url.startsWith("jdbc:h2")) {
return "org.h2.Driver";
}
return null;
}
public int getPriority() {
return PRIORITY_DATABASE;
}
public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
return "H2".equals(conn.getDatabaseProductName());
}
// public void dropDatabaseObjects(String schema) throws DatabaseException {
// DatabaseConnection conn = getConnection();
// Statement dropStatement = null;
// try {
// dropStatement = conn.createStatement();
// dropStatement.executeUpdate("DROP ALL OBJECTS");
// changeLogTableExists = false;
// changeLogLockTableExists = false;
// changeLogCreateAttempted = false;
// changeLogLockCreateAttempted = false;
// } catch (SQLException e) {
// throw new DatabaseException(e);
// } finally {
// try {
// if (dropStatement != null) {
// dropStatement.close();
// }
// conn.commit();
// } catch (SQLException e) {
// ;
// }
// }
//
// }
public boolean supportsTablespaces() {
return false;
}
@Override
public String getViewDefinition(String schemaName, String name) throws DatabaseException {
String definition = super.getViewDefinition(schemaName, name);
if (!definition.startsWith("SELECT")) {
definition = definition.replaceFirst(".*?\n", ""); //some h2 versions return "create view....as\nselect
}
definition = definition.replaceFirst("/\\*.*",""); //sometimes includes comments at the end
return definition;
}
@Override
public Date parseDate(String dateAsString) throws DateParseException {
try {
if (dateAsString.indexOf(' ') > 0) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS").parse(dateAsString);
} else {
if (dateAsString.indexOf(':') > 0) {
return new SimpleDateFormat("HH:mm:ss").parse(dateAsString);
} else {
return new SimpleDateFormat("yyyy-MM-dd").parse(dateAsString);
}
}
} catch (ParseException e) {
throw new DateParseException(dateAsString);
}
}
@Override
public boolean isLocalDatabase() throws DatabaseException {
String url = getConnection().getURL();
boolean isLocalURL = (
super.isLocalDatabase()
|| url.startsWith("jdbc:h2:file:")
|| url.startsWith("jdbc:h2:mem:")
|| url.startsWith("jdbc:h2:zip:")
|| url.startsWith("jdbc:h2:~")
);
return isLocalURL;
}
// @Override
// public String convertRequestedSchemaToSchema(String requestedSchema) throws DatabaseException {
// return super.convertRequestedSchemaToSchema(requestedSchema).toLowerCase();
// }
@Override
public boolean supportsSequences() {
return true;
}
@Override
protected String getDefaultDatabaseSchemaName() throws DatabaseException {
return "PUBLIC";
}
@Override
public String getAutoIncrementClause() {
return "GENERATED BY DEFAULT AS IDENTITY IDENTITY";
}
@Override
public String getConcatSql(String... values) {
if (values == null) {
return null;
}
return getConcatSql(Arrays.asList(values));
}
/**
* Recursive way of building CONCAT instruction
*
* @param values a non null List of String
* @return a String containing the CONCAT instruction with all elements, or only a value if there is only one element in the list
*/
private String getConcatSql(List values) {
if (values.size() == 1) {
return values.get(0);
} else {
return START_CONCAT + values.get(0) + SEP_CONCAT + getConcatSql(values.subList(1, values.size())) + END_CONCAT;
}
}
@Override
public String getDateLiteral(String isoDate) {
String returnString = isoDate;
try {
if (isDateTime(isoDate)) {
ISODateFormat isoTimestampFormat = new ISODateFormat();
DateFormat dbTimestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
returnString = dbTimestampFormat.format(isoTimestampFormat.parse(isoDate));
}
} catch (ParseException e) {
throw new RuntimeException("Unexpected date format: " + isoDate, e);
}
return "'" + returnString + "'";
}
@Override
public String convertRequestedSchemaToSchema(String requestedSchema) throws DatabaseException {
return super.convertRequestedSchemaToSchema(requestedSchema).toUpperCase();
}
@Override
public String escapeDatabaseObject(String objectName) {
if (objectName != null) {
if (isReservedWord(objectName)) {
return "\""+objectName+"\"";
}
}
return objectName;
}
@Override
public boolean isReservedWord(String objectName) {
return keywords.contains(objectName.toUpperCase());
}
private static List keywords = Arrays.asList(
// "ADD",
// "ALL",
// "ALLOCATE",
// "ALTER",
// "AND",
// "ANY",
// "ARE",
// "ARRAY",
// "AS",
// "ASENSITIVE",
// "ASYMMETRIC",
// "AT",
// "ATOMIC",
// "AUTHORIZATION",
// "BEGIN",
// "BETWEEN",
// "BIGINT",
// "BINARY",
// "BLOB",
// "BOOLEAN",
// "BOTH",
// "BY",
// "CALL",
// "CALLED",
// "CASCADED",
// "CASE",
// "CAST",
// "CHAR",
// "CHARACTER",
// "CHECK",
// "CLOB",
// "CLOSE",
// "COLLATE",
// "COLUMN",
// "COMMIT",
// "CONDITION",
// "CONNECT",
// "CONSTRAINT",
// "CONTINUE",
// "CORRESPONDING",
// "CREATE",
// "CROSS",
// "CUBE",
// "CURRENT",
// "CURRENT_DATE",
// "CURRENT_DEFAULT_TRANSFORM_GRO",
// "CURRENT_PATH",
// "CURRENT_ROLE",
// "CURRENT_TIME",
// "CURRENT_TIMESTAMP",
// "CURRENT_TRANSFORM_GROUP_FOR_T",
// "CURRENT_USER",
// "CURSOR",
// "CYCLE",
// "DATE",
// "DAY",
// "DEALLOCATE",
// "DEC",
// "DECIMAL",
// "DECLARE",
// "DEFAULT",
// "DELETE",
// "DEREF",
// "DESCRIBE",
// "DETERMINISTIC",
// "DISCONNECT",
// "DISTINCT",
// "DO",
// "DOUBLE",
// "DROP",
// "DYNAMIC",
// "EACH",
// "ELEMENT",
// "ELSE",
// "ELSEIF",
// "END",
// "ESCAPE",
// "EXCEPT",
// "EXEC",
// "EXECUTE",
// "EXISTS",
// "EXIT",
// "EXTERNAL",
// "FALSE",
// "FETCH",
// "FILTER",
// "FLOAT",
// "FOR",
// "FOREIGN",
// "FREE",
// "FROM",
// "FULL",
// "FUNCTION",
// "GET",
// "GLOBAL",
// "GRANT",
// "GROUP",
// "GROUPING",
// "HANDLER",
// "HAVING",
// "HOLD",
// "HOUR",
// "IDENTITY",
// "IF",
// "IMMEDIATE",
// "IN",
// "INDICATOR",
// "INNER",
// "INOUT",
// "INPUT",
// "INSENSITIVE",
// "INSERT",
// "INT",
// "INTEGER",
// "INTERSECT",
// "INTERVAL",
// "INTO",
// "IS",
// "ITERATE",
// "JOIN",
// "LANGUAGE",
// "LARGE",
// "LATERAL",
// "LEADING",
// "LEAVE",
// "LEFT",
// "LIKE",
// "LOCAL",
// "LOCALTIME",
// "LOCALTIMESTAMP",
// "LOOP",
// "MATCH",
// "MEMBER",
// "MERGE",
// "METHOD",
// "MINUTE",
// "MODIFIES",
// "MODULE",
// "MONTH",
// "MULTISET",
// "NATIONAL",
// "NATURAL",
// "NCHAR",
// "NCLOB",
// "NEW",
// "NO",
// "NONE",
// "NOT",
// "NULL",
// "NUMERIC",
// "OF",
// "OLD",
// "ON",
// "ONLY",
// "OPEN",
// "OR",
// "ORDER",
// "OUT",
// "OUTER",
// "OUTPUT",
// "OVER",
// "OVERLAPS",
// "PARAMETER",
// "PARTITION",
// "PRECISION",
// "PREPARE",
// "PRIMARY",
// "PROCEDURE",
// "RANGE",
// "READS",
// "REAL",
// "RECURSIVE",
// "REF",
// "REFERENCES",
// "REFERENCING",
// "RELEASE",
// "REPEAT",
// "RESIGNAL",
// "RESULT",
// "RETURN",
// "RETURNS",
// "REVOKE",
// "RIGHT",
// "ROLLBACK",
// "ROLLUP",
// "ROW",
// "ROWS",
// "SAVEPOINT",
// "SCOPE",
// "SCROLL",
// "SEARCH",
// "SECOND",
// "SELECT",
// "SENSITIVE",
// "SESSION_USER",
// "SET",
// "SIGNAL",
// "SIMILAR",
// "SMALLINT",
// "SOME",
// "SPECIFIC",
// "SPECIFICTYPE",
// "SQL",
// "SQLEXCEPTION",
// "SQLSTATE",
// "SQLWARNING",
// "START",
// "STATIC",
// "SUBMULTISET",
// "SYMMETRIC",
// "SYSTEM",
// "SYSTEM_USER",
// "TABLE",
// "TABLESAMPLE",
// "THEN",
// "TIME",
// "TIMESTAMP",
// "TIMEZONE_HOUR",
// "TIMEZONE_MINUTE",
// "TO",
// "TRAILING",
// "TRANSLATION",
// "TREAT",
// "TRIGGER",
// "TRUE",
// "UNDO",
// "UNION",
// "UNIQUE",
// "UNKNOWN",
// "UNNEST",
// "UNTIL",
// "UPDATE",
// "USER",
// "USING",
// "VALUE",
// "VALUES",
// "VARCHAR",
// "VARYING",
// "WHEN",
// "WHENEVER",
// "WHERE",
// "WHILE",
// "WINDOW",
// "WITH",
// "WITHIN",
// "WITHOUT",
// "YEAR",
// "ALIAS",
// "AUTOCOMMIT",
// "CACHED",
// "CHECKPOINT",
// "EXPLAIN",
// "IGNORECASE",
// "INDEX",
// "LOGSIZE",
// "MATCHED",
// "MAXROWS",
// "MEMORY",
// "MINUS",
// "NEXT",
// "OPENBRACKET",
// "PASSWORD",
// "PLAN",
// "PROPERTY",
// "READONLY",
// "REFERENTIAL_INTEGRITY",
// "RENAME",
// "RESTART",
// "SCRIPT",
// "SCRIPTFORMAT",
// "SEMICOLON",
// "SEQUENCE",
// "SHUTDOWN",
// "SOURCE",
// "TEMP",
// "TEXT",
// "VIEW",
// "WRITE_DELAY",
// "VAR_POP",
// "VAR_SAMP",
// "STDDEV_POP",
// "STDDEV_SAMP",
// "DEFRAG",
// "INCREMENT",
// "TOCHAR",
// "DATABASE",
// "SCHEMA",
// "ROLE",
// "DOW",
// "INITIAL"
);
public boolean supportsInitiallyDeferrableColumns() {
return false;
}
public String getCurrentDateTimeFunction() {
if (currentDateTimeFunction != null) {
return currentDateTimeFunction;
}
return "NOW()";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy