2 // System.Data.Odbc.OdbcTypeConverter
5 // Sureshkumar T <tsureshkumar@novell.com>
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 // * Type mapping between various odbc driver types.
33 // For further infomartion between these mapping visit following msdn site
35 // * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/
36 // odbcc_data_types.asp
37 // * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/
38 // odbcconverting_data_from_c_to_sql_data_types.asp
39 // * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/
40 // odbcconverting_data_from_sql_to_c_data_types.asp
41 // * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/
42 // odbcparameter_data_types.asp
43 // * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/
44 // html/frlrfsystemdataodbcodbctypeclasstopic.asp
47 // OdbcType SQL_C_TYPE SQL_TYPE
48 // ===================================================================
49 // BigInt SQL_C_TYPE.SBIGINT SQL_TYPE.BIGINT
50 // Binary SQL_C_TYPE.BINARY SQL_TYPE.BINARY
51 // Bit SQL_C_TYPE.BIT SQL_TYPE.BIT
52 // Char SQL_C_TYPE.CHAR SQL_TYPE.CHAR
53 // Date SQL_C_TYPE.TYPE_DATE SQL_TYPE.TYPE_DATE
54 // DateTime SQL_C_TYPE.TIMESTAMP SQL_TYPE.TIMESTAMP
55 // Decimal SQL_C_TYPE.NUMERIC SQL_TYPE.NUMERIC
56 // Double SQL_C_TYPE.DOUBLE SQL_TYPE.DOUBLE
57 // Image SQL_C_TYPE.BINARY SQL_TYPE.BINARY
58 // Int SQL_C_TYPE.LONG SQL_TYPE.INTEGER
59 // NChar SQL_C_TYPE.WCHAR SQL_TYPE.WCHAR
60 // NText SQL_C_TYPE.WCHAR SQL_TYPE.WLONGVARCHAR
61 // Numeric SQL_C_TYPE.NUMERIC SQL_TYPE.NUMERIC
62 // NVarChar SQL_C_TYPE.WCHAR SQL_TYPE.WVARCHAR
63 // Real SQL_C_TYPE.FLOAT SQL_TYPE.REAL
64 // SignedBigInt SQL_C_TYPE.SBIGINT SQL_TYPE.BIGINT
65 // SmallDateTime SQL_C_TYPE.TIMESTAMP SQL_TYPE.TIMESTAMP
66 // SmallInt SQL_C_TYPE.SHORT SQL_TYPE.SMALLINT
67 // Text SQL_C_TYPE.WCHAR SQL_TYPE.LONGVARCHAR
68 // Time SQL_C_TYPE.TYPE_TIME SQL_TYPE.TYPE_TIME
69 // Timestamp SQL_C_TYPE.BINARY SQL_TYPE.BINARY
70 // TinyInt SQL_C_TYPE.UTINYINT SQL_TYPE.TINYINT
71 // UniqueIdentifier SQL_C_TYPE.GUID SQL_TYPE.GUID
72 // VarBinary SQL_C_TYPE.BINARY SQL_TYPE.VARBINARY
73 // VarChar SQL_C_TYPE.WCHAR SQL_TYPE.WVARCHAR
74 //====================================================================
78 using System.Collections;
79 using System.Data.Common;
81 namespace System.Data.Odbc
83 internal sealed class OdbcTypeConverter
85 internal struct TypeMap
87 public const short DefaultForOdbcType = 1;
88 public const short DefaultForSQLCType = 1<<1;
89 public const short DefaultForSQLType = 1<<2;
90 public const short DefaultAll = (DefaultForOdbcType |
93 public OdbcType OdbcType;
94 public SQL_C_TYPE SqlCType;
95 public SQL_TYPE SqlType;
98 public TypeMap (OdbcType odbcType, SQL_C_TYPE sqlCType, SQL_TYPE sqlType)
103 BitMask = DefaultForOdbcType
109 public TypeMap (OdbcType odbcType, SQL_C_TYPE sqlCType, SQL_TYPE sqlType, short defaultFlags)
110 : this (odbcType, sqlCType, sqlType)
112 BitMask = defaultFlags;
118 // FIXME: Write a binary search to make faster
119 internal class MapCollection : CollectionBase
121 public TypeMap this [OdbcType odbcType]
124 foreach (TypeMap map in List){
125 if (map.OdbcType == odbcType
126 && (map.BitMask & TypeMap.DefaultForOdbcType) > 0 )
129 throw new ArgumentException (String.Format ("Type mapping for odbc type {0} is not found",
135 int i = IndexOf (odbcType);
142 public TypeMap this [SQL_C_TYPE sqlCType]
145 foreach (TypeMap map in List){
146 if (map.SqlCType == sqlCType
147 && (map.BitMask & TypeMap.DefaultForSQLCType) > 0 )
150 throw new ArgumentException (String.Format ("Type mapping for odbc type {0} is not found",
156 int i = IndexOf (sqlCType);
165 public TypeMap this [SQL_TYPE sqlType]
168 foreach (TypeMap map in List){
169 if (map.SqlType == sqlType
170 && (map.BitMask & TypeMap.DefaultForSQLType) > 0 )
173 throw new ArgumentException (String.Format ("Type mapping for odbc type {0} is not found",
179 int i = IndexOf (sqlType);
187 public TypeMap this [int index]
189 get { return (TypeMap) List [index];}
190 set { List [index] = value;}
195 public int IndexOf (OdbcType odbcType)
197 for (int i=0; i < List.Count; i++) {
198 TypeMap map = (TypeMap) List [i];
199 if (map.OdbcType == odbcType
200 && (map.BitMask & TypeMap.DefaultForOdbcType) > 0 )
206 public int IndexOf (SQL_C_TYPE sqlCType)
208 for (int i=0; i < List.Count; i++) {
209 TypeMap map = (TypeMap) List [i];
210 if (map.SqlCType == sqlCType
211 && (map.BitMask & TypeMap.DefaultForSQLCType) > 0 )
217 public int IndexOf (SQL_TYPE sqlType)
219 for (int i=0; i < List.Count; i++) {
220 TypeMap map = (TypeMap) List [i];
221 if (map.SqlType == sqlType
222 && (map.BitMask & TypeMap.DefaultForSQLType) > 0 )
228 public int Add (TypeMap map)
230 return List.Add (map);
233 protected override void OnValidate (object value)
235 if (value.GetType () != typeof (TypeMap))
236 throw new ArgumentException ("value is not of type TypeMap");
242 private static MapCollection OdbcTypeMap;
244 static OdbcTypeConverter ()
246 OdbcTypeMap = new MapCollection ();
247 OdbcTypeMap.Add (new TypeMap (OdbcType.BigInt, SQL_C_TYPE.SBIGINT, SQL_TYPE.BIGINT ));
248 OdbcTypeMap.Add (new TypeMap (OdbcType.Binary, SQL_C_TYPE.BINARY, SQL_TYPE.BINARY ));
249 OdbcTypeMap.Add (new TypeMap (OdbcType.Bit, SQL_C_TYPE.BIT, SQL_TYPE.BIT ));
250 OdbcTypeMap.Add (new TypeMap (OdbcType.Char, SQL_C_TYPE.CHAR, SQL_TYPE.CHAR ));
251 OdbcTypeMap.Add (new TypeMap (OdbcType.Date, SQL_C_TYPE.TYPE_DATE, SQL_TYPE.TYPE_DATE ));
252 OdbcTypeMap.Add (new TypeMap (OdbcType.DateTime, SQL_C_TYPE.TIMESTAMP, SQL_TYPE.TIMESTAMP ));
253 OdbcTypeMap.Add (new TypeMap (OdbcType.Decimal, SQL_C_TYPE.NUMERIC, SQL_TYPE.NUMERIC , TypeMap.DefaultAll & (~TypeMap.DefaultForSQLType)));
254 OdbcTypeMap.Add (new TypeMap (OdbcType.Double, SQL_C_TYPE.DOUBLE, SQL_TYPE.DOUBLE ));
255 OdbcTypeMap.Add (new TypeMap (OdbcType.Image, SQL_C_TYPE.BINARY, SQL_TYPE.BINARY , TypeMap.DefaultAll & (~TypeMap.DefaultForSQLType)));
256 OdbcTypeMap.Add (new TypeMap (OdbcType.Int, SQL_C_TYPE.LONG, SQL_TYPE.INTEGER ));
257 OdbcTypeMap.Add (new TypeMap (OdbcType.NChar, SQL_C_TYPE.WCHAR, SQL_TYPE.WCHAR ));
258 OdbcTypeMap.Add (new TypeMap (OdbcType.NText, SQL_C_TYPE.WCHAR, SQL_TYPE.WLONGVARCHAR));
259 OdbcTypeMap.Add (new TypeMap (OdbcType.Numeric, SQL_C_TYPE.NUMERIC, SQL_TYPE.NUMERIC ));
260 OdbcTypeMap.Add (new TypeMap (OdbcType.NVarChar, SQL_C_TYPE.WCHAR, SQL_TYPE.WVARCHAR ));
261 OdbcTypeMap.Add (new TypeMap (OdbcType.Real, SQL_C_TYPE.FLOAT, SQL_TYPE.REAL ));
262 OdbcTypeMap.Add (new TypeMap (OdbcType.SmallDateTime, SQL_C_TYPE.TIMESTAMP, SQL_TYPE.TIMESTAMP , TypeMap.DefaultAll & (~TypeMap.DefaultForSQLType)));
263 OdbcTypeMap.Add (new TypeMap (OdbcType.SmallInt, SQL_C_TYPE.SHORT, SQL_TYPE.SMALLINT ));
264 OdbcTypeMap.Add (new TypeMap (OdbcType.Text, SQL_C_TYPE.WCHAR, SQL_TYPE.LONGVARCHAR));
265 OdbcTypeMap.Add (new TypeMap (OdbcType.Time, SQL_C_TYPE.TYPE_TIME, SQL_TYPE.TYPE_TIME ));
266 OdbcTypeMap.Add (new TypeMap (OdbcType.Timestamp, SQL_C_TYPE.BINARY, SQL_TYPE.BINARY , TypeMap.DefaultAll & (~TypeMap.DefaultForSQLType)));
267 OdbcTypeMap.Add (new TypeMap (OdbcType.TinyInt, SQL_C_TYPE.UTINYINT, SQL_TYPE.TINYINT ));
268 OdbcTypeMap.Add (new TypeMap (OdbcType.UniqueIdentifier,SQL_C_TYPE.GUID, SQL_TYPE.GUID ));
269 OdbcTypeMap.Add (new TypeMap (OdbcType.VarBinary, SQL_C_TYPE.BINARY, SQL_TYPE.VARBINARY ));
270 OdbcTypeMap.Add (new TypeMap (OdbcType.VarChar, SQL_C_TYPE.WCHAR, SQL_TYPE.WVARCHAR , TypeMap.DefaultAll & (~TypeMap.DefaultForSQLType)));
273 public static SQL_C_TYPE ConvertToSqlCType (OdbcType type)
275 return OdbcTypeMap [type].SqlCType;
278 public static SQL_TYPE ConvertToSqlType (OdbcType type)
280 return OdbcTypeMap [type].SqlType;
284 public static OdbcType ConvertToOdbcType (SQL_TYPE sqlType)
286 // Unmapped SQL Types
288 //#define SQL_FLOAT 6
289 // could map to SQL_DOUBLE?
290 //#define SQL_INTERVAL 10
291 // could map to SmallDateTime?
292 return GetTypeMap (sqlType).OdbcType;
295 public static TypeMap GetTypeMap (SQL_TYPE sqlType)
299 map = OdbcTypeMap [sqlType];
301 } catch (ArgumentException) {
305 // If not in default translation
306 map = new TypeMap ();
307 map.SqlType = sqlType;
310 map.OdbcType = OdbcType.DateTime;
311 map.SqlCType = SQL_C_TYPE.TYPE_DATE;
314 case SQL_TYPE.DECIMAL:
315 map.OdbcType = OdbcType.Decimal;
316 map.SqlCType = SQL_C_TYPE.CHAR;
319 case SQL_TYPE.INTERVAL_DAY:
320 map.OdbcType = OdbcType.DateTime;
321 map.SqlCType = SQL_C_TYPE.INTERVAL_DAY;
324 case SQL_TYPE.INTERVAL_DAY_TO_HOUR:
325 map.OdbcType = OdbcType.DateTime;
326 map.SqlCType = SQL_C_TYPE.INTERVAL_DAY_TO_HOUR;
329 case SQL_TYPE.INTERVAL_DAY_TO_MINUTE:
330 map.OdbcType = OdbcType.DateTime;
331 map.SqlCType = SQL_C_TYPE.INTERVAL_DAY_TO_MINUTE;
334 case SQL_TYPE.INTERVAL_DAY_TO_SECOND:
335 map.OdbcType = OdbcType.DateTime;
336 map.SqlCType = SQL_C_TYPE.INTERVAL_DAY_TO_SECOND;
339 case SQL_TYPE.INTERVAL_HOUR:
340 map.OdbcType = OdbcType.DateTime;
341 map.SqlCType = SQL_C_TYPE.INTERVAL_HOUR;
344 case SQL_TYPE.INTERVAL_HOUR_TO_MINUTE:
345 map.OdbcType = OdbcType.DateTime;
346 map.SqlCType = SQL_C_TYPE.INTERVAL_HOUR_TO_MINUTE;
349 case SQL_TYPE.INTERVAL_HOUR_TO_SECOND:
350 map.OdbcType = OdbcType.DateTime;
351 map.SqlCType = SQL_C_TYPE.INTERVAL_HOUR_TO_SECOND;
354 case SQL_TYPE.INTERVAL_MINUTE:
355 map.OdbcType = OdbcType.DateTime;
356 map.SqlCType = SQL_C_TYPE.INTERVAL_MINUTE;
359 case SQL_TYPE.INTERVAL_MINUTE_TO_SECOND:
360 map.OdbcType = OdbcType.DateTime;
361 map.SqlCType = SQL_C_TYPE.INTERVAL_MINUTE_TO_SECOND;
364 case SQL_TYPE.INTERVAL_MONTH:
365 map.OdbcType = OdbcType.DateTime;
366 map.SqlCType = SQL_C_TYPE.INTERVAL_MONTH;
369 case SQL_TYPE.INTERVAL_SECOND:
370 map.OdbcType = OdbcType.DateTime;
371 map.SqlCType = SQL_C_TYPE.INTERVAL_SECOND;
374 case SQL_TYPE.INTERVAL_YEAR:
375 map.OdbcType = OdbcType.DateTime;
376 map.SqlCType = SQL_C_TYPE.INTERVAL_YEAR;
379 case SQL_TYPE.INTERVAL_YEAR_TO_MONTH:
380 map.OdbcType = OdbcType.DateTime;
381 map.SqlCType = SQL_C_TYPE.INTERVAL_YEAR_TO_MONTH;
384 case SQL_TYPE.LONGVARBINARY:
385 map.OdbcType = OdbcType.Binary;
386 map.SqlCType = SQL_C_TYPE.BINARY;
390 map.OdbcType = OdbcType.DateTime;
391 map.SqlCType = SQL_C_TYPE.TIME;
394 case SQL_TYPE.TYPE_TIMESTAMP:
395 map.OdbcType = OdbcType.DateTime;
396 map.SqlCType = SQL_C_TYPE.TIMESTAMP;
399 case SQL_TYPE.VARCHAR:
400 map.OdbcType = OdbcType.VarChar;
401 map.SqlCType = SQL_C_TYPE.CHAR;
405 map.OdbcType = OdbcType.NVarChar;
406 map.SqlCType = SQL_C_TYPE.WCHAR;