* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.SessionState / SessionSQLServerHandler.cs
index 7b6ba2a4c4baace3e38c3bc6acad1a30aeb05c9f..b0c66030e519af2f71457e33c18461f44cedad88 100644 (file)
@@ -34,6 +34,7 @@ using System.Data;
 using System.Reflection;
 using System.Configuration;
 using System.Collections.Specialized;
+using System.Web.Configuration;
 
 namespace System.Web.SessionState {
 
@@ -41,7 +42,18 @@ namespace System.Web.SessionState {
        {
                private static Type cncType = null;
                private IDbConnection cnc = null;
+#if NET_2_0
+               private SessionStateSection config;
+#else
                private SessionConfig config;
+#endif
+                
+               const string defaultParamPrefix = ":";
+               string paramPrefix;
+               string selectCommand = "SELECT * FROM ASPStateTempSessions WHERE SessionID = :SessionID";
+               string insertCommand = "INSERT INTO ASPStateTempSessions VALUES (:SessionID, :Created, :Expires, :Timeout, :StaticObjectsData, :SessionData)";
+               string updateCommand = "UPDATE ASPStateTempSessions SET SessionData = :SessionData WHERE SessionId = :SessionID";
+               string deleteCommand = "DELETE FROM ASPStateTempSessions WHERE SessionId = :SessionID";
 
                public void Dispose ()
                {
@@ -51,7 +63,13 @@ namespace System.Web.SessionState {
                        }
                }
 
-               public void Init (SessionStateModule module, HttpApplication context, SessionConfig config)
+               public void Init (SessionStateModule module, HttpApplication context,
+#if NET_2_0
+                                 SessionStateSection config
+#else
+                                 SessionConfig config
+#endif
+                                 )
                {
                        string connectionTypeName;
                        string providerAssemblyName;
@@ -77,17 +95,33 @@ namespace System.Web.SessionState {
                                cnc = null;
                                throw exc;
                        }
+
+                       if (paramPrefix != defaultParamPrefix) {
+                               ReplaceParamPrefix (ref selectCommand);
+                               ReplaceParamPrefix (ref insertCommand);
+                               ReplaceParamPrefix (ref updateCommand);
+                               ReplaceParamPrefix (ref deleteCommand);
+                       }
+               }
+
+               void ReplaceParamPrefix(ref string command)
+               {
+                       command = command.Replace (defaultParamPrefix, paramPrefix);
                }
 
                public void UpdateHandler (HttpContext context, SessionStateModule module)
                {
-                       if (context.Session == null || context.Session.IsReadOnly)
+                       HttpSessionState session = context.Session;
+                       if (session == null || session.IsReadOnly)
                                return;
 
-                       string id = context.Session.SessionID;
-                       SessionDictionary dict = context.Session.SessionDictionary;
-
-                       UpdateSession (id, dict);
+                       string id = session.SessionID;
+                       if (!session._abandoned) {
+                               SessionDictionary dict = session.SessionDictionary;
+                               UpdateSessionWithRetry (id, dict);
+                       } else {
+                               DeleteSessionWithRetry (id);
+                       }
                }
 
                public HttpSessionState UpdateContext (HttpContext context, SessionStateModule module,
@@ -107,10 +141,21 @@ namespace System.Web.SessionState {
 
                        id = SessionId.Create (module.Rng);
                        session = new HttpSessionState (id, new SessionDictionary (),
-                                       HttpApplicationFactory.ApplicationState.SessionObjects, config.Timeout,
+                                       HttpApplicationFactory.ApplicationState.SessionObjects,
+#if NET_2_0
+                                       (int)config.Timeout.TotalMinutes,
+#else
+                                       config.Timeout,
+#endif
                                        true, config.CookieLess, SessionStateMode.SQLServer, read_only);
 
-                       InsertSession (session, config.Timeout);
+                       InsertSessionWithRetry (session,
+#if NET_2_0
+                                      (int)config.Timeout.TotalMinutes
+#else
+                                      config.Timeout
+#endif
+                                      );
                        isNew = true;
                        return session;
                }
@@ -122,15 +167,11 @@ namespace System.Web.SessionState {
                        cncTypeName = null;
                        cncString = null;
 
-                       NameValueCollection config = ConfigurationSettings.AppSettings as NameValueCollection;
+                       NameValueCollection config = ConfigurationSettings.AppSettings;
                        if (config != null) {
-                               foreach (string s in config.Keys) {
-                                       if (0 == String.Compare ("StateDBProviderAssembly", s, true)) {
-                                               providerAssembly = config [s];
-                                       } else if (0 == String.Compare ("StateDBConnectionType", s, true)) {
-                                               cncTypeName = config [s];
-                                       }
-                               }
+                               providerAssembly = config ["StateDBProviderAssembly"];
+                               cncTypeName = config ["StateDBConnectionType"];
+                               paramPrefix = config ["StateDBParamPrefix"];
                        }
 
                        cncString = this.config.SqlConnectionString;
@@ -143,23 +184,40 @@ namespace System.Web.SessionState {
 
                        if (cncString == null || cncString == String.Empty)
                                cncString = "SERVER=127.0.0.1;USER ID=monostate;PASSWORD=monostate;dbname=monostate";
+
+                       if (paramPrefix == null || paramPrefix == String.Empty)
+                               paramPrefix = defaultParamPrefix;
                }
 
-               private HttpSessionState SelectSession (string id, bool read_only)
+               IDataReader GetReader (string id)
                {
-                       HttpSessionState session = null;
-                       IDbCommand command = cnc.CreateCommand();
-                       IDataReader reader;
-
-                       string select = "SELECT * from aspstatetempsessions WHERE SessionID = :SessionID";
-
-                       command.CommandText = select;
+                       IDbCommand command = null;
+                       command = cnc.CreateCommand();
+                       command.CommandText = selectCommand;
+                       command.Parameters.Add (CreateParam (command, DbType.String, "SessionID", id));
+                       return command.ExecuteReader ();
+               }
 
-                       command.Parameters.Add (CreateParam (command, DbType.String, ":SessionID", id));
+               IDataReader GetReaderWithRetry (string id)
+               {
+                       try {
+                               return GetReader (id);
+                       } catch {
+                       }
 
                        try {
-                               reader = command.ExecuteReader ();
+                               cnc.Close ();
+                       } catch {
+                       }
+
+                       cnc.Open ();
+                       return GetReader (id);
+               }
 
+               private HttpSessionState SelectSession (string id, bool read_only)
+               {
+                       HttpSessionState session = null;
+                       using (IDataReader reader = GetReaderWithRetry (id)) {
                                if (!reader.Read ())
                                        return null;
 
@@ -172,58 +230,112 @@ namespace System.Web.SessionState {
                                session = new HttpSessionState (id, dict, sobjs, 100, false, config.CookieLess,
                                                SessionStateMode.SQLServer, read_only);
                                return session;
-                       } catch {
-                               throw;
                        }
                }
 
-               private void InsertSession (HttpSessionState session, int timeout)
+               void InsertSession (HttpSessionState session, int timeout)
                {
                        IDbCommand command = cnc.CreateCommand ();
                        IDataParameterCollection param;
 
-                       string insert = "INSERT INTO ASPStateTempSessions VALUES " +
-                       "(:SessionID, :Created, :Expires, :Timeout, :StaticObjectsData, :SessionData)";
-
-                       command.CommandText = insert;
+                       command.CommandText = insertCommand;
 
                        param = command.Parameters;
-                       param.Add (CreateParam (command, DbType.String, ":SessionID", session.SessionID));
-                       param.Add (CreateParam (command, DbType.DateTime, ":Created", DateTime.Now));
-                       param.Add (CreateParam (command, DbType.DateTime, ":Expires", Tommorow ()));
-                       param.Add (CreateParam (command, DbType.Int32, ":Timeout", timeout));
-                       param.Add (CreateParam (command, DbType.Binary, ":StaticObjectsData",
+                       param.Add (CreateParam (command, DbType.String, "SessionID", session.SessionID));
+                       param.Add (CreateParam (command, DbType.DateTime, "Created", DateTime.Now));
+                       param.Add (CreateParam (command, DbType.DateTime, "Expires", Tommorow ()));
+                       param.Add (CreateParam (command, DbType.Int32, "Timeout", timeout));
+                       param.Add (CreateParam (command, DbType.Binary, "StaticObjectsData",
                                                   session.StaticObjects.ToByteArray ()));
-                       param.Add (CreateParam (command, DbType.Binary, ":SessionData",
+                       param.Add (CreateParam (command, DbType.Binary, "SessionData",
                                                   session.SessionDictionary.ToByteArray ()));
 
                        command.ExecuteNonQuery ();
                }
 
-               private void UpdateSession (string id, SessionDictionary dict)
+               void InsertSessionWithRetry (HttpSessionState session, int timeout)
+               {
+                       try {
+                               InsertSession (session, timeout);
+                               return;
+                       } catch {
+                       }
+
+                       try {
+                               cnc.Close ();
+                       } catch {
+                       }
+
+                       cnc.Open ();
+                       InsertSession (session, timeout);
+               }
+
+               void UpdateSession (string id, SessionDictionary dict)
                {
                        IDbCommand command = cnc.CreateCommand ();
                        IDataParameterCollection param;
 
-                       string update = "UPDATE ASPStateTempSessions SET " +
-                       "SessionData = :SessionData WHERE SessionId = :SessionID";
-
-                       command.CommandText = update;
+                       command.CommandText = updateCommand;
 
                        param = command.Parameters;
-                       param.Add (CreateParam (command, DbType.String, ":SessionID", id));
-                       param.Add (CreateParam (command, DbType.Binary, ":SessionData",
+                       param.Add (CreateParam (command, DbType.String, "SessionID", id));
+                       param.Add (CreateParam (command, DbType.Binary, "SessionData",
                                                                dict.ToByteArray ()));
 
                        command.ExecuteNonQuery ();
                }
 
+               void UpdateSessionWithRetry (string id, SessionDictionary dict)
+               {
+                       try {
+                               UpdateSession (id, dict);
+                               return;
+                       } catch {
+                       }
+
+                       try {
+                               cnc.Close ();
+                       } catch {
+                       }
+
+                       cnc.Open ();
+                       UpdateSession (id, dict);
+               }
+
+               void DeleteSession (string id)
+               {
+                       IDbCommand command = cnc.CreateCommand ();
+                       IDataParameterCollection param;
+
+                       command.CommandText = deleteCommand;
+                       param = command.Parameters;
+                       param.Add (CreateParam (command, DbType.String, "SessionID", id));
+                       command.ExecuteNonQuery ();
+               }
+
+               void DeleteSessionWithRetry (string id)
+               {
+                       try {
+                               DeleteSession (id);
+                               return;
+                       } catch {
+                       }
+
+                       try {
+                               cnc.Close ();
+                       } catch {
+                       }
+
+                       cnc.Open ();
+                       DeleteSession (id);
+               }
+
                private IDataParameter CreateParam (IDbCommand command, DbType type,
                                string name, object value)
                {
                        IDataParameter result = command.CreateParameter ();
                        result.DbType = type;
-                       result.ParameterName = name;
+                       result.ParameterName = paramPrefix + name;
                        result.Value = value;
                        return result;
                }