/// <summary> /// GetSessionStoreItem is called by both the GetItem and /// GetItemExclusive methods. GetSessionStoreItem retrieves the </summary> /// session data from the data source. If the lockRecord parameter<param name="lockRecord"></param> /// is true (in the case of GetItemExclusive), then GetSessionStoreItem<param name="context"></param> /// locks the record and sets a new LockId and LockDate.<param name="id"></param> private SessionStateStoreData GetSessionStoreItem(Boolean lockRecord, HttpContext context, String id, out Boolean 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; // SQLite database connection. IDbConnection conn = new SQLiteConnection(_connectionString); // SQLiteCommand for database commands. IDbCommand cmd = null; // DataReader to read database record. IDataReader reader = null; // DateTime to check if current session item is expired. DateTime expires; // String to hold serialized SessionStateItemCollection. String serializedItems = ""; // True if a record is found in the database. Boolean foundRecord = false; // True if the returned session item is expired and needs to be deleted. Boolean deleteData = false; // Timeout value from the data store. int timeout = 0; try { conn.Open(); // lockRecord is true when called from GetItemExclusive and // false when called from GetItem. // Obtain a lock if possible. Ignore the record if it is expired. if (lockRecord) { cmd = conn.CreateCommand(); cmd.CommandText = "UPDATE Sessions SET Locked = @Locked, LockDate = @LockDate WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Locked = @Locked AND Expires > @Expires"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Locked", DbType.Boolean, true)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@LockDate", DbType.DateTime, DateTime.Now)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, ApplicationName)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Locked", DbType.Int32, false)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Expires", DbType.DateTime, DateTime.Now)); if (cmd.ExecuteNonQuery() == 0) { // No record was updated because the record was locked or not found. locked = true; } else { // The record was updated. locked = false; } } // Retrieve the current session item information. cmd = conn.CreateCommand(); cmd.CommandText = "SELECT Expires, SessionItems, LockId, LockDate, Flags, Timeout FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, ApplicationName)); // Retrieve session item data from the data source. reader = cmd.ExecuteReader(CommandBehavior.SingleRow); while (reader.Read()) { expires = reader.GetDateTime(0); if (expires < DateTime.Now) { // The record was expired. Mark it as not locked. locked = false; // The session was expired. Mark the data for deletion. deleteData = true; } else { foundRecord = true; } serializedItems = reader.GetString(1); lockId = reader.GetInt32(2); lockAge = DateTime.Now.Subtract(reader.GetDateTime(3)); actionFlags = (SessionStateActions)reader.GetInt32(4); timeout = reader.GetInt32(5); } reader.Close(); // If the returned session item is expired, // delete the record from the data source. if (deleteData) { cmd = conn.CreateCommand(); cmd.CommandText = "DELETE FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, ApplicationName)); cmd.ExecuteNonQuery(); } // The record was not found. Ensure that locked is false. if (!foundRecord) { 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; cmd = conn.CreateCommand(); cmd.CommandText = "UPDATE Sessions SET LockId = @LockId, Flags = 0 WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@LockId", DbType.Int32, lockId)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, 255, ApplicationName)); cmd.ExecuteNonQuery(); // If the actionFlags parameter is not InitializeItem, // deserialize the stored SessionStateItemCollection. if (actionFlags == SessionStateActions.InitializeItem) { item = CreateNewStoreData(context, (int)_config.Timeout.TotalMinutes); } else { item = Deserialize(context, serializedItems, timeout); } } } catch (SQLiteException e) { if (WriteExceptionsToEventLog) { WriteToEventLog(e, "GetSessionStoreItem"); throw new ProviderException(_exceptionMessage); } else { throw e; } } finally { if (reader != null) { reader.Close(); } conn.Close(); } return(item); }
// SessionStateProviderBase.SetAndReleaseItemExclusive public override void SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) { // Serialize the SessionStateItemCollection as a String. String sessItems = Serialize((SessionStateItemCollection)item.Items); IDbConnection conn = new SQLiteConnection(_connectionString); IDbCommand cmd; IDbCommand deleteCmd = null; if (newItem) { // SQLiteCommand to clear an existing expired session if it exists. deleteCmd = conn.CreateCommand(); deleteCmd.CommandText = "DELETE FROM Sessions WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND Expires < @Expires"; deleteCmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); deleteCmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, 255, ApplicationName)); deleteCmd.Parameters.Add(SQLiteHelper.CreateParameter("@Expires", DbType.DateTime, DateTime.Now)); // SQLiteCommand to insert the new session item. cmd = conn.CreateCommand(); cmd.CommandText = "INSERT INTO Sessions (SessionId, ApplicationName, Created, Expires, LockDate, LockId, Timeout, Locked, SessionItems, Flags) Values(@SessionId, @ApplicationName, @Created, @Expires, @LockDate, @LockId, @Timeout, @Locked, @SessionItems, @Flags)"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, 255, ApplicationName)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Created", DbType.DateTime, DateTime.Now)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Expires", DbType.DateTime, DateTime.Now.AddMinutes((Double)item.Timeout))); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@LockDate", DbType.DateTime, DateTime.Now)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@LockId", DbType.Int32, 0)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Timeout", DbType.Int32, item.Timeout)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Locked", DbType.Boolean, false)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionItems", DbType.String, sessItems.Length, sessItems)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Flags", DbType.Int32, 0)); } else { // SQLiteCommand to update the existing session item. cmd = conn.CreateCommand(); cmd.CommandText = "UPDATE Sessions SET Expires = @Expires, SessionItems = @SessionItems, Locked = @Locked WHERE SessionId = @SessionId AND ApplicationName = @ApplicationName AND LockId = @LockId"; cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Expires", DbType.DateTime, DateTime.Now.AddMinutes((Double)item.Timeout))); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionItems", DbType.String, sessItems.Length, sessItems)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@Locked", DbType.Boolean, false)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@SessionId", DbType.String, 80, id)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@ApplicationName", DbType.String, ApplicationName)); cmd.Parameters.Add(SQLiteHelper.CreateParameter("@LockId", DbType.Int32, lockId)); } try { conn.Open(); if (deleteCmd != null) { deleteCmd.ExecuteNonQuery(); } cmd.ExecuteNonQuery(); } catch (SQLiteException e) { if (WriteExceptionsToEventLog) { WriteToEventLog(e, "SetAndReleaseItemExclusive"); throw new ProviderException(_exceptionMessage); } else { throw e; } } finally { conn.Close(); } }