16802f90831af5502f134e0414caed02986e0816
[mono.git] / mcs / class / System.Web / System.Web.SessionState_2.0 / SessionSQLServerHandler.cs
1 //
2 // System.Web.Compilation.SessionStateItemCollection
3 //
4 // Authors:
5 //   Marek Habersack <mhabersack@novell.com>
6 //
7 // (C) 2009-2010 Novell, Inc (http://novell.com/)
8 //
9
10 // Code based on samples from MSDN
11 //
12 // Database schema found in ../ASPState.sql
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 using System;
34 using System.Collections.Generic;
35 using System.Collections.Specialized;
36 using System.Configuration.Provider;
37 using System.Data;
38 using System.Data.Common;
39 using System.IO;
40 using System.IO.Compression;
41 using System.Reflection;
42 using System.Web;
43 using System.Web.Configuration;
44 using System.Web.Hosting;
45
46 namespace System.Web.SessionState 
47 {
48         sealed class SessionSQLServerHandler : SessionStateStoreProviderBase
49         {
50                 static readonly string defaultDbFactoryTypeName = "Mono.Data.Sqlite.SqliteFactory, Mono.Data.Sqlite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";
51                 
52                 SessionStateSection sessionConfig;
53                 string connectionString;
54                 Type providerFactoryType;
55                 DbProviderFactory providerFactory;
56                 int sqlCommandTimeout;
57                 
58                 DbProviderFactory ProviderFactory {
59                         get {
60                                 if (providerFactory == null) {
61                                         try {
62                                                 providerFactory = Activator.CreateInstance (providerFactoryType) as DbProviderFactory;
63                                         } catch (Exception ex) {
64                                                 throw new ProviderException ("Failure to create database factory instance.", ex);
65                                         }
66                                 }
67
68                                 return providerFactory;
69                         }
70                 }
71                 
72                 public string ApplicationName {
73                         get; private set;
74                 }
75                 
76                 public override void Initialize (string name, NameValueCollection config)
77                 {
78                         if (config == null)
79                                 throw new ArgumentNullException ("config");
80
81                         if (String.IsNullOrEmpty (name))
82                                 name = "SessionSQLServerHandler";
83
84                         if (String.IsNullOrEmpty (config["description"])) {
85                                 config.Remove ("description");
86                                 config.Add ("description", "Mono SQL Session Store Provider");
87                         }
88                         ApplicationName = HostingEnvironment.ApplicationVirtualPath;
89                         
90                         base.Initialize(name, config);
91                         sessionConfig = WebConfigurationManager.GetWebApplicationSection ("system.web/sessionState") as SessionStateSection;
92                         connectionString = sessionConfig.SqlConnectionString;
93                         string dbProviderName;
94                         
95                         if (String.IsNullOrEmpty (connectionString) || String.Compare (connectionString, SessionStateSection.DefaultSqlConnectionString, StringComparison.Ordinal) == 0) {
96                                 connectionString = "Data Source=|DataDirectory|/ASPState.sqlite;Version=3";
97                                 dbProviderName = defaultDbFactoryTypeName;
98                         } else {
99                                 string[] parts = connectionString.Split (';');
100                                 var newCS = new List <string> ();
101                                 dbProviderName = null;
102                                 bool allowDb = sessionConfig.AllowCustomSqlDatabase;
103                                 
104                                 foreach (string p in parts) {
105                                         if (p.Trim ().Length == 0)
106                                                 continue;
107                                         
108                                         if (p.StartsWith ("DbProviderName", StringComparison.OrdinalIgnoreCase)) {
109                                                 int idx = p.IndexOf ('=');
110                                                 if (idx < 0)
111                                                         throw new ProviderException ("Invalid format for the 'DbProviderName' connection string parameter. Expected 'DbProviderName = value'.");
112
113                                                 dbProviderName = p.Substring (idx + 1);
114                                                 continue;
115                                         }
116
117                                         if (!allowDb) {
118                                                 string tmp = p.Trim ();
119                                                 if (tmp.StartsWith ("database", StringComparison.OrdinalIgnoreCase) ||
120                                                     tmp.StartsWith ("initial catalog", StringComparison.OrdinalIgnoreCase))
121                                                         throw new ProviderException ("Specifying a custom database is not allowed. Set the allowCustomSqlDatabase attribute of the <system.web/sessionState> section to 'true' in order to use a custom database name.");
122                                         }
123                                         
124                                         newCS.Add (p);
125                                 }
126
127                                 connectionString = String.Join (";", newCS.ToArray ());
128                                 if (String.IsNullOrEmpty (dbProviderName))
129                                         dbProviderName = defaultDbFactoryTypeName;
130
131                                 
132                         }
133
134                         Exception typeException = null;
135                         
136                         try {   
137                                 providerFactoryType = Type.GetType (dbProviderName, true);
138                         } catch (Exception ex) {
139                                 typeException = ex;
140                                 providerFactoryType = null;
141                         }
142
143                         if (providerFactoryType == null)
144                                 throw new ProviderException ("Unable to find database provider factory type.", typeException);
145
146                         sqlCommandTimeout = (int)sessionConfig.SqlCommandTimeout.TotalSeconds;
147                 }
148
149                 public override void Dispose ()
150                 {
151                 }
152
153                 public override bool SetItemExpireCallback (SessionStateItemExpireCallback expireCallback)
154                 {
155                         return false;
156                 }
157
158                 public override void SetAndReleaseItemExclusive (HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)                                           
159                 {
160                         DbCommand cmd;
161                         DbCommand deleteCmd = null;
162                         string sessItems = Serialize((SessionStateItemCollection)item.Items);
163                         DbProviderFactory factory = ProviderFactory;
164                         string appName = ApplicationName;
165                         DbConnection conn = CreateConnection (factory);
166                         DateTime now = DateTime.Now;                    
167                         DbParameterCollection parameters;
168                         
169                         if (newItem) {  
170                                 deleteCmd = CreateCommand (factory, conn, "DELETE FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Expires < @Expires");
171                                 parameters = deleteCmd.Parameters;                              
172
173                                 parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
174                                 parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
175                                 parameters.Add (CreateParameter <DateTime> (factory, "@Expires", now));
176
177                                 cmd = CreateCommand (factory, conn, "INSERT INTO Sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) Values (@SessionId, @ApplicationName, @Created, @Expires, @LockDate, @LockId , @Timeout, @Locked, @SessionItems, @Flags)");
178                                 parameters = cmd.Parameters;
179                                 
180                                 parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
181                                 parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
182                                 parameters.Add (CreateParameter <DateTime> (factory, "@Created", now));
183                                 parameters.Add (CreateParameter <DateTime> (factory, "@Expires", now.AddMinutes ((double)item.Timeout)));
184                                 parameters.Add (CreateParameter <DateTime> (factory, "@LockDate", now));
185                                 parameters.Add (CreateParameter <int> (factory, "@LockId", 0));
186                                 parameters.Add (CreateParameter <int> (factory, "@Timeout", item.Timeout));
187                                 parameters.Add (CreateParameter <bool> (factory, "@Locked", false));
188                                 parameters.Add (CreateParameter <string> (factory, "@SessionItems", sessItems));
189                                 parameters.Add (CreateParameter <int> (factory, "@Flags", 0));
190                         } else {
191                                 cmd = CreateCommand (factory, conn, "UPDATE Sessions SET Expires = @Expires, SessionItems = @SessionItems, Locked = @Locked WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId");
192                                 parameters = cmd.Parameters;
193
194                                 parameters.Add (CreateParameter <DateTime> (factory, "@Expires", now.AddMinutes ((double)item.Timeout)));
195                                 parameters.Add (CreateParameter <string> (factory, "@SessionItems", sessItems));
196                                 parameters.Add (CreateParameter <bool> (factory, "@Locked", false));
197                                 parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
198                                 parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
199                                 parameters.Add (CreateParameter <int> (factory, "@Lockid", (int)lockId));
200                         }
201
202                         try
203                         {
204                                 conn.Open();
205                                 if (deleteCmd != null)
206                                         deleteCmd.ExecuteNonQuery();
207
208                                 cmd.ExecuteNonQuery();
209                         } catch (Exception ex) {
210                                 throw new ProviderException ("Failure storing session item in database.", ex);
211                         } finally {
212                                 conn.Close();
213                         }
214                 }
215
216                 public override SessionStateStoreData GetItem (HttpContext context, string id, out bool locked, out TimeSpan lockAge,
217                                                                out object lockId, out SessionStateActions actionFlags)
218                 {
219                         return GetSessionStoreItem (false, context, id, out locked, out lockAge, out lockId, out actionFlags);
220                 }
221
222                 public override SessionStateStoreData GetItemExclusive (HttpContext context, string id, out bool locked,out TimeSpan lockAge,
223                                                                        out object lockId, out SessionStateActions actionFlags)
224                 {
225                         return GetSessionStoreItem (true, context, id, out locked, out lockAge, out lockId, out actionFlags);
226                 }
227
228                 private SessionStateStoreData GetSessionStoreItem (bool lockRecord, HttpContext context, string id, out bool locked,
229                                                                    out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags)
230                 {
231                         SessionStateStoreData item = null;
232                         lockAge = TimeSpan.Zero;
233                         lockId = null;
234                         locked = false;
235                         actionFlags = 0;
236
237                         DbProviderFactory factory = ProviderFactory;
238                         DbConnection conn = CreateConnection (factory);
239                         string appName = ApplicationName;
240                         DbCommand cmd = null;
241                         DbDataReader reader = null;
242                         DbParameterCollection parameters;
243                         DateTime expires;
244                         string serializedItems = String.Empty;
245                         bool foundRecord = false;
246                         bool deleteData = false;
247                         int timeout = 0;
248                         DateTime now = DateTime.Now;
249
250                         try {
251                                 conn.Open();
252                                 if (lockRecord) {
253                                         cmd = CreateCommand (factory, conn, "UPDATE Sessions SET Locked = @Locked, LockDate = @LockDate WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Expires > @Expires");
254                                         parameters = cmd.Parameters;
255                                         
256                                         parameters.Add (CreateParameter <bool> (factory, "@Locked", true));
257                                         parameters.Add (CreateParameter <DateTime> (factory, "@LockDate", now));
258                                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
259                                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
260                                         parameters.Add (CreateParameter <DateTime> (factory, "@Expires", now));
261
262                                         if (cmd.ExecuteNonQuery() == 0)
263                                                 locked = true;             
264                                         else
265                                                 locked = false;
266                                 }
267
268                                 cmd = CreateCommand (factory, conn, "SELECT Expires, SessionItems, LockId, LockDate, Flags, Timeout FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName");
269                                 parameters = cmd.Parameters;
270
271                                 parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
272                                 parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
273                                 
274                                 reader = cmd.ExecuteReader (CommandBehavior.SingleRow);
275                                 while (reader.Read()) {
276                                         expires = reader.GetDateTime (reader.GetOrdinal ("Expires"));
277
278                                         if (expires < now) {
279                                                 locked = false;
280                                                 deleteData = true;
281                                         } else
282                                                 foundRecord = true;
283
284                                         serializedItems = reader.GetString (reader.GetOrdinal ("SessionItems"));
285                                         lockId = reader.GetInt32 (reader.GetOrdinal ("LockId"));
286                                         lockAge = now.Subtract (reader.GetDateTime (reader.GetOrdinal ("LockDate")));
287                                         actionFlags = (SessionStateActions) reader.GetInt32 (reader.GetOrdinal ("Flags"));
288                                         timeout = reader.GetInt32 (reader.GetOrdinal ("Timeout"));
289                                 }
290                                 reader.Close();
291
292                                 if (deleteData) {
293                                         cmd = CreateCommand (factory, conn, "DELETE FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName");
294                                         parameters = cmd.Parameters;
295
296                                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
297                                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
298
299                                         cmd.ExecuteNonQuery();
300                                 }
301
302                                 if (!foundRecord)
303                                         locked = false;
304
305                                 if (foundRecord && !locked) {
306                                         lockId = (int)lockId + 1;
307
308                                         cmd = CreateCommand (factory, conn, "UPDATE Sessions SET LockId = @LockId, Flags = 0 WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName");
309                                         parameters = cmd.Parameters;
310
311                                         parameters.Add (CreateParameter <int> (factory, "@LockId", (int)lockId));
312                                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
313                                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", appName, 255));
314                                         
315                                         cmd.ExecuteNonQuery();
316
317                                         if (actionFlags == SessionStateActions.InitializeItem)
318                                                 item = CreateNewStoreData (context, (int)sessionConfig.Timeout.TotalMinutes);
319                                         else
320                                                 item = Deserialize (context, serializedItems, timeout);
321                                 }
322                         } catch (Exception ex) {
323                                 throw new ProviderException ("Unable to retrieve session item from database.", ex);
324                         } finally {
325                                 if (reader != null)
326                                         reader.Close ();
327                                 
328                                 conn.Close();
329                         } 
330
331                         return item;
332                 }
333
334                 string Serialize (SessionStateItemCollection items)
335                 {
336 #if NET_4_0
337                         GZipStream gzip = null;
338 #endif
339                         Stream output;
340                         MemoryStream ms = null;
341                         BinaryWriter writer = null;
342                         
343                         try {
344                                 ms = new MemoryStream ();
345 #if NET_4_0
346                                 if (sessionConfig.CompressionEnabled)
347                                         output = gzip = new GZipStream (ms, CompressionMode.Compress, true);
348                                 else
349 #endif
350                                         output = ms;
351                                 writer = new BinaryWriter (output);
352
353                                 if (items != null)
354                                         items.Serialize (writer);
355 #if NET_4_0
356                                 if (gzip != null)
357                                         gzip.Close ();
358 #endif
359                                 writer.Close ();
360                                 return Convert.ToBase64String (ms.ToArray ());
361                         } finally {
362 #if NET_4_0
363                                 if (writer != null)
364                                         writer.Dispose ();
365                                 if (gzip != null)
366                                         gzip.Dispose ();
367 #else
368                                 if (writer != null)
369                                         ((IDisposable)writer).Dispose ();
370 #endif
371                                 if (ms != null)
372                                         ms.Dispose ();
373                         }
374                 }
375
376                 SessionStateStoreData Deserialize (HttpContext context, string serializedItems, int timeout)
377                 {
378                         MemoryStream ms = null;
379                         Stream input;
380                         BinaryReader reader = null;
381 #if NET_4_0
382                         GZipStream gzip = null;
383 #endif
384                         try {
385                                 ms = new MemoryStream (Convert.FromBase64String (serializedItems));
386                                 var sessionItems = new SessionStateItemCollection ();
387
388                                 if (ms.Length > 0) {
389 #if NET_4_0
390                                         if (sessionConfig.CompressionEnabled)
391                                                 input = gzip = new GZipStream (ms, CompressionMode.Decompress, true);
392                                         else
393 #endif
394                                                 input = ms;
395                                         
396                                         reader = new BinaryReader (input);
397                                         sessionItems = SessionStateItemCollection.Deserialize (reader);
398 #if NET_4_0
399                                         if (gzip != null)
400                                                 gzip.Close ();
401 #endif
402                                         reader.Close ();
403                                 }
404
405                                 return new SessionStateStoreData (sessionItems, SessionStateUtility.GetSessionStaticObjects (context), timeout);
406                         } finally {
407 #if NET_4_0
408                                 if (reader != null)
409                                         reader.Dispose ();
410                                 if (gzip != null)
411                                         gzip.Dispose ();
412 #else
413                                 if (reader != null)
414                                         ((IDisposable)reader).Dispose ();
415 #endif
416                                 if (ms != null)
417                                         ms.Dispose ();
418                         }
419                 }
420
421                 public override void ReleaseItemExclusive (HttpContext context, string id, object lockId)
422                 {
423                         DbProviderFactory factory = ProviderFactory;
424                         DbConnection conn = CreateConnection (factory);
425                         DbCommand cmd = CreateCommand (factory, conn,
426                                                        "UPDATE Sessions SET Locked = 0, Expires = @Expires WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId");
427
428                         DbParameterCollection parameters = cmd.Parameters;
429                         
430                         parameters.Add (CreateParameter <DateTime> (factory, "@Expires", DateTime.Now.AddMinutes(sessionConfig.Timeout.TotalMinutes)));
431                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
432                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", ApplicationName, 255));
433                         parameters.Add (CreateParameter <int> (factory, "@LockId", (int)lockId));
434
435                         try {
436                                 conn.Open ();
437                                 cmd.ExecuteNonQuery ();
438                         } catch (Exception ex) {
439                                 throw new ProviderException ("Error releasing item in database.", ex);
440                         } finally {
441                                 conn.Close();
442                         }      
443                 }
444
445                 public override void RemoveItem (HttpContext context, string id, object lockId, SessionStateStoreData item)
446                 {
447                         DbProviderFactory factory = ProviderFactory;
448                         DbConnection conn = CreateConnection (factory);
449                         DbCommand cmd = CreateCommand (factory, conn,
450                                                        "DELETE FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId");
451
452                         DbParameterCollection parameters = cmd.Parameters;
453                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
454                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", ApplicationName, 255));
455                         parameters.Add (CreateParameter <int> (factory, "@LockId", (int)lockId));
456
457                         try {
458                                 conn.Open ();
459                                 cmd.ExecuteNonQuery ();
460                         } catch (Exception ex) {
461                                 throw new ProviderException ("Error removing item from database.", ex);
462                         } finally {
463                                 conn.Close();
464                         } 
465                 }
466
467                 public override void CreateUninitializedItem (HttpContext context, string id, int timeout)
468                 {
469                         DbProviderFactory factory = ProviderFactory;
470                         DbConnection conn = CreateConnection (factory);
471                         DbCommand cmd = CreateCommand (factory, conn,
472                                                        "INSERT INTO Sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) Values (@SessionId, @ApplicationName, @Created, @Expires, @LockDate, @LockId , @Timeout, @Locked, @SessionItems, @Flags)");
473
474                         DateTime now = DateTime.Now;
475                         DbParameterCollection parameters = cmd.Parameters;
476                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
477                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", ApplicationName, 255));
478                         parameters.Add (CreateParameter <DateTime> (factory, "@Created", now));
479                         parameters.Add (CreateParameter <DateTime> (factory, "@Expires", now.AddMinutes ((double)timeout)));
480                         parameters.Add (CreateParameter <DateTime> (factory, "@LockDate", now));
481                         parameters.Add (CreateParameter <int> (factory, "@LockId", 0));
482                         parameters.Add (CreateParameter <int> (factory, "@Timeout", timeout));
483                         parameters.Add (CreateParameter <bool> (factory, "@Locked", false));
484                         parameters.Add (CreateParameter <string> (factory, "@SessionItems", String.Empty));
485                         parameters.Add (CreateParameter <int> (factory, "@Flags", 1));
486                                 
487                         try {
488                                 conn.Open ();
489                                 cmd.ExecuteNonQuery ();
490                         } catch (Exception ex) {
491                                 throw new ProviderException ("Error creating uninitialized session item in the database.", ex);
492                         } finally {
493                                 conn.Close();
494                         }
495                 }
496
497                 public override SessionStateStoreData CreateNewStoreData (HttpContext context, int timeout)
498                 {
499                         return new SessionStateStoreData (new SessionStateItemCollection (), SessionStateUtility.GetSessionStaticObjects (context), timeout);
500                 }
501
502                 public override void ResetItemTimeout (HttpContext context, string id)
503                 {
504                         DbProviderFactory factory = ProviderFactory;
505                         DbConnection conn = CreateConnection (factory);
506                         DbCommand cmd = CreateCommand (factory, conn,
507                                                        "UPDATE Sessions SET Expires = @Expires WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName");
508
509                         DbParameterCollection parameters = cmd.Parameters;
510                         parameters.Add (CreateParameter <DateTime> (factory, "@Expires", DateTime.Now.AddMinutes (sessionConfig.Timeout.TotalMinutes)));
511                         parameters.Add (CreateParameter <string> (factory, "@SessionId", id, 80));
512                         parameters.Add (CreateParameter <string> (factory, "@ApplicationName", ApplicationName, 255));
513
514                         try {
515                                 conn.Open ();
516                                 cmd.ExecuteNonQuery ();
517                         } catch (Exception ex) {
518                                 throw new ProviderException ("Error resetting session item timeout in the database.", ex);
519                         } finally {
520                                 conn.Close();
521                         }
522                 }
523
524                 public override void InitializeRequest (HttpContext context)
525                 {
526                 }
527
528                 public override void EndRequest(HttpContext context)
529                 {
530                 }
531
532                 DbConnection CreateConnection (DbProviderFactory factory)
533                 {
534                         DbConnection conn = factory.CreateConnection ();
535                         conn.ConnectionString = connectionString;
536
537                         return conn;
538                 }
539
540                 DbCommand CreateCommand (DbProviderFactory factory, DbConnection conn, string commandText)
541                 {
542                         DbCommand cmd = factory.CreateCommand ();
543                         cmd.CommandTimeout = sqlCommandTimeout;
544                         cmd.Connection = conn;
545                         cmd.CommandText = commandText;
546
547                         return cmd;
548                 }
549                 
550                 DbParameter CreateParameter <ValueType> (DbProviderFactory factory, string name, ValueType value)
551                 {
552                         return CreateParameter <ValueType> (factory, name, value, -1);
553                 }
554                 
555                 DbParameter CreateParameter <ValueType> (DbProviderFactory factory, string name, ValueType value, int size)
556                 {
557                         DbParameter param = factory.CreateParameter ();
558                         param.ParameterName = name;
559                         Type vt = typeof (ValueType);
560                         
561                         if (vt == typeof (string))
562                                 param.DbType = DbType.String;
563                         else if (vt == typeof (int))
564                                 param.DbType = DbType.Int32;
565                         else if (vt == typeof (bool))
566                                 param.DbType = DbType.Boolean;
567                         else if (vt == typeof (DateTime))
568                                 param.DbType = DbType.DateTime;
569
570                         if (size > -1)
571                                 param.Size = size;
572                         
573                         param.Value = value;
574
575                         return param;
576                 }
577                 
578         }
579 }