|
13 | 13 |
|
14 | 14 | package org.stdg; |
15 | 15 |
|
| 16 | +import org.stdg.dbtype.DatabaseType; |
| 17 | + |
| 18 | +import java.sql.Time; |
| 19 | +import java.sql.Timestamp; |
| 20 | +import java.time.OffsetTime; |
| 21 | +import java.util.Calendar; |
| 22 | + |
16 | 23 | class ColumnValueFormatter { |
17 | 24 |
|
18 | 25 | static final ColumnValueFormatter INSTANCE = new ColumnValueFormatter(); |
19 | 26 |
|
20 | 27 | private ColumnValueFormatter() { } |
21 | 28 |
|
22 | | - String formatColumnValue(Object columnValue) { |
23 | | - if (columnValue instanceof String || columnValue instanceof java.sql.Date) { |
| 29 | + String formatColumnValue(Object columnValue, DatabaseType dbType) { |
| 30 | + if(columnValue == null) { |
| 31 | + return "NULL"; |
| 32 | + } else if(DatabaseType.ORACLE.equals(dbType) |
| 33 | + && columnValue instanceof Timestamp) { |
| 34 | + Timestamp timeStamp = (Timestamp) columnValue; |
| 35 | + return buildOracleToDateFunctionFor(timeStamp); |
| 36 | + } else if(DatabaseType.ORACLE.equals(dbType) |
| 37 | + && isOracleSqlTimestamp(columnValue)) { |
| 38 | + return buildOracleToTimeStampFunctionFor(columnValue); |
| 39 | + } else if (columnValue instanceof String |
| 40 | + || columnValue instanceof java.sql.Date |
| 41 | + || columnValue instanceof Timestamp |
| 42 | + || columnValue instanceof Time |
| 43 | + || columnValue instanceof OffsetTime |
| 44 | + || isTimestampWithTimeZoneH2Type(columnValue)) { |
24 | 45 | String stringColumnValue = columnValue.toString(); |
25 | 46 | return "'" + stringColumnValue + "'"; |
26 | | - } else if (columnValue == null) { |
27 | | - return "NULL"; |
28 | 47 | } |
29 | 48 | return columnValue.toString(); |
30 | 49 | } |
31 | 50 |
|
| 51 | + private String buildOracleToDateFunctionFor(Timestamp timeStamp) { |
| 52 | + //https://stackoverflow.com/questions/9180014/using-oracle-to-date-function-for-date-string-with-milliseconds |
| 53 | + // "An Oracle DATE does not store times with more precision than a second." |
| 54 | + Calendar calendar = Calendar.getInstance(); |
| 55 | + calendar.setTime(timeStamp); |
| 56 | + int monthNumber = calendar.get(Calendar.MONTH) + 1; |
| 57 | + int secondNumber = calendar.get(Calendar.SECOND); |
| 58 | + String toDateString = calendar.get(Calendar.YEAR) |
| 59 | + + "-" + (monthNumber < 10 ? "0" : "") + monthNumber |
| 60 | + + "-" + calendar.get(Calendar.DAY_OF_MONTH) |
| 61 | + + "-" + calendar.get(Calendar.HOUR_OF_DAY) |
| 62 | + + "-" + calendar.get(Calendar.MINUTE) |
| 63 | + + "-" + (secondNumber < 10 ? "0" : "") + secondNumber; |
| 64 | + return "TO_DATE('" + toDateString + "', 'yyyy-mm-dd-HH24-mi-ss')"; |
| 65 | + } |
| 66 | + |
| 67 | + private boolean isOracleSqlTimestamp(Object columnValue) { |
| 68 | + Class<?> columnValueClass = columnValue.getClass(); |
| 69 | + String classCanonicalName = columnValueClass.getCanonicalName(); |
| 70 | + return classCanonicalName.equals("oracle.sql.TIMESTAMP"); |
| 71 | + } |
| 72 | + |
| 73 | + private String buildOracleToTimeStampFunctionFor(Object columnValue) { |
| 74 | + String oracleTimeStampAsString = columnValue.toString(); |
| 75 | + String aDateWithMsLessThan100 = "2012-09-17 19:56:47.10"; |
| 76 | + boolean dateHasMsLessThan100 = oracleTimeStampAsString.length() == aDateWithMsLessThan100.length(); |
| 77 | + String dateForTimeStampCreation = dateHasMsLessThan100 ? oracleTimeStampAsString + "0" : oracleTimeStampAsString; |
| 78 | + return "TO_TIMESTAMP('" + dateForTimeStampCreation |
| 79 | + + "', 'YYYY-MM-DD HH24:MI:SS.FF')"; |
| 80 | + } |
| 81 | + |
| 82 | + private boolean isTimestampWithTimeZoneH2Type(Object columnValue) { |
| 83 | + Class<?> columnValueClass = columnValue.getClass(); |
| 84 | + String classCanonicalName = columnValueClass.getCanonicalName(); |
| 85 | + return classCanonicalName.equals("org.h2.api.TimestampWithTimeZone"); |
| 86 | + } |
| 87 | + |
32 | 88 | } |
0 commit comments