*** empty log message ***
[mono.git] / mcs / class / IBM.Data.DB2 / IBM.Data.DB2 / DB2Parameter.cs
1 using System;\r
2 using System.Data;\r
3 using System.Runtime.InteropServices;\r
4 \r
5 namespace IBM.Data.DB2\r
6 {\r
7 \r
8         public sealed class DB2Parameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable\r
9         {\r
10                 private DbType dbType = DbType.Object;\r
11                 private DB2Type db2Type = DB2Type.Invalid;\r
12                 private short db2DataType = DB2Constants.SQL_UNKNOWN_TYPE;\r
13                 private short db2LastUsedDataType = DB2Constants.SQL_UNKNOWN_TYPE;\r
14 \r
15                 private ParameterDirection direction;\r
16                 private short db2Direction = DB2Constants.SQL_PARAM_INPUT;\r
17                 private bool nullable = true;\r
18                 private string parameterName;\r
19                 private string sourceColumn;\r
20                 private DataRowVersion sourceVersion;\r
21                 private object dataVal;\r
22                 private byte scale, precision;\r
23                 private int size;\r
24                 internal IntPtr internalBuffer;\r
25                 internal IntPtr internalLengthBuffer;\r
26                 internal int requiredMemory;\r
27 \r
28                 #region Contructors and destructors\r
29                 public DB2Parameter()\r
30                 {\r
31                         direction = ParameterDirection.Input;\r
32                         sourceVersion = DataRowVersion.Current;\r
33                 } \r
34 \r
35                 public DB2Parameter(string name, DB2Type type)\r
36                 {\r
37                         direction = ParameterDirection.Input;\r
38                         sourceVersion = DataRowVersion.Current;\r
39                         this.ParameterName = name;\r
40                         this.DB2Type = type;\r
41                 } \r
42 \r
43                 public DB2Parameter(string name, DB2Type type, int size)\r
44                 {\r
45                         direction = ParameterDirection.Input;\r
46                         sourceVersion = DataRowVersion.Current;\r
47                         this.ParameterName = name;\r
48                         this.DB2Type = type;\r
49                         this.Size = size;\r
50                 }\r
51 \r
52                 public DB2Parameter(string name, DB2Type type, int size, string sourceColumn)\r
53                 {\r
54                         direction = ParameterDirection.Input;\r
55                         sourceVersion = DataRowVersion.Current;\r
56                         this.ParameterName = name;\r
57                         this.DB2Type = type;\r
58                         this.Size = size;\r
59                         this.SourceColumn = sourceColumn;\r
60                 }\r
61 \r
62                 public DB2Parameter(string parameterName, object value)\r
63                 {\r
64                         direction = ParameterDirection.Input;\r
65                         sourceVersion = DataRowVersion.Current;\r
66                         this.ParameterName = parameterName;\r
67                         this.Value = value;\r
68                 }\r
69 \r
70                 public DB2Parameter(string parameterName, DB2Type db2Type, int size, ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string srcColumn, DataRowVersion srcVersion, object value)\r
71                 {\r
72                         this.ParameterName = parameterName;\r
73                         this.DB2Type = db2Type;\r
74                         this.Size = size;\r
75                         this.Direction = parameterDirection;\r
76                         this.IsNullable = isNullable;\r
77                         this.Precision = precision;\r
78                         this.Scale = scale;\r
79                         this.SourceColumn = srcColumn;\r
80                         this.SourceVersion = srcVersion;\r
81                         this.Value = value;\r
82                 }\r
83 \r
84                 #endregion\r
85                 #region Properties\r
86                 #region DbType Property\r
87                 public DB2Type DB2Type\r
88                 {\r
89                         get \r
90                         {\r
91                                 return db2Type;\r
92                         }\r
93                         set \r
94                         {\r
95                                 db2Type = value;\r
96                                 switch(db2Type)\r
97                                 {\r
98                                         case DB2Type.Invalid:        dbType = DbType.Object;            db2DataType = DB2Constants.SQL_UNKNOWN_TYPE;   break;\r
99                                         case DB2Type.SmallInt:       dbType = DbType.Int16;             db2DataType = DB2Constants.SQL_SMALLINT;       break;\r
100                                         case DB2Type.Integer:        dbType = DbType.Int32;             db2DataType = DB2Constants.SQL_INTEGER;        break;\r
101                                         case DB2Type.BigInt:         dbType = DbType.Int64;             db2DataType = DB2Constants.SQL_BIGINT;         break;\r
102                                         case DB2Type.Real:           dbType = DbType.Single;            db2DataType = DB2Constants.SQL_REAL;           break;\r
103                                         case DB2Type.Double:         dbType = DbType.Double;            db2DataType = DB2Constants.SQL_DOUBLE;         break;\r
104                                         case DB2Type.Float:          dbType = DbType.Single;            db2DataType = DB2Constants.SQL_REAL;           break;\r
105                                         case DB2Type.Decimal:        dbType = DbType.Decimal;           db2DataType = DB2Constants.SQL_DECIMAL;        break;\r
106                                         case DB2Type.Numeric:        dbType = DbType.VarNumeric;        db2DataType = DB2Constants.SQL_WCHAR;          break;\r
107                                         case DB2Type.Date:           dbType = DbType.Date;              db2DataType = DB2Constants.SQL_TYPE_DATE;      break;\r
108                                         case DB2Type.Time:           dbType = DbType.Time;              db2DataType = DB2Constants.SQL_TYPE_TIME;      break;\r
109                                         case DB2Type.Timestamp:      dbType = DbType.DateTime;          db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP; break;\r
110                                         case DB2Type.Char:           dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
111                                         case DB2Type.VarChar:        dbType = DbType.StringFixedLength; db2DataType = DB2Constants.SQL_WCHAR;          break;\r
112                                         case DB2Type.LongVarChar:    dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
113                                         case DB2Type.Binary:         dbType = DbType.Binary;            db2DataType = DB2Constants.SQL_VARBINARY;      break;\r
114                                         case DB2Type.VarBinary:      dbType = DbType.Binary;            db2DataType = DB2Constants.SQL_VARBINARY;      break;\r
115                                         case DB2Type.LongVarBinary:  dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
116                                         case DB2Type.Graphic:        dbType = DbType.StringFixedLength; db2DataType = DB2Constants.SQL_WCHAR;          break;\r
117                                         case DB2Type.VarGraphic:     dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
118                                         case DB2Type.LongVarGraphic: dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
119                                         case DB2Type.Clob:           dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
120                                         case DB2Type.Blob:           dbType = DbType.Binary;            db2DataType = DB2Constants.SQL_VARBINARY;      break;\r
121                                         case DB2Type.DbClob:         dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
122                                         case DB2Type.Datalink:       dbType = DbType.Byte;              db2DataType = DB2Constants.SQL_VARBINARY;      break;\r
123                                         case DB2Type.RowId:          dbType = DbType.Decimal;           db2DataType = DB2Constants.SQL_DECIMAL;        break;\r
124                                         case DB2Type.XmlReader:      dbType = DbType.String;            db2DataType = DB2Constants.SQL_WCHAR;          break;\r
125                                         default:\r
126                                                 throw new NotSupportedException("Value is of unknown data type");\r
127                                 }\r
128                         }\r
129                 }\r
130                 ///\r
131                 /// Parameter data type\r
132                 /// \r
133                 public DbType DbType\r
134                 {\r
135                         get \r
136                         {\r
137                                 return dbType;\r
138                         }\r
139                         set \r
140                         {\r
141                                 dbType = value;\r
142                                 switch(dbType)\r
143                                 {\r
144                                         case DbType.AnsiString:             db2Type = DB2Type.VarChar;    db2DataType = DB2Constants.SQL_WCHAR;          break;\r
145                                         case DbType.AnsiStringFixedLength:  db2Type = DB2Type.Char;       db2DataType = DB2Constants.SQL_WCHAR;          break;\r
146                                         case DbType.Binary:                 db2Type = DB2Type.Binary;     db2DataType = DB2Constants.SQL_VARBINARY;      break;\r
147                                         case DbType.Boolean:                db2Type = DB2Type.SmallInt;   db2DataType = DB2Constants.SQL_BIT;            break;\r
148                                         case DbType.Byte:                   db2Type = DB2Type.SmallInt;   db2DataType = DB2Constants.SQL_UTINYINT;       break;\r
149                                         case DbType.Currency:               db2Type = DB2Type.Decimal;    db2DataType = DB2Constants.SQL_DECIMAL;        break;\r
150                                         case DbType.Date:                   db2Type = DB2Type.Date;       db2DataType = DB2Constants.SQL_TYPE_DATE;      break;\r
151                                         case DbType.DateTime:               db2Type = DB2Type.Timestamp;  db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP; break;\r
152                                         case DbType.Decimal:                db2Type = DB2Type.Decimal;    db2DataType = DB2Constants.SQL_DECIMAL;        break;\r
153                                         case DbType.Double:                 db2Type = DB2Type.Double;     db2DataType = DB2Constants.SQL_DOUBLE;         break;\r
154                                         case DbType.Guid:                   db2Type = DB2Type.Binary;     db2DataType = DB2Constants.SQL_WCHAR;          break;\r
155                                         case DbType.Int16:                  db2Type = DB2Type.SmallInt;   db2DataType = DB2Constants.SQL_SMALLINT;       break;\r
156                                         case DbType.Int32:                  db2Type = DB2Type.Integer;    db2DataType = DB2Constants.SQL_INTEGER;        break;\r
157                                         case DbType.Int64:                  db2Type = DB2Type.BigInt;     db2DataType = DB2Constants.SQL_BIGINT;         break;\r
158                                         case DbType.Object:                 db2Type = DB2Type.Invalid;    db2DataType = DB2Constants.SQL_UNKNOWN_TYPE;   break;\r
159                                         case DbType.SByte:                  db2Type = DB2Type.SmallInt;   db2DataType = DB2Constants.SQL_UTINYINT;       break;\r
160                                         case DbType.Single:                 db2Type = DB2Type.Float;      db2DataType = DB2Constants.SQL_REAL;           break;\r
161                                         case DbType.String:                 db2Type = DB2Type.VarChar;    db2DataType = DB2Constants.SQL_WCHAR;          break;\r
162                                         case DbType.StringFixedLength:      db2Type = DB2Type.Char;       db2DataType = DB2Constants.SQL_WCHAR;          break;\r
163                                         case DbType.Time:                   db2Type = DB2Type.Time;       db2DataType = DB2Constants.SQL_TYPE_TIME;      break;\r
164                                         case DbType.UInt16:                 db2Type = DB2Type.SmallInt;   db2DataType = DB2Constants.SQL_SMALLINT;       break;\r
165                                         case DbType.UInt32:                 db2Type = DB2Type.Integer;    db2DataType = DB2Constants.SQL_INTEGER;        break;\r
166                                         case DbType.UInt64:                 db2Type = DB2Type.BigInt;     db2DataType = DB2Constants.SQL_BIGINT;         break;\r
167                                         case DbType.VarNumeric:             db2Type = DB2Type.Numeric;    db2DataType = DB2Constants.SQL_WCHAR;          break;\r
168                                         default:\r
169                                                 throw new NotSupportedException("Value is of unknown data type");\r
170                                 }\r
171                         }\r
172                 }\r
173 \r
174                 #endregion\r
175                 #region Direction\r
176                 ///\r
177                 /// In or out parameter, or both\r
178                 /// \r
179                 public ParameterDirection Direction\r
180                 {\r
181                         get \r
182                         {\r
183                                 return direction;\r
184                         }\r
185                         set \r
186                         {\r
187                                 direction = value;\r
188                                 switch(direction)\r
189                                 {\r
190                                         default:\r
191                                         case ParameterDirection.Input:                  db2Direction = DB2Constants.SQL_PARAM_INPUT;            break;\r
192                                         case ParameterDirection.Output:                 db2Direction = DB2Constants.SQL_PARAM_OUTPUT;           break;\r
193                                         case ParameterDirection.InputOutput:    db2Direction = DB2Constants.SQL_PARAM_INPUT_OUTPUT;     break;\r
194                                         case ParameterDirection.ReturnValue:    db2Direction = DB2Constants.SQL_RETURN_VALUE;           break;\r
195                                 }\r
196                         }\r
197                 }\r
198                 #endregion\r
199                 #region IsNullable\r
200                 ///\r
201                 /// Does this parameter support a null value\r
202                 /// \r
203                 public bool IsNullable \r
204                 {\r
205                         get \r
206                         {\r
207                                 return nullable;\r
208                         }\r
209                         set \r
210                         {\r
211                                 nullable = value;\r
212                         }\r
213                 }\r
214                 #endregion\r
215                 #region ParameterName\r
216                 public string ParameterName\r
217                 {\r
218                         get \r
219                         {\r
220                                 return parameterName;\r
221                         }\r
222                         set \r
223                         {\r
224                                 parameterName = value;\r
225                         }\r
226                 }\r
227                 #endregion\r
228                 #region SourceColumn\r
229                 ///\r
230                 /// Gets or sets the name of the source column that is mapped to the DataSet\r
231                 /// \r
232                 public string SourceColumn\r
233                 {\r
234                         get \r
235                         {\r
236                                 return sourceColumn;\r
237                         }\r
238                         set \r
239                         {\r
240                                 sourceColumn = value;\r
241                         }\r
242                 }\r
243                 #endregion\r
244                 #region SourceVersion\r
245                 ///\r
246                 /// DataRowVersion property\r
247                 /// \r
248                 public DataRowVersion SourceVersion \r
249                 {\r
250                         get \r
251                         {\r
252                                 return sourceVersion;\r
253                         }\r
254                         set \r
255                         {\r
256                                 sourceVersion = value;\r
257                         }\r
258                 }\r
259                 #endregion\r
260                 #region IDbDataParameter properties\r
261                 public byte Precision \r
262                 {\r
263                         get \r
264                         { \r
265                                 return precision;\r
266                         }\r
267                         set \r
268                         { \r
269                                 precision = value; \r
270                         }\r
271                 }\r
272                 \r
273                 public byte Scale \r
274                 {\r
275                         get \r
276                         { \r
277                                 return scale;\r
278                         }\r
279                         set \r
280                         { \r
281                                 scale = value; \r
282                         }\r
283                 }\r
284                 \r
285                 public int Size \r
286                 {\r
287                         get \r
288                         {\r
289                                 return size;\r
290                         }\r
291                         set \r
292                         { \r
293                                 size = value;\r
294                         }\r
295                 }\r
296                 #endregion\r
297                 #region Value\r
298                 ///\r
299                 /// The actual parameter data\r
300                 /// \r
301                 public object Value \r
302                 {\r
303                         get\r
304                         {\r
305                                 return dataVal;\r
306                         }\r
307                         set \r
308                         {\r
309                                 this.dataVal = value;\r
310                         }\r
311                 }\r
312                 #endregion\r
313                 #endregion\r
314                 #region inferType Method\r
315                 /// <summary>\r
316                 /// Determine the data type based on the value\r
317                 /// </summary>\r
318                 private void InferType()\r
319                 {\r
320                         if(Value == null)\r
321                                 throw new ArgumentException("No DB2Parameter.Value found");\r
322 \r
323                         if(Value is IConvertible)\r
324                         {\r
325                                 switch(((IConvertible)Value).GetTypeCode())\r
326                                 {\r
327                                         case TypeCode.Char:      dbType = DbType.Byte;       db2Type = DB2Type.SmallInt;    db2DataType = DB2Constants.SQL_WCHAR;           break;\r
328                                         case TypeCode.Boolean:   dbType = DbType.Byte;       db2Type = DB2Type.SmallInt;    db2DataType = DB2Constants.SQL_BIT;             break;\r
329                                         case TypeCode.SByte:\r
330                                         case TypeCode.Byte:      dbType = DbType.Byte;       db2Type = DB2Type.SmallInt;    db2DataType = DB2Constants.SQL_UTINYINT;        break;\r
331                                         case TypeCode.UInt16:\r
332                                         case TypeCode.Int16:     dbType = DbType.Int16;      db2Type = DB2Type.SmallInt;    db2DataType = DB2Constants.SQL_SMALLINT;        break;\r
333                                         case TypeCode.UInt32:\r
334                                         case TypeCode.Int32:     dbType = DbType.Int32;      db2Type = DB2Type.Integer;     db2DataType = DB2Constants.SQL_INTEGER;         break;\r
335                                         case TypeCode.UInt64:\r
336                                         case TypeCode.Int64:     dbType = DbType.Int64;      db2Type = DB2Type.BigInt;      db2DataType = DB2Constants.SQL_BIGINT;          break;\r
337                                         case TypeCode.Single:    dbType = DbType.Single;     db2Type = DB2Type.Float;       db2DataType = DB2Constants.SQL_REAL;            break;\r
338                                         case TypeCode.Double:    dbType = DbType.Double;     db2Type = DB2Type.Double;      db2DataType = DB2Constants.SQL_DOUBLE;          break;\r
339                                         case TypeCode.Decimal:   dbType = DbType.Decimal;    db2Type = DB2Type.Decimal;     db2DataType = DB2Constants.SQL_DECIMAL;         break;\r
340                                         case TypeCode.DateTime:  dbType = DbType.DateTime;   db2Type = DB2Type.Timestamp;   db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP;  break;\r
341                                         case TypeCode.String:    dbType = DbType.String;     db2Type = DB2Type.VarChar;     db2DataType = DB2Constants.SQL_WCHAR;           break;\r
342 \r
343                                         case TypeCode.Object:\r
344                                         case TypeCode.DBNull:\r
345                                         case TypeCode.Empty:\r
346                                                 throw new SystemException("Unknown data type");\r
347                                         default:\r
348                                                 throw new SystemException("Value is of unknown data type");\r
349                                 }\r
350                         }\r
351                         else if(Value is byte[])\r
352                         {\r
353                                 dbType = DbType.Binary;\r
354                                 db2Type = DB2Type.VarBinary;\r
355                                 db2DataType = DB2Constants.SQL_VARBINARY;\r
356                         }\r
357                         else if(Value is TimeSpan)\r
358                         {\r
359                                 dbType = DbType.Time;\r
360                                 db2Type = DB2Type.Time;\r
361                                 db2DataType = DB2Constants.SQL_TYPE_TIME;\r
362                         }\r
363                         else\r
364                         {\r
365                                 throw new NotSupportedException("Value is of unsupported data type");\r
366                         }\r
367                 }\r
368                 #endregion\r
369                 \r
370                 internal void CalculateRequiredmemory()\r
371                 {\r
372                         if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))\r
373                         {\r
374                                 if(Value == null)\r
375                                         throw new ArgumentException("Value missing");\r
376                         }\r
377                         if(dbType == DbType.Object)\r
378                         {\r
379                                 if((direction == ParameterDirection.Output) || (direction == ParameterDirection.ReturnValue))\r
380                                         throw new ArgumentException("Unknown type");\r
381 \r
382                                 if((direction != ParameterDirection.Input) || !Convert.IsDBNull(Value))\r
383                                 {\r
384                                         InferType();\r
385                                 }\r
386                         }\r
387 \r
388                         if((db2DataType == DB2Constants.SQL_VARBINARY) ||\r
389                                 (db2DataType == DB2Constants.SQL_WCHAR))\r
390                         {\r
391                                 if(Size <= 0)\r
392                                 {\r
393                                         if(direction != ParameterDirection.Input)\r
394                                                 throw new ArgumentException("Size not specified");\r
395                                         if(Value == DBNull.Value)\r
396                                                 requiredMemory = 0;\r
397                                         else if(Value is string)\r
398                                                 requiredMemory = ((string)Value).Length;\r
399                                         else if(Value is byte[])\r
400                                                 requiredMemory = ((byte[])Value).Length;\r
401                                         else\r
402                                                 throw new ArgumentException("wrong type!?");\r
403                                 }\r
404                                 else\r
405                                 {\r
406                                         requiredMemory = Size;\r
407                                 }\r
408                                 if(db2DataType == DB2Constants.SQL_WCHAR)\r
409                                         requiredMemory = (requiredMemory * 2) + 2;\r
410                                 requiredMemory = (requiredMemory | 0xf) + 1;\r
411                         }\r
412                         requiredMemory = Math.Max(128, requiredMemory);\r
413                 }\r
414 \r
415                 #region Bind \r
416                 ///\r
417                 /// Bind this parameter\r
418                 /// \r
419                 internal short Bind(IntPtr hwndStmt, short paramNum)\r
420                 {\r
421                         int inLength = requiredMemory;\r
422                         db2LastUsedDataType = db2DataType;\r
423                         short db2CType = DB2Constants.SQL_C_DEFAULT;\r
424                         if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))\r
425                         {\r
426                                 if(Convert.IsDBNull(Value))\r
427                                 {\r
428                                         inLength = DB2Constants.SQL_NULL_DATA;\r
429                                         if((db2DataType == DB2Constants.SQL_UNKNOWN_TYPE) || \r
430                                                 (db2DataType == DB2Constants.SQL_DECIMAL))\r
431                                         {\r
432                                                 db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;\r
433                                                 db2CType = DB2Constants.SQL_C_WCHAR;\r
434                                         }\r
435                                 }\r
436                         }\r
437                         if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))\r
438                         {\r
439                                 switch (db2DataType) \r
440                                 {\r
441                                         case DB2Constants.SQL_WCHAR:\r
442                                                 string tmpString = Convert.ToString(Value);\r
443                                                 inLength =  tmpString.Length;\r
444                                                 if((Size > 0) && (inLength > Size))\r
445                                                         inLength = Size;\r
446                                                 Marshal.Copy(tmpString.ToCharArray(), 0, internalBuffer, inLength);\r
447                                                 inLength *= 2;\r
448                                                 db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;\r
449                                                 db2CType = DB2Constants.SQL_C_WCHAR;\r
450                                                 break;\r
451                                         case DB2Constants.SQL_VARBINARY:\r
452                                                 byte[] tmpBytes = (byte[])Value;\r
453                                                 inLength = tmpBytes.Length;\r
454                                                 if((Size > 0) && (inLength > Size))\r
455                                                         inLength = Size;\r
456                                                 Marshal.Copy(tmpBytes, 0, internalBuffer, inLength);\r
457                                                 db2CType = DB2Constants.SQL_TYPE_BINARY;\r
458                                                 break;\r
459                                         case DB2Constants.SQL_BIT:\r
460                                         case DB2Constants.SQL_UTINYINT:\r
461                                         case DB2Constants.SQL_SMALLINT:\r
462                                                 Marshal.WriteInt16(internalBuffer, Convert.ToInt16(Value));\r
463                                                 db2CType = DB2Constants.SQL_C_SSHORT;\r
464                                                 break;\r
465                                         case DB2Constants.SQL_INTEGER:\r
466                                                 Marshal.WriteInt32(internalBuffer, Convert.ToInt32(Value));\r
467                                                 db2CType = DB2Constants.SQL_C_SLONG;\r
468                                                 break;\r
469                                         case DB2Constants.SQL_BIGINT:\r
470                                                 Marshal.WriteInt64(internalBuffer, Convert.ToInt64(Value));\r
471                                                 db2CType = DB2Constants.SQL_C_SBIGINT;\r
472                                                 break;\r
473                                         case DB2Constants.SQL_REAL:\r
474                                                 Marshal.StructureToPtr((float)Convert.ToDouble(Value), internalBuffer, false);\r
475                                                 db2CType = DB2Constants.SQL_C_TYPE_REAL;\r
476                                                 break;\r
477                                         case DB2Constants.SQL_DOUBLE:\r
478                                                 Marshal.StructureToPtr(Convert.ToDouble(Value), internalBuffer, false);\r
479                                                 db2CType = DB2Constants.SQL_C_DOUBLE;\r
480                                                 break;\r
481                                         case DB2Constants.SQL_DECIMAL:\r
482                                                 byte[] tmpDecimalData = System.Text.Encoding.UTF8.GetBytes(\r
483                                                         Convert.ToDecimal(Value).ToString(System.Globalization.CultureInfo.InvariantCulture));\r
484                                                 inLength =  Math.Min(tmpDecimalData.Length, requiredMemory);\r
485                                                 Marshal.Copy(tmpDecimalData, 0, internalBuffer, inLength);\r
486                                                 db2LastUsedDataType = DB2Constants.SQL_VARCHAR;\r
487                                                 db2CType = DB2Constants.SQL_C_CHAR;\r
488                                                 break;\r
489                                         case DB2Constants.SQL_TYPE_DATE:\r
490                                                 DateTime tmpDate = Convert.ToDateTime(Value);\r
491                                                 Marshal.WriteInt16(internalBuffer, 0,  (short)tmpDate.Year);\r
492                                                 Marshal.WriteInt16(internalBuffer, 2,  (short)tmpDate.Month);\r
493                                                 Marshal.WriteInt16(internalBuffer, 4,  (short)tmpDate.Day);\r
494                                                 db2CType = DB2Constants.SQL_C_TYPE_DATE;\r
495                                                 break;\r
496                                         case DB2Constants.SQL_TYPE_TIMESTAMP:\r
497                                                 DateTime tmpDateTime = Convert.ToDateTime(Value);\r
498                                                 Marshal.WriteInt16(internalBuffer, 0,  (short)tmpDateTime.Year);\r
499                                                 Marshal.WriteInt16(internalBuffer, 2,  (short)tmpDateTime.Month);\r
500                                                 Marshal.WriteInt16(internalBuffer, 4,  (short)tmpDateTime.Day);\r
501                                                 Marshal.WriteInt16(internalBuffer, 6,  (short)tmpDateTime.Hour);\r
502                                                 Marshal.WriteInt16(internalBuffer, 8,  (short)tmpDateTime.Minute);\r
503                                                 Marshal.WriteInt16(internalBuffer, 10, (short)tmpDateTime.Second);\r
504                                                 Marshal.WriteInt32(internalBuffer, 12, (int)((tmpDateTime.Ticks % 10000000) * 100));\r
505                                                 db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;\r
506                                                 break;\r
507                                         case DB2Constants.SQL_TYPE_TIME:\r
508                                                 TimeSpan tmpTime = (TimeSpan)Value;\r
509                                                 Marshal.WriteInt16(internalBuffer, 0,  (short)tmpTime.Hours);\r
510                                                 Marshal.WriteInt16(internalBuffer, 2,  (short)tmpTime.Minutes);\r
511                                                 Marshal.WriteInt16(internalBuffer, 4,  (short)tmpTime.Seconds);\r
512                                                 db2CType = DB2Constants.SQL_C_TYPE_TIME;\r
513                                                 break;\r
514                                 }\r
515                         }\r
516                         else\r
517                         {\r
518                                 switch (db2DataType) \r
519                                 {\r
520                                         case DB2Constants.SQL_WCHAR:\r
521                                                 db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;\r
522                                                 db2CType = DB2Constants.SQL_C_WCHAR;\r
523                                                 break;\r
524                                         case DB2Constants.SQL_VARBINARY:\r
525                                                 db2CType = DB2Constants.SQL_TYPE_BINARY;\r
526                                                 break;\r
527                                         case DB2Constants.SQL_BIT:\r
528                                         case DB2Constants.SQL_UTINYINT:\r
529                                         case DB2Constants.SQL_SMALLINT:\r
530                                                 db2CType = DB2Constants.SQL_C_SSHORT;\r
531                                                 break;\r
532                                         case DB2Constants.SQL_INTEGER:\r
533                                                 db2CType = DB2Constants.SQL_C_SLONG;\r
534                                                 break;\r
535                                         case DB2Constants.SQL_BIGINT:\r
536                                                 db2CType = DB2Constants.SQL_C_SBIGINT;\r
537                                                 break;\r
538                                         case DB2Constants.SQL_REAL:\r
539                                                 db2CType = DB2Constants.SQL_C_TYPE_REAL;\r
540                                                 break;\r
541                                         case DB2Constants.SQL_DOUBLE:\r
542                                                 db2CType = DB2Constants.SQL_C_DOUBLE;\r
543                                                 break;\r
544                                         case DB2Constants.SQL_DECIMAL:\r
545                                                 db2LastUsedDataType = DB2Constants.SQL_VARCHAR;\r
546                                                 db2CType = DB2Constants.SQL_C_CHAR;\r
547                                                 break;\r
548                                         case DB2Constants.SQL_TYPE_DATE:\r
549                                                 db2CType = DB2Constants.SQL_C_TYPE_DATE;\r
550                                                 break;\r
551                                         case DB2Constants.SQL_TYPE_TIMESTAMP:\r
552                                                 db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;\r
553                                                 break;\r
554                                         case DB2Constants.SQL_TYPE_TIME:\r
555                                                 db2CType = DB2Constants.SQL_C_TYPE_TIME;\r
556                                                 break;\r
557                                 }\r
558                         }\r
559                         Marshal.WriteInt32(internalLengthBuffer, inLength);\r
560                         short sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, paramNum, db2Direction, \r
561                                 db2CType, db2LastUsedDataType, Size, Scale,\r
562                                 internalBuffer, requiredMemory, internalLengthBuffer);\r
563 \r
564                         return sqlRet;\r
565                 }\r
566                 #endregion\r
567                 object ICloneable.Clone ()\r
568                 {\r
569                         DB2Parameter clone = new DB2Parameter();\r
570                         clone.dbType = dbType;\r
571                         clone.db2Type = db2Type;\r
572                         clone.db2DataType = db2DataType;\r
573                         clone.db2LastUsedDataType = db2LastUsedDataType;\r
574                         clone.direction = direction;\r
575                         clone.db2Direction = db2Direction;\r
576                         clone.nullable = nullable;\r
577                         clone.parameterName = parameterName;\r
578                         clone.sourceColumn = sourceColumn;\r
579                         clone.sourceVersion = sourceVersion;\r
580                         clone.dataVal = dataVal;\r
581                         clone.scale = scale;\r
582                         clone.precision = precision;\r
583                         clone.size = size;\r
584                         if(dataVal is ICloneable)\r
585                         {\r
586                                 clone.dataVal = ((ICloneable)dataVal).Clone();\r
587                         }\r
588                         return clone;\r
589                 }\r
590                 \r
591                 internal void GetOutValue()\r
592                 {\r
593                         int length = Marshal.ReadInt32(internalLengthBuffer);\r
594                         if(length == DB2Constants.SQL_NULL_DATA)\r
595                         {\r
596                                 dataVal = DBNull.Value;\r
597                                 return;\r
598                         }\r
599                         switch(DB2Type) \r
600                         {\r
601                                 case DB2Type.SmallInt:\r
602                                         dataVal = Marshal.ReadInt16(internalBuffer);\r
603                                         break;\r
604                                 case DB2Type.Integer:\r
605                                         dataVal = Marshal.ReadInt32(internalBuffer);\r
606                                         break;\r
607                                 case DB2Type.BigInt:\r
608                                         dataVal = Marshal.ReadInt64(internalBuffer);\r
609                                         break;\r
610                                 case DB2Type.Double:\r
611                                         dataVal = Marshal.PtrToStructure(internalBuffer, typeof(Double));\r
612                                         break;\r
613                                 case DB2Type.Float:\r
614                                         dataVal = Marshal.PtrToStructure(internalBuffer, typeof(Single));\r
615                                         break;\r
616                                 case DB2Type.Char:\r
617                                 case DB2Type.VarChar:\r
618                                 case DB2Type.LongVarChar:\r
619                                 case DB2Type.Graphic:\r
620                                 case DB2Type.VarGraphic:\r
621                                 case DB2Type.LongVarGraphic:\r
622                                 case DB2Type.Clob:\r
623                                 case DB2Type.DbClob:\r
624                                         dataVal = Marshal.PtrToStringUni(internalBuffer, Math.Min(Size, length / 2));\r
625                                         break;\r
626                                 case DB2Type.Binary:\r
627                                 case DB2Type.VarBinary:\r
628                                 case DB2Type.LongVarBinary:\r
629                                 case DB2Type.Blob:\r
630                                 case DB2Type.Datalink:\r
631                                         length = Math.Min(Size, length);\r
632                                         dataVal = new byte[length];\r
633                                         Marshal.Copy(internalBuffer, (byte[])dataVal, 0, length);\r
634                                         break;\r
635                                 case DB2Type.Decimal:\r
636                                         dataVal = decimal.Parse(Marshal.PtrToStringAnsi(internalBuffer, length), \r
637                                                 System.Globalization.CultureInfo.InvariantCulture);\r
638                                         break;\r
639                                 case DB2Type.Timestamp:\r
640                                         DateTime dtTmp = new DateTime(\r
641                                                 Marshal.ReadInt16(internalBuffer, 0),  // year\r
642                                                 Marshal.ReadInt16(internalBuffer, 2),  // month\r
643                                                 Marshal.ReadInt16(internalBuffer, 4),  // day\r
644                                                 Marshal.ReadInt16(internalBuffer, 6),  // hour\r
645                                                 Marshal.ReadInt16(internalBuffer, 8),  // minute\r
646                                                 Marshal.ReadInt16(internalBuffer, 10));// second\r
647                                         dataVal = dtTmp.AddTicks(Marshal.ReadInt32(internalBuffer, 12) / 100); // nanoseconds \r
648                                         break;\r
649                                 case DB2Type.Date:\r
650                                         dataVal = new DateTime(\r
651                                                 Marshal.ReadInt16(internalBuffer, 0),\r
652                                                 Marshal.ReadInt16(internalBuffer, 2),\r
653                                                 Marshal.ReadInt16(internalBuffer, 4));\r
654                                         break;\r
655                                 case DB2Type.Time:\r
656                                         dataVal = new TimeSpan(\r
657                                                 Marshal.ReadInt16(internalBuffer, 0),  // Hour\r
658                                                 Marshal.ReadInt16(internalBuffer, 2),  // Minute\r
659                                                 Marshal.ReadInt16(internalBuffer, 4)); // Second\r
660                                         break;\r
661 \r
662                                 case DB2Type.Invalid:\r
663                                 case DB2Type.Real:\r
664                                 case DB2Type.Numeric:\r
665                                 case DB2Type.RowId:\r
666                                 case DB2Type.XmlReader:\r
667                                         throw new NotImplementedException();\r
668                                 default:\r
669                                         throw new NotSupportedException("unknown data type");\r
670                         }\r
671                 }\r
672         }\r
673 }\r