Coverage Report - liquibase.database.core.H2Database
 
Classes in this File Line Coverage Branch Coverage Complexity
H2Database
35%
20/57
20%
6/30
2.3
 
 1  
 package liquibase.database.core;
 2  
 
 3  
 import liquibase.database.DatabaseConnection;
 4  
 import liquibase.database.AbstractDatabase;
 5  
 import liquibase.exception.DatabaseException;
 6  
 import liquibase.exception.DateParseException;
 7  
 import liquibase.statement.DatabaseFunction;
 8  
 import liquibase.util.ISODateFormat;
 9  
 
 10  
 import java.text.ParseException;
 11  
 import java.text.SimpleDateFormat;
 12  
 import java.text.DateFormat;
 13  
 import java.util.Date;
 14  
 import java.util.Arrays;
 15  
 import java.util.List;
 16  
 
 17  
 public class H2Database extends AbstractDatabase {
 18  
 
 19  1
     private static String START_CONCAT = "CONCAT(";
 20  1
     private static String END_CONCAT = ")";
 21  1
     private static String SEP_CONCAT = ", ";
 22  
 
 23  15
     public H2Database() {
 24  15
         this.databaseFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP()"));
 25  15
     }
 26  
 
 27  
     public String getTypeName() {
 28  59
         return "h2";
 29  
     }
 30  
 
 31  
     public String getDefaultDriver(String url) {
 32  2
         if (url.startsWith("jdbc:h2")) {
 33  1
             return "org.h2.Driver";
 34  
         }
 35  1
         return null;
 36  
     }
 37  
 
 38  
     public int getPriority() {
 39  0
         return PRIORITY_DATABASE;
 40  
     }
 41  
 
 42  
     public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
 43  1
         return "H2".equals(conn.getDatabaseProductName());
 44  
     }
 45  
 
 46  
     // public void dropDatabaseObjects(String schema) throws DatabaseException {
 47  
     // DatabaseConnection conn = getConnection();
 48  
     // Statement dropStatement = null;
 49  
     // try {
 50  
     // dropStatement = conn.createStatement();
 51  
     // dropStatement.executeUpdate("DROP ALL OBJECTS");
 52  
     // changeLogTableExists = false;
 53  
     // changeLogLockTableExists = false;
 54  
     // changeLogCreateAttempted = false;
 55  
     // changeLogLockCreateAttempted = false;
 56  
     // } catch (SQLException e) {
 57  
     // throw new DatabaseException(e);
 58  
     // } finally {
 59  
     // try {
 60  
     // if (dropStatement != null) {
 61  
     // dropStatement.close();
 62  
     // }
 63  
     // conn.commit();
 64  
     // } catch (SQLException e) {
 65  
     // ;
 66  
     // }
 67  
     // }
 68  
     //
 69  
     // }
 70  
 
 71  
     public boolean supportsTablespaces() {
 72  0
         return false;
 73  
     }
 74  
 
 75  
     @Override
 76  
     public String getViewDefinition(String schemaName, String name) throws DatabaseException {
 77  0
         String definition = super.getViewDefinition(schemaName, name);
 78  0
         if (!definition.startsWith("SELECT")) {
 79  0
             definition = definition.replaceFirst(".*?\n", ""); // some h2 versions return "create view....as\nselect
 80  
         }
 81  
 
 82  0
         definition = definition.replaceFirst("/\\*.*", ""); // sometimes includes comments at the end
 83  0
         return definition;
 84  
     }
 85  
 
 86  
     @Override
 87  
     public Date parseDate(String dateAsString) throws DateParseException {
 88  
         try {
 89  0
             if (dateAsString.indexOf(' ') > 0) {
 90  0
                 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS").parse(dateAsString);
 91  
             } else {
 92  0
                 if (dateAsString.indexOf(':') > 0) {
 93  0
                     return new SimpleDateFormat("HH:mm:ss").parse(dateAsString);
 94  
                 } else {
 95  0
                     return new SimpleDateFormat("yyyy-MM-dd").parse(dateAsString);
 96  
                 }
 97  
             }
 98  0
         } catch (ParseException e) {
 99  0
             throw new DateParseException(dateAsString);
 100  
         }
 101  
     }
 102  
 
 103  
     @Override
 104  
     public boolean isLocalDatabase() throws DatabaseException {
 105  0
         String url = getConnection().getURL();
 106  0
         boolean isLocalURL = (super.isLocalDatabase() || url.startsWith("jdbc:h2:file:")
 107  
                 || url.startsWith("jdbc:h2:mem:") || url.startsWith("jdbc:h2:zip:") || url.startsWith("jdbc:h2:~"));
 108  0
         return isLocalURL;
 109  
     }
 110  
 
 111  
     // @Override
 112  
     // public String convertRequestedSchemaToSchema(String requestedSchema) throws DatabaseException {
 113  
     // return super.convertRequestedSchemaToSchema(requestedSchema).toLowerCase();
 114  
     // }
 115  
 
 116  
     @Override
 117  
     public boolean supportsSequences() {
 118  14
         return true;
 119  
     }
 120  
 
 121  
     @Override
 122  
     protected String getDefaultDatabaseSchemaName() throws DatabaseException {
 123  0
         return "PUBLIC";
 124  
     }
 125  
 
 126  
     @Override
 127  
     public String getAutoIncrementClause() {
 128  0
         return "GENERATED BY DEFAULT AS IDENTITY IDENTITY";
 129  
     }
 130  
 
 131  
     @Override
 132  
     public String getConcatSql(String... values) {
 133  0
         if (values == null) {
 134  0
             return null;
 135  
         }
 136  
 
 137  0
         return getConcatSql(Arrays.asList(values));
 138  
     }
 139  
 
 140  
     /**
 141  
      * Recursive way of building CONCAT instruction
 142  
      * 
 143  
      * @param values
 144  
      *            a non null List of String
 145  
      * @return a String containing the CONCAT instruction with all elements, or only a value if there is only one
 146  
      *         element in the list
 147  
      */
 148  
     private String getConcatSql(List<String> values) {
 149  0
         if (values.size() == 1) {
 150  0
             return values.get(0);
 151  
         } else {
 152  0
             return START_CONCAT + values.get(0) + SEP_CONCAT + getConcatSql(values.subList(1, values.size()))
 153  
                     + END_CONCAT;
 154  
         }
 155  
     }
 156  
 
 157  
     @Override
 158  
     public String getDateLiteral(String isoDate) {
 159  0
         String returnString = isoDate;
 160  
         try {
 161  0
             if (isDateTime(isoDate)) {
 162  0
                 ISODateFormat isoTimestampFormat = new ISODateFormat();
 163  0
                 DateFormat dbTimestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
 164  0
                 returnString = dbTimestampFormat.format(isoTimestampFormat.parse(isoDate));
 165  
             }
 166  0
         } catch (ParseException e) {
 167  0
             throw new RuntimeException("Unexpected date format: " + isoDate, e);
 168  0
         }
 169  0
         return "'" + returnString + "'";
 170  
     }
 171  
 
 172  
     @Override
 173  
     public String convertRequestedSchemaToSchema(String requestedSchema) throws DatabaseException {
 174  0
         return super.convertRequestedSchemaToSchema(requestedSchema).toUpperCase();
 175  
     }
 176  
 
 177  
     @Override
 178  
     public String escapeDatabaseObject(String objectName) {
 179  13
         if (objectName != null) {
 180  7
             if (isReservedWord(objectName)) {
 181  0
                 return "\"" + objectName + "\"";
 182  
             }
 183  
         }
 184  13
         return objectName;
 185  
     }
 186  
 
 187  
     @Override
 188  
     public boolean isReservedWord(String objectName) {
 189  7
         return keywords.contains(objectName.toUpperCase());
 190  
     }
 191  
 
 192  1
     private static List keywords = Arrays.asList(
 193  
     // "ADD",
 194  
     // "ALL",
 195  
     // "ALLOCATE",
 196  
     // "ALTER",
 197  
     // "AND",
 198  
     // "ANY",
 199  
     // "ARE",
 200  
     // "ARRAY",
 201  
     // "AS",
 202  
     // "ASENSITIVE",
 203  
     // "ASYMMETRIC",
 204  
     // "AT",
 205  
     // "ATOMIC",
 206  
     // "AUTHORIZATION",
 207  
     // "BEGIN",
 208  
     // "BETWEEN",
 209  
     // "BIGINT",
 210  
     // "BINARY",
 211  
     // "BLOB",
 212  
     // "BOOLEAN",
 213  
     // "BOTH",
 214  
     // "BY",
 215  
     // "CALL",
 216  
     // "CALLED",
 217  
     // "CASCADED",
 218  
     // "CASE",
 219  
     // "CAST",
 220  
     // "CHAR",
 221  
     // "CHARACTER",
 222  
     // "CHECK",
 223  
     // "CLOB",
 224  
     // "CLOSE",
 225  
     // "COLLATE",
 226  
     // "COLUMN",
 227  
     // "COMMIT",
 228  
     // "CONDITION",
 229  
     // "CONNECT",
 230  
     // "CONSTRAINT",
 231  
     // "CONTINUE",
 232  
     // "CORRESPONDING",
 233  
     // "CREATE",
 234  
     // "CROSS",
 235  
     // "CUBE",
 236  
     // "CURRENT",
 237  
     // "CURRENT_DATE",
 238  
     // "CURRENT_DEFAULT_TRANSFORM_GRO",
 239  
     // "CURRENT_PATH",
 240  
     // "CURRENT_ROLE",
 241  
     // "CURRENT_TIME",
 242  
     // "CURRENT_TIMESTAMP",
 243  
     // "CURRENT_TRANSFORM_GROUP_FOR_T",
 244  
     // "CURRENT_USER",
 245  
     // "CURSOR",
 246  
     // "CYCLE",
 247  
     // "DATE",
 248  
     // "DAY",
 249  
     // "DEALLOCATE",
 250  
     // "DEC",
 251  
     // "DECIMAL",
 252  
     // "DECLARE",
 253  
     // "DEFAULT",
 254  
     // "DELETE",
 255  
     // "DEREF",
 256  
     // "DESCRIBE",
 257  
     // "DETERMINISTIC",
 258  
     // "DISCONNECT",
 259  
     // "DISTINCT",
 260  
     // "DO",
 261  
     // "DOUBLE",
 262  
     // "DROP",
 263  
     // "DYNAMIC",
 264  
     // "EACH",
 265  
     // "ELEMENT",
 266  
     // "ELSE",
 267  
     // "ELSEIF",
 268  
     // "END",
 269  
     // "ESCAPE",
 270  
     // "EXCEPT",
 271  
     // "EXEC",
 272  
     // "EXECUTE",
 273  
     // "EXISTS",
 274  
     // "EXIT",
 275  
     // "EXTERNAL",
 276  
     // "FALSE",
 277  
     // "FETCH",
 278  
     // "FILTER",
 279  
     // "FLOAT",
 280  
     // "FOR",
 281  
     // "FOREIGN",
 282  
     // "FREE",
 283  
     // "FROM",
 284  
     // "FULL",
 285  
     // "FUNCTION",
 286  
     // "GET",
 287  
     // "GLOBAL",
 288  
     // "GRANT",
 289  
     // "GROUP",
 290  
     // "GROUPING",
 291  
     // "HANDLER",
 292  
     // "HAVING",
 293  
     // "HOLD",
 294  
     // "HOUR",
 295  
     // "IDENTITY",
 296  
     // "IF",
 297  
     // "IMMEDIATE",
 298  
     // "IN",
 299  
     // "INDICATOR",
 300  
     // "INNER",
 301  
     // "INOUT",
 302  
     // "INPUT",
 303  
     // "INSENSITIVE",
 304  
     // "INSERT",
 305  
     // "INT",
 306  
     // "INTEGER",
 307  
     // "INTERSECT",
 308  
     // "INTERVAL",
 309  
     // "INTO",
 310  
     // "IS",
 311  
     // "ITERATE",
 312  
     // "JOIN",
 313  
     // "LANGUAGE",
 314  
     // "LARGE",
 315  
     // "LATERAL",
 316  
     // "LEADING",
 317  
     // "LEAVE",
 318  
     // "LEFT",
 319  
     // "LIKE",
 320  
     // "LOCAL",
 321  
     // "LOCALTIME",
 322  
     // "LOCALTIMESTAMP",
 323  
     // "LOOP",
 324  
     // "MATCH",
 325  
     // "MEMBER",
 326  
     // "MERGE",
 327  
     // "METHOD",
 328  
     // "MINUTE",
 329  
     // "MODIFIES",
 330  
     // "MODULE",
 331  
     // "MONTH",
 332  
     // "MULTISET",
 333  
     // "NATIONAL",
 334  
     // "NATURAL",
 335  
     // "NCHAR",
 336  
     // "NCLOB",
 337  
     // "NEW",
 338  
     // "NO",
 339  
     // "NONE",
 340  
     // "NOT",
 341  
     // "NULL",
 342  
     // "NUMERIC",
 343  
     // "OF",
 344  
     // "OLD",
 345  
     // "ON",
 346  
     // "ONLY",
 347  
     // "OPEN",
 348  
     // "OR",
 349  
     // "ORDER",
 350  
     // "OUT",
 351  
     // "OUTER",
 352  
     // "OUTPUT",
 353  
     // "OVER",
 354  
     // "OVERLAPS",
 355  
     // "PARAMETER",
 356  
     // "PARTITION",
 357  
     // "PRECISION",
 358  
     // "PREPARE",
 359  
     // "PRIMARY",
 360  
     // "PROCEDURE",
 361  
     // "RANGE",
 362  
     // "READS",
 363  
     // "REAL",
 364  
     // "RECURSIVE",
 365  
     // "REF",
 366  
     // "REFERENCES",
 367  
     // "REFERENCING",
 368  
     // "RELEASE",
 369  
     // "REPEAT",
 370  
     // "RESIGNAL",
 371  
     // "RESULT",
 372  
     // "RETURN",
 373  
     // "RETURNS",
 374  
     // "REVOKE",
 375  
     // "RIGHT",
 376  
     // "ROLLBACK",
 377  
     // "ROLLUP",
 378  
     // "ROW",
 379  
     // "ROWS",
 380  
     // "SAVEPOINT",
 381  
     // "SCOPE",
 382  
     // "SCROLL",
 383  
     // "SEARCH",
 384  
     // "SECOND",
 385  
     // "SELECT",
 386  
     // "SENSITIVE",
 387  
     // "SESSION_USER",
 388  
     // "SET",
 389  
     // "SIGNAL",
 390  
     // "SIMILAR",
 391  
     // "SMALLINT",
 392  
     // "SOME",
 393  
     // "SPECIFIC",
 394  
     // "SPECIFICTYPE",
 395  
     // "SQL",
 396  
     // "SQLEXCEPTION",
 397  
     // "SQLSTATE",
 398  
     // "SQLWARNING",
 399  
     // "START",
 400  
     // "STATIC",
 401  
     // "SUBMULTISET",
 402  
     // "SYMMETRIC",
 403  
     // "SYSTEM",
 404  
     // "SYSTEM_USER",
 405  
     // "TABLE",
 406  
     // "TABLESAMPLE",
 407  
     // "THEN",
 408  
     // "TIME",
 409  
     // "TIMESTAMP",
 410  
     // "TIMEZONE_HOUR",
 411  
     // "TIMEZONE_MINUTE",
 412  
     // "TO",
 413  
     // "TRAILING",
 414  
     // "TRANSLATION",
 415  
     // "TREAT",
 416  
     // "TRIGGER",
 417  
     // "TRUE",
 418  
     // "UNDO",
 419  
     // "UNION",
 420  
     // "UNIQUE",
 421  
     // "UNKNOWN",
 422  
     // "UNNEST",
 423  
     // "UNTIL",
 424  
     // "UPDATE",
 425  
             "USER",
 426  
             // "USING",
 427  
             // "VALUE",
 428  
             // "VALUES",
 429  
             // "VARCHAR",
 430  
             // "VARYING",
 431  
             // "WHEN",
 432  
             // "WHENEVER",
 433  
             // "WHERE",
 434  
             // "WHILE",
 435  
             // "WINDOW",
 436  
             // "WITH",
 437  
             // "WITHIN",
 438  
             // "WITHOUT",
 439  
             // "YEAR",
 440  
             // "ALIAS",
 441  
             // "AUTOCOMMIT",
 442  
             // "CACHED",
 443  
             // "CHECKPOINT",
 444  
             // "EXPLAIN",
 445  
             // "IGNORECASE",
 446  
             // "INDEX",
 447  
             // "LOGSIZE",
 448  
             // "MATCHED",
 449  
             // "MAXROWS",
 450  
             // "MEMORY",
 451  
             // "MINUS",
 452  
             // "NEXT",
 453  
             // "OPENBRACKET",
 454  
             "PASSWORD"
 455  
     // "PLAN",
 456  
     // "PROPERTY",
 457  
     // "READONLY",
 458  
     // "REFERENTIAL_INTEGRITY",
 459  
     // "RENAME",
 460  
     // "RESTART",
 461  
     // "SCRIPT",
 462  
     // "SCRIPTFORMAT",
 463  
     // "SEMICOLON",
 464  
     // "SEQUENCE",
 465  
     // "SHUTDOWN",
 466  
     // "SOURCE",
 467  
     // "TEMP",
 468  
     // "TEXT",
 469  
     // "VIEW",
 470  
     // "WRITE_DELAY",
 471  
     // "VAR_POP",
 472  
     // "VAR_SAMP",
 473  
     // "STDDEV_POP",
 474  
     // "STDDEV_SAMP",
 475  
     // "DEFRAG",
 476  
     // "INCREMENT",
 477  
     // "TOCHAR",
 478  
     // "DATABASE",
 479  
     // "SCHEMA",
 480  
     // "ROLE",
 481  
     // "DOW",
 482  
     // "INITIAL"
 483  
             );
 484  
 
 485  
     public boolean supportsInitiallyDeferrableColumns() {
 486  1
         return false;
 487  
     }
 488  
 
 489  
     public String getCurrentDateTimeFunction() {
 490  1
         if (currentDateTimeFunction != null) {
 491  0
             return currentDateTimeFunction;
 492  
         }
 493  
 
 494  1
         return "NOW()";
 495  
     }
 496  
 
 497  
 }