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