2 // System.Data.Common.DbConvert
\r
5 // Boris Kirzner (borisk@mainsoft.com)
\r
13 namespace System.Data.Common
\r
15 internal class DbConvert
\r
19 const long JAVA_MIN_MILLIS_UTC = -62135769600000L; // java.sql.Timestamp.valueOf("0001-01-01 00:00:00.000000000").getTime() at Greenwich time zone.
\r
20 static readonly long TIMEZONE_RAW_OFFSET;
\r
21 // .NET milliseconds value of DateTime(1582,1,1,0,0,0,0).Ticks/TimeSpan.TicksPerMillisecond
\r
22 const long CLR_MILLIS_1582 = 49891507200000L;
\r
23 const long MILLIS_PER_TWO_DAYS = 2 * TimeSpan.TicksPerDay / TimeSpan.TicksPerMillisecond; // 172800000L;
\r
24 internal static readonly java.util.TimeZone DEFAULT_TIME_ZONE;
\r
26 #endregion // Fields
\r
32 DEFAULT_TIME_ZONE = java.util.SimpleTimeZone.getDefault();
\r
33 TIMEZONE_RAW_OFFSET = (long)DEFAULT_TIME_ZONE.getRawOffset();
\r
36 // The diff between .Net and Java goes as the following:
\r
37 // * at 1582: java has 10 days less than .net
\r
38 // * below 1500 (exept 1200,800,400) : each 100'th year java adds 1 day over .net.
\r
39 // Current implementation compatible with .net in 1-99 and since 1582. In 100-1582 we're not compatible with .Ner nor with Java
\r
41 internal static long JavaMillisToClrMillis(long javaMillis)
\r
43 return JavaMillisToClrMillisUTC(javaMillis) + TIMEZONE_RAW_OFFSET;
\r
46 internal static long JavaMillisToClrMillisUTC(long javaMillis) {
\r
47 long clrMillis = javaMillis - JAVA_MIN_MILLIS_UTC;
\r
48 if (clrMillis > CLR_MILLIS_1582) {
\r
49 clrMillis -= MILLIS_PER_TWO_DAYS;
\r
54 internal static long ClrMillisToJavaMillis(long clrMillis)
\r
56 return ClrMillisToJavaMillisUTC(clrMillis) - TIMEZONE_RAW_OFFSET;
\r
59 internal static long ClrMillisToJavaMillisUTC(long clrMillis) {
\r
60 long javaMillis = clrMillis + JAVA_MIN_MILLIS_UTC;
\r
61 if (clrMillis > CLR_MILLIS_1582) {
\r
62 javaMillis += MILLIS_PER_TWO_DAYS;
\r
67 internal static java.sql.Time ClrTicksToJavaTime(long ticks) {
\r
68 return new Time((ticks / TimeSpan.TicksPerMillisecond)
\r
69 - DEFAULT_TIME_ZONE.getRawOffset());
\r
72 internal static java.sql.Date ClrTicksToJavaDate(long ticks) {
\r
73 java.sql.Date d = new java.sql.Date(0);
\r
74 ClrTicksToJavaDate(d, ticks);
\r
78 internal static java.sql.Timestamp ClrTicksToJavaTimestamp(long ticks)
\r
80 java.sql.Timestamp ts = new java.sql.Timestamp(0);
\r
81 ClrTicksToJavaDate(ts, ticks);
\r
83 // int nanos = (int)(ticks % TimeSpan.TicksPerMillisecond) * 100;
\r
84 // ts.setNanos(javaTimestamp.getNanos() + nanos);
\r
89 internal static void ClrTicksToJavaDate(java.util.Date d, long ticks) {
\r
90 long millis = ClrMillisToJavaMillis(ticks / TimeSpan.TicksPerMillisecond);
\r
93 if (DEFAULT_TIME_ZONE.inDaylightTime(d)) {
\r
94 millis -= DEFAULT_TIME_ZONE.getDSTSavings();
\r
99 internal static long JavaTimestampToClrTicks(java.sql.Timestamp ts)
\r
101 long ticks = JavaDateToClrTicks(ts);
\r
102 // Extra ticks, for dbs that can save them.
\r
103 // We do not use it, since .net does not saves ticks for fractial milliseconds
\r
104 // long ticksLessThanMilliseconds = (ts.getNanos()*100) % TimeSpan.TicksPerMillisecond;
\r
105 // ticks += ticksLessThanMilliseconds;
\r
110 internal static long JavaDateToClrTicks(java.util.Date d) {
\r
111 long millis = JavaMillisToClrMillis(d.getTime());
\r
112 if (DEFAULT_TIME_ZONE.inDaylightTime(d)) {
\r
113 millis += DEFAULT_TIME_ZONE.getDSTSavings();
\r
115 return millis * TimeSpan.TicksPerMillisecond;
\r
118 internal static long JavaTimeToClrTicks(java.sql.Time t) {
\r
119 return (t.getTime() + DEFAULT_TIME_ZONE.getRawOffset())
\r
120 * TimeSpan.TicksPerMillisecond;
\r
123 internal protected static Type JavaSqlTypeToClrType(int sqlTypeValue)
\r
125 DbTypes.JavaSqlTypes sqlType = (DbTypes.JavaSqlTypes)sqlTypeValue;
\r
128 case DbTypes.JavaSqlTypes.ARRAY : return typeof (java.sql.Array);
\r
129 case DbTypes.JavaSqlTypes.BIGINT : return DbTypes.TypeOfInt64;
\r
130 case DbTypes.JavaSqlTypes.BINARY : return DbTypes.TypeOfByteArray;
\r
131 case DbTypes.JavaSqlTypes.BIT : return DbTypes.TypeOfBoolean;
\r
132 case DbTypes.JavaSqlTypes.BLOB : return DbTypes.TypeOfByteArray;
\r
133 case DbTypes.JavaSqlTypes.BOOLEAN : return DbTypes.TypeOfBoolean;
\r
134 case DbTypes.JavaSqlTypes.CHAR : return DbTypes.TypeOfString;
\r
135 case DbTypes.JavaSqlTypes.CLOB : return DbTypes.TypeOfString;
\r
136 // case DbTypes.JavaSqlTypes.DATALINK :
\r
137 case DbTypes.JavaSqlTypes.DATE : return DbTypes.TypeOfDateTime;
\r
138 case DbTypes.JavaSqlTypes.DECIMAL : return DbTypes.TypeOfDecimal;
\r
139 // case DbTypes.JavaSqlTypes.DISTINCT :
\r
140 case DbTypes.JavaSqlTypes.DOUBLE : return DbTypes.TypeOfDouble;
\r
141 case DbTypes.JavaSqlTypes.FLOAT : return DbTypes.TypeOfDouble;
\r
142 case DbTypes.JavaSqlTypes.INTEGER : return DbTypes.TypeOfInt32;
\r
143 // case DbTypes.JavaSqlTypes.JAVA_OBJECT :
\r
144 case DbTypes.JavaSqlTypes.LONGVARBINARY : return DbTypes.TypeOfByteArray;
\r
145 case DbTypes.JavaSqlTypes.LONGVARCHAR : return DbTypes.TypeOfString;
\r
146 case DbTypes.JavaSqlTypes.NULL : return null;
\r
147 case DbTypes.JavaSqlTypes.NUMERIC : return DbTypes.TypeOfDecimal;
\r
148 // case DbTypes.JavaSqlTypes.OTHER :
\r
149 case DbTypes.JavaSqlTypes.REAL : return DbTypes.TypeOfSingle;
\r
150 case DbTypes.JavaSqlTypes.REF : return typeof (java.sql.Ref);
\r
151 case DbTypes.JavaSqlTypes.SMALLINT : return DbTypes.TypeOfInt16;
\r
152 case DbTypes.JavaSqlTypes.STRUCT : return typeof (java.sql.Struct);
\r
153 case DbTypes.JavaSqlTypes.TIME : return DbTypes.TypeOfTimespan;
\r
154 case DbTypes.JavaSqlTypes.TIMESTAMP : return DbTypes.TypeOfDateTime;
\r
155 case DbTypes.JavaSqlTypes.TINYINT : return DbTypes.TypeOfByte;
\r
156 case DbTypes.JavaSqlTypes.VARBINARY : return DbTypes.TypeOfByteArray;
\r
157 case DbTypes.JavaSqlTypes.VARCHAR : return DbTypes.TypeOfString;
\r
158 default : return DbTypes.TypeOfObject;
\r
164 internal protected static object JavaResultSetToClrWrapper(CallableStatement results,int columnIndex,DbTypes.JavaSqlTypes javaSqlType,int maxLength ,ResultSetMetaData resultsMetaData)
\r
166 object returnValue = null;
\r
167 sbyte[] sbyteArray;
\r
171 columnIndex++; //jdbc style
\r
172 switch (javaSqlType) {
\r
173 case DbTypes.JavaSqlTypes.ARRAY :
\r
174 returnValue = results.getArray(columnIndex);
\r
176 case DbTypes.JavaSqlTypes.BIGINT :
\r
177 returnValue = results.getLong(columnIndex);
\r
179 case DbTypes.JavaSqlTypes.BINARY :
\r
180 case DbTypes.JavaSqlTypes.VARBINARY :
\r
181 case DbTypes.JavaSqlTypes.LONGVARBINARY :
\r
182 // FIXME : comsider using maxLength
\r
183 sbyteArray = results.getBytes(columnIndex);
\r
184 if (sbyteArray != null) {
\r
185 returnValue = vmw.common.TypeUtils.ToByteArray(sbyteArray);
\r
188 case DbTypes.JavaSqlTypes.BIT :
\r
189 returnValue = results.getBoolean(columnIndex);
\r
191 case DbTypes.JavaSqlTypes.BLOB :
\r
192 // FIXME : comsider using maxLength
\r
193 java.sql.Blob blob = results.getBlob(columnIndex);
\r
194 if (blob != null) {
\r
195 InputStream input = blob.getBinaryStream();
\r
196 if (input == null) {
\r
197 returnValue = new byte[0];
\r
200 long length = blob.length();
\r
201 byte[] byteValue = new byte[length];
\r
202 sbyte[] sbyteValue = vmw.common.TypeUtils.ToSByteArray(byteValue);
\r
203 input.read(sbyteValue);
\r
204 returnValue = byteValue;
\r
208 case DbTypes.JavaSqlTypes.CHAR :
\r
209 if (resultsMetaData != null && "uniqueidentifier".Equals(resultsMetaData.getColumnTypeName(columnIndex))) {
\r
210 returnValue = new Guid(results.getString(columnIndex));
\r
213 // Oracle Jdbc driver returns extra trailing 0 chars for NCHAR columns, so we threat this at parameter.Size level
\r
214 s = results.getString(columnIndex);
\r
215 if ((s != null) && (maxLength < s.Length)) {
\r
216 s = s.Substring(0,maxLength);
\r
221 case DbTypes.JavaSqlTypes.CLOB :
\r
222 // FIXME : comsider using maxLength
\r
223 java.sql.Clob clob = results.getClob(columnIndex);
\r
224 if (clob != null) {
\r
225 java.io.Reader reader = clob.getCharacterStream();
\r
226 if (reader == null) {
\r
227 returnValue = String.Empty;
\r
230 long length = clob.length();
\r
231 char[] charValue = new char[length];
\r
232 reader.read(charValue);
\r
233 returnValue = new string(charValue);
\r
237 case DbTypes.JavaSqlTypes.TIME :
\r
238 Time t = results.getTime(columnIndex);
\r
240 returnValue = new TimeSpan(JavaTimeToClrTicks(t));
\r
243 case DbTypes.JavaSqlTypes.DATE :
\r
244 Date d = results.getDate(columnIndex);
\r
246 returnValue = new DateTime(JavaDateToClrTicks(d));
\r
249 case DbTypes.JavaSqlTypes.TIMESTAMP :
\r
250 Timestamp ts = results.getTimestamp(columnIndex);
\r
252 returnValue = new DateTime(JavaTimestampToClrTicks(ts));
\r
255 case DbTypes.JavaSqlTypes.DECIMAL :
\r
256 case DbTypes.JavaSqlTypes.NUMERIC :
\r
257 // java.sql.Types.NUMERIC (2), columnTypeName NUMBER, columnClassName java.math.BigDecimal
\r
258 // therefore we rely on scale
\r
259 if (resultsMetaData != null && resultsMetaData.getScale(columnIndex) == -127) {
\r
260 // Oracle db type FLOAT
\r
261 returnValue = results.getDouble(columnIndex);
\r
264 java.math.BigDecimal bigDecimal = results.getBigDecimal(columnIndex);
\r
265 if (bigDecimal != null) {
\r
266 returnValue = vmw.common.PrimitiveTypeUtils.BigDecimalToDecimal(bigDecimal);
\r
270 case DbTypes.JavaSqlTypes.DISTINCT :
\r
271 returnValue = results.getObject(columnIndex);
\r
273 case DbTypes.JavaSqlTypes.DOUBLE :
\r
274 returnValue = results.getDouble(columnIndex);
\r
276 case DbTypes.JavaSqlTypes.FLOAT :
\r
277 //float f = results.getFloat(columnIndex);
\r
278 returnValue = results.getDouble(columnIndex);
\r
280 case DbTypes.JavaSqlTypes.INTEGER :
\r
281 returnValue = results.getInt(columnIndex);
\r
283 case DbTypes.JavaSqlTypes.JAVA_OBJECT :
\r
284 returnValue = results.getObject(columnIndex);
\r
286 case DbTypes.JavaSqlTypes.LONGVARCHAR :
\r
287 returnValue = results.getString(columnIndex);
\r
289 case DbTypes.JavaSqlTypes.NULL :
\r
290 returnValue = DBNull.Value;
\r
292 case DbTypes.JavaSqlTypes.OTHER :
\r
293 returnValue = results.getObject(columnIndex);
\r
295 case DbTypes.JavaSqlTypes.REAL :
\r
296 returnValue = results.getFloat(columnIndex);
\r
298 case DbTypes.JavaSqlTypes.REF :
\r
299 returnValue = results.getRef(columnIndex);
\r
301 case DbTypes.JavaSqlTypes.SMALLINT :
\r
302 returnValue = results.getShort(columnIndex);
\r
304 case DbTypes.JavaSqlTypes.STRUCT :
\r
305 returnValue = results.getObject(columnIndex);
\r
307 case DbTypes.JavaSqlTypes.TINYINT :
\r
308 returnValue = Convert.ToByte(results.getByte(columnIndex));
\r
310 case DbTypes.JavaSqlTypes.VARCHAR :
\r
311 s = results.getString(columnIndex);
\r
312 if ((s != null) && (maxLength < s.Length)) {
\r
313 s = s.Substring(0,maxLength);
\r
318 returnValue = results.getObject(columnIndex);
\r
322 if (results.wasNull() || results == null) {
\r
323 return DBNull.Value;
\r
325 return returnValue;
\r
328 #endregion // Methods
\r