1 10 11 package com.triactive.jdo.store; 12 13 import com.triactive.jdo.PersistenceManager; 14 import java.sql.PreparedStatement ; 15 import java.sql.ResultSet ; 16 import java.sql.SQLException ; 17 import java.sql.Timestamp ; 18 import java.sql.Types ; 19 import java.util.Calendar ; 20 import java.util.GregorianCalendar ; 21 import java.util.TimeZone ; 22 import javax.jdo.JDODataStoreException; 23 24 25 public class SqlTimestampMapping extends ColumnMapping 26 { 27 31 private static final int TIMESTAMP_STRING_LENGTH = 29; 32 33 private static final TimeZone timeZoneUTC = TimeZone.getTimeZone("UTC"); 34 35 36 private static final String zeroes = "000000000"; 37 38 39 public SqlTimestampMapping(DatabaseAdapter dba, Class type) 40 { 41 super(dba, type); 42 43 initTypeInfo(); 44 } 45 46 public SqlTimestampMapping(Column col) 47 { 48 super(col); 49 50 col.checkPrimitive(); 51 52 initTypeInfo(); 53 } 54 55 public SqlTimestampMapping(ClassBaseTable table, int relativeFieldNumber) 56 { 57 this(table.newColumn(relativeFieldNumber)); 58 } 59 60 protected TypeInfo getTypeInfo() 61 { 62 return dba.getTypeInfo(new int[] { Types.TIMESTAMP, Types.CHAR }); 63 } 64 65 protected void initTypeInfo() 66 { 67 super.initTypeInfo(); 68 69 if (col != null && typeInfo.dataType == Types.CHAR) 70 { 71 col.setFixedLength(TIMESTAMP_STRING_LENGTH); 72 col.checkString(); 73 } 74 } 75 76 public void setObject(PersistenceManager pm, PreparedStatement ps, int param, Object value) 77 { 78 try 79 { 80 Calendar cal = new GregorianCalendar (timeZoneUTC); 81 82 if (value == null) 83 ps.setNull(param, typeInfo.dataType); 84 else if (typeInfo.dataType == Types.TIMESTAMP) 85 ps.setTimestamp(param, (Timestamp )value, cal); 86 else 87 ps.setString(param, timestampToString((Timestamp )value, cal)); 88 } 89 catch (SQLException e) 90 { 91 throw dba.newDataStoreException("Can't set Timestamp parameter: value = " + value, e); 92 } 93 } 94 95 protected Timestamp getTimestamp(ResultSet rs, int param) 96 { 97 Timestamp value; 98 99 try 100 { 101 Calendar cal = new GregorianCalendar (timeZoneUTC); 102 103 if (typeInfo.dataType == Types.TIMESTAMP) 104 value = rs.getTimestamp(param, cal); 105 else 106 { 107 String s = rs.getString(param); 108 109 value = s == null ? null : stringToTimestamp(s, cal); 110 } 111 } 112 catch (SQLException e) 113 { 114 throw dba.newDataStoreException("Can't get Timestamp result: param = " + param, e); 115 } 116 117 return value; 118 } 119 120 public Object getObject(PersistenceManager pm, ResultSet rs, int param) 121 { 122 Timestamp value = getTimestamp(rs, param); 123 124 if (value == null) 125 return null; 126 else 127 return value; 128 } 129 130 public SQLExpression newSQLLiteral(QueryStatement qs, Object value) 131 { 132 return new SqlTimestampLiteral(qs, this, (Timestamp )value); 133 } 134 135 public SQLExpression newSQLExpression(QueryStatement qs, QueryStatement.QueryColumn qsc, String fieldName) 136 { 137 return new SqlTimestampExpression(qs, qsc); 138 } 139 140 141 156 157 public static Timestamp stringToTimestamp(String s, Calendar cal) 158 { 159 String formatError = "Bad timestamp format: \"" + s + "\", must be yyyy-mm-dd hh:mm:ss.fffffffff"; 160 161 162 s = s.trim(); 163 int dividingSpace = s.indexOf(' '); 164 165 if (dividingSpace <= 0) 166 throw new java.lang.IllegalArgumentException (formatError); 167 168 String date_s = s.substring(0, dividingSpace); 169 String time_s = s.substring(dividingSpace + 1); 170 171 172 int firstDash = date_s.indexOf('-'); 173 int secondDash = date_s.indexOf('-', firstDash + 1); 174 int firstColon = time_s.indexOf(':'); 175 int secondColon = time_s.indexOf(':', firstColon + 1); 176 int period = time_s.indexOf('.', secondColon + 1); 177 178 179 if (firstDash <= 0 || secondDash <= 0 || secondDash >= date_s.length() - 1) 180 throw new java.lang.IllegalArgumentException (formatError); 181 182 int year = Integer.parseInt(date_s.substring(0, firstDash)); 183 int month = Integer.parseInt(date_s.substring(firstDash + 1, secondDash)); 184 int day = Integer.parseInt(date_s.substring(secondDash + 1)); 185 186 187 if (firstColon <= 0 || secondColon <= 0 || secondColon >= time_s.length() - 1) 188 throw new java.lang.IllegalArgumentException (formatError); 189 190 int hour = Integer.parseInt(time_s.substring(0, firstColon)); 191 int minute = Integer.parseInt(time_s.substring(firstColon + 1, secondColon)); 192 int second; 193 int nanos = 0; 194 195 if (period < 0) 196 second = Integer.parseInt(time_s.substring(secondColon + 1)); 197 else if (period == 0 || period >= time_s.length() - 1) 198 throw new java.lang.IllegalArgumentException (formatError); 199 else 200 { 201 second = Integer.parseInt(time_s.substring(secondColon + 1, period)); 202 String nanos_s = time_s.substring(period + 1); 203 204 if (nanos_s.length() > zeroes.length()) 205 throw new java.lang.IllegalArgumentException (formatError); 206 207 nanos_s += zeroes.substring(0, zeroes.length() - nanos_s.length()); 208 nanos = Integer.parseInt(nanos_s); 209 } 210 211 cal.set(Calendar.ERA, GregorianCalendar.AD); 212 cal.set(Calendar.YEAR, year); 213 cal.set(Calendar.MONTH, month - 1); cal.set(Calendar.DATE, day); 215 cal.set(Calendar.HOUR_OF_DAY, hour); 216 cal.set(Calendar.MINUTE, minute); 217 cal.set(Calendar.SECOND, second); 218 219 Timestamp ts = new Timestamp (cal.getTime().getTime()); 220 ts.setNanos(nanos); 221 222 return ts; 223 } 224 225 226 236 237 public static String timestampToString(Timestamp ts, Calendar cal) 238 { 239 cal.setTime(ts); 240 241 int year = cal.get(Calendar.YEAR); 242 int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DATE); 244 int hour = cal.get(Calendar.HOUR_OF_DAY); 245 int minute = cal.get(Calendar.MINUTE); 246 int second = cal.get(Calendar.SECOND); 247 248 String yearString = Integer.toString(year); 249 String monthString = month < 10 ? "0" + month : Integer.toString(month); 250 String dayString = day < 10 ? "0" + day : Integer.toString(day); 251 String hourString = hour < 10 ? "0" + hour : Integer.toString(hour); 252 String minuteString = minute < 10 ? "0" + minute : Integer.toString(minute); 253 String secondString = second < 10 ? "0" + second : Integer.toString(second); 254 String nanosString = Integer.toString(ts.getNanos()); 255 256 if (ts.getNanos() != 0) 257 { 258 259 nanosString = zeroes.substring(0, zeroes.length() - nanosString.length()) + nanosString; 260 261 262 int truncIndex = nanosString.length() - 1; 263 264 while (nanosString.charAt(truncIndex) == '0') 265 --truncIndex; 266 267 nanosString = nanosString.substring(0, truncIndex + 1); 268 } 269 270 return (yearString + "-" + monthString + "-" + dayString + " " + 271 hourString + ":" + minuteString + ":" + secondString + "." + nanosString); 272 } 273 } 274 | Popular Tags |