} // End of the UpdateLockIdAndFlags method #endregion #region Get methods /// <summary> /// Get one session based on id /// </summary> /// <param name="id">The id</param> /// <param name="applicationName">The application name</param> /// <returns>A reference to a session post</returns> public static WebsiteSession GetOneById(string id, string applicationName) { // Create the post to return WebsiteSession post = null; // Create the connection and the sql statement string connection = Tools.GetConnectionString(); string sql = "SELECT * FROM dbo.website_sessions WHERE id = @id AND application_name = @application_name;"; // The using block is used to call dispose automatically even if there is a exception. using (SqlConnection cn = new SqlConnection(connection)) { // The using block is used to call dispose automatically even if there is a exception. using (SqlCommand cmd = new SqlCommand(sql, cn)) { // Add a parameters cmd.Parameters.AddWithValue("@id", id); cmd.Parameters.AddWithValue("@application_name", applicationName); // Create a MySqlDataReader SqlDataReader reader = null; // The Try/Catch/Finally statement is used to handle unusual exceptions in the code to // avoid having our application crash in such cases. try { // Open the connection. cn.Open(); // Fill the reader with one row of data. reader = cmd.ExecuteReader(); // Loop through the reader as long as there is something to read and add values while (reader.Read()) { post = new WebsiteSession(reader); } } catch (Exception e) { // We do not want to throw an exception string exMessage = e.Message; } finally { // Call Close when done reading to avoid memory leakage. if (reader != null) reader.Close(); } } } // Return the post return post; } // End of the GetOneById method
} // End of the ReleaseItemExclusive method /// <summary> /// Reset the timeout for the session /// </summary> public override void ResetItemTimeout(HttpContext context, string id) { // Create a session post WebsiteSession session = new WebsiteSession(); session.id = id; session.application_name = this.applicationName; session.expires_date = DateTime.UtcNow.AddMinutes(this.sessionStateConfiguration.Timeout.TotalMinutes); // Update the expiration date WebsiteSession.UpdateExpirationDate(session); } // End of the ResetItemTimeout method
/// <summary> /// This method runs in the background /// </summary> public static void Run() { while(true) { // Sleep for 30 minutes 1800000 Thread.Sleep(1800000); // Do the work WebsiteSession.DeleteAllExpired(); } } // End of the Run method
} // End of the SetAndReleaseItemExclusive method /// <summary> /// Release an session item /// </summary> public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { // Create a webshop session post WebsiteSession session = new WebsiteSession(); session.id = id; session.application_name = this.applicationName; session.lock_id = (Int32)lockId; session.expires_date = DateTime.UtcNow.AddMinutes(this.sessionStateConfiguration.Timeout.TotalMinutes); session.locked = false; // Update the lock WebsiteSession.Unlock(session); } // End of the ReleaseItemExclusive method
} // End of the constructor #endregion #region Insert methods /// <summary> /// Add one session post /// </summary> /// <param name="post">A reference to a session post</param> public static void Add(WebsiteSession post) { // Create the connection and the sql statement string connection = Tools.GetConnectionString(); string sql = "INSERT INTO dbo.website_sessions (id, application_name, created_date, expires_date, " + "lock_date, lock_id, timeout_limit, locked, session_items, flags) " + "VALUES (@id, @application_name, @created_date, @expires_date, @lock_date, @lock_id, " + "@timeout_limit, @locked, @session_items, @flags);"; // The using block is used to call dispose automatically even if there are an exception. using (SqlConnection cn = new SqlConnection(connection)) { // The using block is used to call dispose automatically even if there are an exception. using (SqlCommand cmd = new SqlCommand(sql, cn)) { // Add parameters cmd.Parameters.AddWithValue("@id", post.id); cmd.Parameters.AddWithValue("@application_name", post.application_name); cmd.Parameters.AddWithValue("@created_date", post.created_date); cmd.Parameters.AddWithValue("@expires_date", post.expires_date); cmd.Parameters.AddWithValue("@lock_date", post.lock_date); cmd.Parameters.AddWithValue("@lock_id", post.lock_id); cmd.Parameters.AddWithValue("@timeout_limit", post.timeout_limit); cmd.Parameters.AddWithValue("@locked", post.locked); cmd.Parameters.AddWithValue("@session_items", post.session_items); cmd.Parameters.AddWithValue("@flags", post.flags); // The Try/Catch/Finally statement is used to handle unusual exceptions in the code to // avoid having our application crash in such cases try { // Open the connection cn.Open(); // Execute the insert cmd.ExecuteNonQuery(); } catch (Exception e) { // We do not want to throw an exception string exMessage = e.Message; } } } } // End of the Add method
} // End of the UpdateExpirationDate method /// <summary> /// Lock a session /// </summary> /// <param name="post">A reference to a session post</param> public static Int32 Lock(WebsiteSession post) { // Create the int to return Int32 postsAffected = 0; // Create the connection and the sql statement string connection = Tools.GetConnectionString(); string sql = "UPDATE dbo.website_sessions SET lock_date = @lock_date, locked = @locked " + "WHERE id = @id AND application_name = @application_name AND locked = 0 AND expires_date > @expires_date;"; // The using block is used to call dispose automatically even if there are an exception. using (SqlConnection cn = new SqlConnection(connection)) { // The using block is used to call dispose automatically even if there are an exception. using (SqlCommand cmd = new SqlCommand(sql, cn)) { // Add parameters cmd.Parameters.AddWithValue("@id", post.id); cmd.Parameters.AddWithValue("@application_name", post.application_name); cmd.Parameters.AddWithValue("@expires_date", post.expires_date); cmd.Parameters.AddWithValue("@lock_date", post.lock_date); cmd.Parameters.AddWithValue("@locked", post.locked); // The Try/Catch/Finally statement is used to handle unusual exceptions in the code to // avoid having our application crash in such cases. try { // Open the connection. cn.Open(); // Execute the update postsAffected = cmd.ExecuteNonQuery(); } catch (Exception e) { // We do not want to throw an exception string exMessage = e.Message; } } } // Return the int return postsAffected; } // End of the Lock method
} // End of the Initialize method #endregion #region Add methods /// <summary> /// Create an uninitialized item /// </summary> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { // Create a session post WebsiteSession session = new WebsiteSession(); session.id = id; session.application_name = this.applicationName; session.created_date = DateTime.UtcNow; session.expires_date = DateTime.UtcNow.AddMinutes((Double)timeout); session.lock_date = DateTime.UtcNow; session.lock_id = 0; session.timeout_limit = timeout; session.locked = false; session.session_items = ""; session.flags = 1; // Add the session WebsiteSession.Add(session); } // End of the CreateUninitializedItem method
} // End of the SetItemExpireCallback method /// <summary> /// Set and realease a session post /// </summary> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { // Serialize the SessionStateItemCollection as a string. string sessItems = Serialize((SessionStateItemCollection)item.Items); // Create a session WebsiteSession session = new WebsiteSession(); session.id = id; session.application_name = this.applicationName; session.created_date = DateTime.UtcNow; session.expires_date = DateTime.UtcNow.AddMinutes((Double)item.Timeout); session.lock_date = DateTime.UtcNow; session.lock_id = 0; session.timeout_limit = item.Timeout; session.locked = false; session.session_items = sessItems; session.flags = 0; if (newItem == true) { // Delete the session if it exists WebsiteSession.DeleteOnId(id, this.applicationName); // Add the session WebsiteSession.Add(session); } else { // Update session values session.lock_id = (Int32)lockId; // Update the session WebsiteSession.UpdateWithLockId(session); } } // End of the SetAndReleaseItemExclusive method
} // End of the Lock method /// <summary> /// Unlock a session /// </summary> /// <param name="post">A reference to a session post</param> public static void Unlock(WebsiteSession post) { // Create the connection and the sql statement string connection = Tools.GetConnectionString(); string sql = "UPDATE dbo.website_sessions SET expires_date = @expires_date, locked = @locked " + "WHERE id = @id AND application_name = @application_name AND lock_id = @lock_id;"; // The using block is used to call dispose automatically even if there are an exception. using (SqlConnection cn = new SqlConnection(connection)) { // The using block is used to call dispose automatically even if there are an exception. using (SqlCommand cmd = new SqlCommand(sql, cn)) { // Add parameters cmd.Parameters.AddWithValue("@id", post.id); cmd.Parameters.AddWithValue("@application_name", post.application_name); cmd.Parameters.AddWithValue("@lock_id", post.lock_id); cmd.Parameters.AddWithValue("@expires_date", post.expires_date); cmd.Parameters.AddWithValue("@locked", post.locked); // The Try/Catch/Finally statement is used to handle unusual exceptions in the code to // avoid having our application crash in such cases. try { // Open the connection. cn.Open(); // Execute the update cmd.ExecuteNonQuery(); } catch (Exception e) { // We do not want to throw an exception string exMessage = e.Message; } } } } // End of the Unlock method
} // End of the Deserialize method #endregion #region Delete methods /// <summary> /// Remove a session item /// </summary> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { // Delete the session post WebsiteSession.DeleteOnId(id, this.applicationName, (int)lockId); } // End of the RemoveItem method
} // End of the GetItemExclusive method /// <summary> /// Get a session store item /// </summary> private SessionStateStoreData GetSessionStoreItem(bool lockRecord, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags) { // Initial values for return value and out parameters SessionStateStoreData item = null; lockAge = TimeSpan.Zero; lockId = null; locked = false; actionFlags = 0; // String to hold serialized SessionStateItemCollection. string serializedItems = ""; // True if a record is found in the database. bool foundRecord = false; // True if the returned session item is expired and needs to be deleted. bool deleteData = false; // Timeout value from the data store. int timeout = 0; // Create a session WebsiteSession session = new WebsiteSession(); if (lockRecord == true) { // Update the session session.id = id; session.application_name = this.applicationName; session.expires_date = DateTime.UtcNow; session.lock_date = DateTime.UtcNow; session.locked = true; // Lock the session Int32 postsAffected = WebsiteSession.Lock(session); // Set the locked variable locked = postsAffected == 0 ? true : false; } // Get the current session session = WebsiteSession.GetOneById(id, this.applicationName); if (session != null) { if (session.expires_date < DateTime.UtcNow) { locked = false; deleteData = true; } else { foundRecord = true; } // Set data serializedItems = session.session_items; lockId = session.lock_id; lockAge = DateTime.UtcNow.Subtract(session.lock_date); actionFlags = (SessionStateActions)session.flags; timeout = session.timeout_limit; } // If the returned session item is expired, // delete the record from the data source. if (deleteData) { WebsiteSession.DeleteOnId(id, this.applicationName); } // The record was not found. Ensure that locked is false. if (foundRecord == false) { locked = false; } // If the record was found and you obtained a lock, then set // the lockId, clear the actionFlags, // and create the SessionStateStoreItem to return. if (foundRecord && !locked) { lockId = (int)lockId + 1; // Update the lock id and flags WebsiteSession.UpdateLockIdAndFlags(id, this.applicationName, (Int32)lockId); // If the actionFlags parameter is not InitializeItem, deserialize the stored SessionStateItemCollection. if (actionFlags == SessionStateActions.InitializeItem) item = CreateNewStoreData(context, (Int32)this.sessionStateConfiguration.Timeout.TotalMinutes); else item = Deserialize(context, serializedItems, timeout); } // Return the session item return item; } // End of the GetSessionStoreItem method