2005-06-05 Peter Bartok <pbartok@novell.com>
[mono.git] / mcs / class / Mono.Data.DB2Client / Mono.Data.Db2Client / DB2ClientParameter.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 #region Licence\r
23         /// DB2DriverCS - A DB2 driver for .Net\r
24         /// Copyright 2003 By Christopher Bockner\r
25         /// Released under the terms of the MIT/X11 Licence\r
26         /// Please refer to the Licence.txt file that should be distributed with this package\r
27         /// This software requires that DB2 client software be installed correctly on the machine\r
28         /// (or instance) on which the driver is running.  \r
29 #endregion\r
30 using System;\r
31 using System.Data;\r
32 \r
33 namespace DB2ClientCS\r
34 {\r
35         /// <summary>\r
36         /// Parameter object for DB2 client\r
37         /// </summary>\r
38         public sealed class DB2ClientParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable\r
39         {\r
40                 private DbType dbType;\r
41                 private IntPtr db2DataType;\r
42                 private ParameterDirection direction;\r
43                 private bool nullable;\r
44                 private string parameterName;\r
45                 private string sourceColumn;\r
46                 private IntPtr paramSize;\r
47                 private IntPtr decimalDigits;\r
48                 private DataRowVersion sourceVersion;\r
49                 object dataVal;\r
50                 byte[] bDataVal;\r
51                 private int iDataVal;\r
52                 private byte scale, precision;\r
53                 private int size;\r
54                 bool selfDescribe = false;\r
55 \r
56                 #region Contructors and destructors\r
57                 public DB2ClientParameter()\r
58                 {\r
59                 }\r
60                 public DB2ClientParameter (string name)\r
61                 {\r
62                         parameterName = name;\r
63                 }\r
64 \r
65                 public DB2ClientParameter(string name, DbType type)\r
66                 {\r
67                         parameterName = name;\r
68                         dbType = type;\r
69                 }\r
70                 public DB2ClientParameter(string name, object data)\r
71                 {\r
72                         parameterName = name;\r
73                         this.Value = data;\r
74                 }\r
75                 public DB2ClientParameter(string name, DbType type, string columnName)\r
76                 {\r
77                         parameterName = name;\r
78                         dbType = type;\r
79                         sourceColumn = columnName;\r
80                 }\r
81                 public DB2ClientParameter(string name, int db2Type)\r
82                 {\r
83                         parameterName = name;\r
84                         dbType = inferTypeFromDB2Type(db2Type);\r
85                         db2DataType = new IntPtr(db2Type);\r
86                 }\r
87                 #endregion\r
88                 #region Properties\r
89                 #region DbType Property\r
90                 ///\r
91                 /// Parameter data type\r
92                 /// \r
93                 public DbType DbType\r
94                 {\r
95                         get \r
96                         {\r
97                                 return dbType;\r
98                         }\r
99                         set \r
100                         {\r
101                                 dbType = value;\r
102                         }\r
103                 }\r
104                 #endregion\r
105                 #region Direction\r
106                 ///\r
107                 /// In or out parameter, or both\r
108                 /// \r
109                 public ParameterDirection Direction\r
110                 {\r
111                         get \r
112                         {\r
113                                 return direction;\r
114                         }\r
115                         set \r
116                         {\r
117                                 direction = value;\r
118                         }\r
119                 }\r
120                 #endregion\r
121                 #region IsNullable\r
122                 ///\r
123                 /// Does this parameter support a null value\r
124                 /// \r
125                 public bool IsNullable \r
126                 {\r
127                         get \r
128                         {\r
129                                 return nullable;\r
130                         }\r
131                         set \r
132                         {\r
133                                 nullable = value;\r
134                         }\r
135                 }\r
136                 #endregion\r
137                 #region ParameterName\r
138                 public string ParameterName\r
139                 {\r
140                         get \r
141                         {\r
142                                 return parameterName;\r
143                         }\r
144                         set \r
145                         {\r
146                                 parameterName = value;\r
147                         }\r
148                 }\r
149                 #endregion\r
150                 #region SourceColumn\r
151                 ///\r
152                 /// Gets or sets the name of the source column that is mapped to the DataSet\r
153                 /// \r
154                 public string SourceColumn\r
155                 {\r
156                         get \r
157                         {\r
158                                 return sourceColumn;\r
159                         }\r
160                         set \r
161                         {\r
162                                 sourceColumn = value;\r
163                         }\r
164                 }\r
165                 #endregion\r
166                 #region SourceVersion\r
167                 ///\r
168                 /// DataRowVersion property\r
169                 /// \r
170                 public DataRowVersion SourceVersion \r
171                 {\r
172                         get \r
173                         {\r
174                                 return sourceVersion;\r
175                         }\r
176                         set \r
177                         {\r
178                                 sourceVersion = value;\r
179                         }\r
180                 }\r
181                 #endregion\r
182                 #region IDbDataParameter properties\r
183                 public byte Precision \r
184                 {\r
185                         get \r
186                         { \r
187                                 return precision; \r
188                         }\r
189                         set \r
190                         { \r
191                                 precision = value; \r
192                         }\r
193                 }\r
194                 \r
195                 public byte Scale \r
196                 {\r
197                         get \r
198                         { \r
199                                 return scale; \r
200                         }\r
201                         set \r
202                         { \r
203                                 scale = value; \r
204                         }\r
205                 }\r
206                 \r
207                 public int Size \r
208                 {\r
209                         get \r
210                         { \r
211                                 return size;\r
212                         }\r
213                         set \r
214                         { \r
215                                 size = value;\r
216                         }\r
217                 }\r
218                 #endregion\r
219                 #region Value\r
220                 ///\r
221                 /// The actual parameter data\r
222                 /// \r
223                 public object Value \r
224                 {\r
225                         get\r
226                         {\r
227                                 return dataVal;\r
228                         }\r
229                         set \r
230                         {\r
231                                 this.dataVal = value;\r
232                                 DbType = inferType(dataVal);\r
233                                 // Load buffer with new value\r
234                                 if (dbType==DbType.Int32)\r
235                                         iDataVal=(int) value;\r
236                                 else\r
237                                 {\r
238                                         // Treat everything else as a string\r
239                                         // Init string buffer\r
240                                         if (bDataVal==null || bDataVal.Length< (((int)paramSize>20)?(int)paramSize:20) )\r
241                                                 bDataVal=new byte[((int)paramSize>20)?(int)paramSize:20];\r
242                                         else\r
243                                                 bDataVal.Initialize();\r
244                                         // Convert value into string and store into buffer\r
245                                         byte[] strValueBuffer=System.Text.Encoding.ASCII.GetBytes(dataVal.ToString());\r
246                                         strValueBuffer.CopyTo(bDataVal,0);\r
247                                 }\r
248                         }\r
249                 }\r
250                 #endregion\r
251                 #endregion\r
252                 #region inferType Method\r
253                 /// <summary>\r
254                 /// Determine the data type based on the value\r
255                 /// </summary>\r
256                 private DbType inferType (object Data)\r
257                 {\r
258                         switch (Type.GetTypeCode(Data.GetType()))\r
259                         {\r
260                                 case TypeCode.Empty:\r
261                                         throw new SystemException("Invalid data type");\r
262 \r
263                                 case TypeCode.Object:\r
264                                         return DbType.Object;\r
265 \r
266                                 case TypeCode.DBNull:\r
267                                 case TypeCode.Char:\r
268                                 case TypeCode.SByte:\r
269                                 case TypeCode.UInt16:\r
270                                 case TypeCode.UInt32:\r
271                                 case TypeCode.UInt64:\r
272                                         // Throw a SystemException for unsupported data types.\r
273                                         throw new SystemException("Invalid data type");\r
274 \r
275                                 case TypeCode.Boolean:\r
276                                         return DbType.Boolean;\r
277 \r
278                                 case TypeCode.Byte:\r
279                                         return DbType.Byte;\r
280 \r
281                                 case TypeCode.Int16:\r
282                                         return DbType.Int16;\r
283 \r
284                                 case TypeCode.Int32:\r
285                                         return DbType.Int32;\r
286 \r
287                                 case TypeCode.Int64:\r
288                                         return DbType.Int64;\r
289 \r
290                                 case TypeCode.Single:\r
291                                         return DbType.Single;\r
292 \r
293                                 case TypeCode.Double:\r
294                                         return DbType.Double;\r
295 \r
296                                 case TypeCode.Decimal:\r
297                                         return DbType.Decimal;\r
298 \r
299                                 case TypeCode.DateTime:\r
300                                         return DbType.DateTime;\r
301 \r
302                                 case TypeCode.String:\r
303                                         return DbType.String;\r
304 \r
305                                 default:\r
306                                         throw new SystemException("Value is of unknown data type");\r
307                         }\r
308                 }\r
309                 #endregion\r
310                 #region inferTypeFromDB2Type\r
311                 ///\r
312                 /// Determine the DbType from the SQL type returned by SQLDescribeParam\r
313                 /// \r
314                 private DbType inferTypeFromDB2Type(int db2Type)\r
315                 {\r
316                         switch (db2Type) \r
317                         {\r
318                                 case DB2ClientConstants.SQL_CHAR:\r
319                                         return DbType.AnsiString;\r
320                                 case DB2ClientConstants.SQL_NUMERIC:\r
321                                 case DB2ClientConstants.SQL_DECIMAL:\r
322                                         return DbType.Decimal;\r
323                                 case DB2ClientConstants.SQL_DATETIME:\r
324                                         return DbType.DateTime;\r
325                                 case DB2ClientConstants.SQL_FLOAT:\r
326                                 case DB2ClientConstants.SQL_DOUBLE:\r
327                                         return DbType.Double;\r
328                                 case DB2ClientConstants.SQL_INTEGER:\r
329                                         return DbType.Int32;\r
330                                 case DB2ClientConstants.SQL_SMALLINT:\r
331                                         return DbType.Int16;\r
332                                 case DB2ClientConstants.SQL_VARCHAR:\r
333                                         return DbType.String;\r
334                                 case DB2ClientConstants.SQL_USER_DEFINED_TYPE:\r
335                                         return DbType.Object;\r
336                                 default:\r
337                                         throw new SystemException("DB2 Data type is unknown.");\r
338                         }\r
339                 }\r
340                 #endregion\r
341                 #region Describe\r
342                 ///\r
343                 /// Describe the parameter.  Use at the caller's discretion\r
344                 /// \r
345                 public short Describe(IntPtr hwndStmt, short paramNum)\r
346                 {\r
347                         IntPtr nullable = IntPtr.Zero;\r
348                         paramSize = IntPtr.Zero;\r
349                         decimalDigits = IntPtr.Zero;\r
350                         short sqlRet = 0;\r
351 \r
352                         sqlRet = DB2ClientPrototypes.SQLDescribeParam(hwndStmt, paramNum, ref db2DataType, ref paramSize, ref decimalDigits, ref nullable);\r
353                         return sqlRet;\r
354                 }\r
355                 #endregion\r
356                 #region Bind \r
357                 ///\r
358                 /// Bind this parameter\r
359                 /// \r
360                 public short Bind(IntPtr hwndStmt, short paramNum)\r
361                 {\r
362                         short sqlRet = 0;\r
363 \r
364                         switch ((int)db2DataType) \r
365                         {\r
366                                 case DB2ClientConstants.SQL_DECIMAL:    //These types are treated as SQL_C_CHAR for binding purposes\r
367                                 case DB2ClientConstants.SQL_TYPE_DATE:\r
368                                 case DB2ClientConstants.SQL_TYPE_TIME:\r
369                                 case DB2ClientConstants.SQL_TYPE_TIMESTAMP:\r
370                                 case DB2ClientConstants.SQL_VARCHAR:\r
371                                 case DB2ClientConstants.SQL_CHAR:\r
372                                         sqlRet = DB2ClientPrototypes.SQLBindParameter(hwndStmt, (ushort)paramNum, DB2ClientConstants.SQL_PARAM_INPUT, DB2ClientConstants.SQL_C_DEFAULT, (short)db2DataType,  Convert.ToUInt32((int)paramSize) , (short) decimalDigits, bDataVal, 0, 0);\r
373                                         break;\r
374                                 default:\r
375                                         sqlRet = DB2ClientPrototypes.SQLBindParameter(hwndStmt, (ushort)paramNum, DB2ClientConstants.SQL_PARAM_INPUT, DB2ClientConstants.SQL_C_DEFAULT, (short)db2DataType,  Convert.ToUInt32((int)paramSize) , 0, ref iDataVal, 0, 0);\r
376                                         break;\r
377                         }               \r
378                         return sqlRet;\r
379                 }\r
380                 #endregion\r
381                 object ICloneable.Clone ()\r
382                 {\r
383                         throw new NotImplementedException ();\r
384                 }\r
385         }\r
386 }\r