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_DEFAULT;
}
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 (keywords.contains(objectName.toUpperCase())) {
return "\""+objectName+"\"";
}
}
return objectName;
}
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