KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > store > SqlTimestampMapping


1 /*
2  * Copyright 2002 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: SqlTimestampMapping.java,v 1.6 2003/10/10 22:22:15 pierreg0 Exp $
9  */

10
11 package com.triactive.jdo.store;
12
13 import com.triactive.jdo.PersistenceManager;
14 import java.sql.PreparedStatement JavaDoc;
15 import java.sql.ResultSet JavaDoc;
16 import java.sql.SQLException JavaDoc;
17 import java.sql.Timestamp JavaDoc;
18 import java.sql.Types JavaDoc;
19 import java.util.Calendar JavaDoc;
20 import java.util.GregorianCalendar JavaDoc;
21 import java.util.TimeZone JavaDoc;
22 import javax.jdo.JDODataStoreException;
23
24
25 public class SqlTimestampMapping extends ColumnMapping
26 {
27     /**
28      * Maximum length of a timestamp string, based on JDBC timestamp escape
29      * format: "YYYY-MM-DD HH:MM:SS.FFFFFFFFF"
30      */

31     private static final int TIMESTAMP_STRING_LENGTH = 29;
32
33     private static final TimeZone JavaDoc timeZoneUTC = TimeZone.getTimeZone("UTC");
34
35     /** Used to zero-fill the fractional seconds to nine digits. */
36     private static final String JavaDoc zeroes = "000000000";
37
38
39     public SqlTimestampMapping(DatabaseAdapter dba, Class JavaDoc 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 JavaDoc ps, int param, Object JavaDoc value)
77     {
78         try
79         {
80             Calendar JavaDoc cal = new GregorianCalendar JavaDoc(timeZoneUTC);
81
82             if (value == null)
83                 ps.setNull(param, typeInfo.dataType);
84             else if (typeInfo.dataType == Types.TIMESTAMP)
85                 ps.setTimestamp(param, (Timestamp JavaDoc)value, cal);
86             else
87                 ps.setString(param, timestampToString((Timestamp JavaDoc)value, cal));
88         }
89         catch (SQLException JavaDoc e)
90         {
91             throw dba.newDataStoreException("Can't set Timestamp parameter: value = " + value, e);
92         }
93     }
94
95     protected Timestamp JavaDoc getTimestamp(ResultSet JavaDoc rs, int param)
96     {
97         Timestamp JavaDoc value;
98
99         try
100         {
101             Calendar JavaDoc cal = new GregorianCalendar JavaDoc(timeZoneUTC);
102
103             if (typeInfo.dataType == Types.TIMESTAMP)
104                 value = rs.getTimestamp(param, cal);
105             else
106             {
107                 String JavaDoc s = rs.getString(param);
108
109                 value = s == null ? null : stringToTimestamp(s, cal);
110             }
111         }
112         catch (SQLException JavaDoc e)
113         {
114             throw dba.newDataStoreException("Can't get Timestamp result: param = " + param, e);
115         }
116
117         return value;
118     }
119
120     public Object JavaDoc getObject(PersistenceManager pm, ResultSet JavaDoc rs, int param)
121     {
122         Timestamp JavaDoc 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 JavaDoc value)
131     {
132         return new SqlTimestampLiteral(qs, this, (Timestamp JavaDoc)value);
133     }
134
135     public SQLExpression newSQLExpression(QueryStatement qs, QueryStatement.QueryColumn qsc, String JavaDoc fieldName)
136     {
137         return new SqlTimestampExpression(qs, qsc);
138     }
139
140
141     /**
142      * Converts a string in JDBC timestamp escape format to a
143      * <tt>java.sql.Timestamp</tt> object using the "UTC" time zone.
144      *
145      * @param s Timestamp string in format
146      * <tt>yyyy-mm-dd hh:mm:ss.fffffffff</tt>.
147      *
148      * @return Corresponding <tt>java.sql.Timestamp</tt> value.
149      *
150      * @exception java.lang.IllegalArgumentException
151      * If the given argument does not have the format
152      * <tt>yyyy-mm-dd hh:mm:ss.fffffffff</tt>.
153      *
154      * @see java.sql.Timestamp
155      */

156
157     public static Timestamp JavaDoc stringToTimestamp(String JavaDoc s, Calendar JavaDoc cal)
158     {
159         String JavaDoc formatError = "Bad timestamp format: \"" + s + "\", must be yyyy-mm-dd hh:mm:ss.fffffffff";
160
161         /* Split the string into date and time components. */
162         s = s.trim();
163         int dividingSpace = s.indexOf(' ');
164
165         if (dividingSpace <= 0)
166             throw new java.lang.IllegalArgumentException JavaDoc(formatError);
167
168         String JavaDoc date_s = s.substring(0, dividingSpace);
169         String JavaDoc time_s = s.substring(dividingSpace + 1);
170
171         /* Parse the date. */
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         /* Convert the date. */
179         if (firstDash <= 0 || secondDash <= 0 || secondDash >= date_s.length() - 1)
180             throw new java.lang.IllegalArgumentException JavaDoc(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         /* Convert the time; default missing nanos. */
187         if (firstColon <= 0 || secondColon <= 0 || secondColon >= time_s.length() - 1)
188             throw new java.lang.IllegalArgumentException JavaDoc(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 JavaDoc(formatError);
199         else
200         {
201             second = Integer.parseInt(time_s.substring(secondColon + 1, period));
202             String JavaDoc nanos_s = time_s.substring(period + 1);
203
204             if (nanos_s.length() > zeroes.length())
205                 throw new java.lang.IllegalArgumentException JavaDoc(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); // Months are zero based in Calendar
214
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 JavaDoc ts = new Timestamp JavaDoc(cal.getTime().getTime());
220         ts.setNanos(nanos);
221
222         return ts;
223     }
224
225
226     /**
227      * Formats a timestamp in JDBC timestamp escape format using the "UTC" time
228      * zone.
229      *
230      * @param ts The timestamp to be formatted.
231      *
232      * @return A String in <tt>yyyy-mm-dd hh:mm:ss.fffffffff</tt> format.
233      *
234      * @see java.sql.Timestamp
235      */

236
237     public static String JavaDoc timestampToString(Timestamp JavaDoc ts, Calendar JavaDoc cal)
238     {
239         cal.setTime(ts);
240
241         int year = cal.get(Calendar.YEAR);
242         int month = cal.get(Calendar.MONTH) + 1; // Months are zero based in Calendar
243
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 JavaDoc yearString = Integer.toString(year);
249         String JavaDoc monthString = month < 10 ? "0" + month : Integer.toString(month);
250         String JavaDoc dayString = day < 10 ? "0" + day : Integer.toString(day);
251         String JavaDoc hourString = hour < 10 ? "0" + hour : Integer.toString(hour);
252         String JavaDoc minuteString = minute < 10 ? "0" + minute : Integer.toString(minute);
253         String JavaDoc secondString = second < 10 ? "0" + second : Integer.toString(second);
254         String JavaDoc nanosString = Integer.toString(ts.getNanos());
255
256         if (ts.getNanos() != 0)
257         {
258             /* Add leading zeroes. */
259             nanosString = zeroes.substring(0, zeroes.length() - nanosString.length()) + nanosString;
260
261             /* Truncate trailing zeroes. */
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