//Website: http://www.kowitz.net //Author : Brendan Kowitz using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Collections; using System.Data; using System.Web; using System.ComponentModel; using MarkItUp.SingleUserBlog.Common; using MarkItUp.SingleUserBlog.Services; using System.Web.Caching; namespace kowitz.SingleUserBlog.Services { #region Security class public class SecurityImport { internal static bool UserCanViewPost(Post post) { if (post == null || post.IsApproved) return true; // if the post is not authorized then the user must be the blog owner return SecurityHelper.CurrentUserIsBlogOwner; } } #endregion public class DataReaderBlogDataProvider : BlogDataProvider { private SQLiteDataHandler _SqlDL = null; public DataReaderBlogDataProvider() { _SqlDL = new SQLiteDataHandler(); } public override bool Authenticate(string username, string password) { if (password == Globals.UserPassword && username == Globals.UserLoginName) { return true; } return false; } // Feedback Methods public override void DeleteFeedback(string feedbackId) { FeedbackItem tmp = LoadFeedback(feedbackId); using (_SqlDL = new SQLiteDataHandler()) { _SqlDL.DeleteFeedback(feedbackId); } CacheHelper.InvalidateCache("Feedback." + feedbackId); CacheHelper.InvalidateCache("FeedbackByPost." + tmp.PostId); } public override FeedbackItem LoadFeedback(string feedbackItemId) { return LoadFeedback(feedbackItemId, false); } public override FeedbackItem LoadFeedback(string feedbackItemId, bool forceRefresh) { string cacheKey = "Feedback." + feedbackItemId; FeedbackItem obj = (FeedbackItem)HttpRuntime.Cache[cacheKey]; if (obj == null) { obj = new FeedbackItem(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.LoadFeedback(feedbackItemId); if (dr.Read()) { Fill(dr, obj); } dr.Close(); } CacheHelper.Insert(cacheKey, obj); } return obj; } public override FeedbackItemCollection ListFeedbackByPost(string postId) { string cacheKey = "FeedbackByPost."+postId; FeedbackItemCollection list = (FeedbackItemCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new FeedbackItemCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListFeedbackByPost(postId); while (dr.Read()) { FeedbackItem obj = new FeedbackItem(); Fill(dr, obj); list.Add(obj); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override void SaveFeedback(FeedbackItem item) { TimeZoneInformation info = TimeZoneInformation.FromName(BlogConfigurationSettings.TimeZoneName); DateTime dt1 = info.CurrentDateTime; item.DateCreated = dt1; item.DateModified = dt1; using (_SqlDL = new SQLiteDataHandler()) { _SqlDL.SaveFeedback(item); } CacheHelper.InvalidateCache("FeedbackByPost." + item.PostId); } // Post Methods public override void DeletePost(string postId) { if (!SecurityHelper.CurrentUserIsBlogOwner) throw new ApplicationException("You do not have permission to delete this post item."); using (_SqlDL = new SQLiteDataHandler()) { _SqlDL.DeletePost(postId); } CacheHelper.InvalidateCache("ListPostsByAll"); } public override Post LoadPost(string postId) { return LoadPost(postId,false); } public override Post LoadPost(string postId, bool forceRefresh) { string cacheKey = "Post."+postId; Post obj = (Post)HttpRuntime.Cache[cacheKey]; if (obj == null || forceRefresh) { obj = new Post(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.LoadPost(postId); if (dr.Read()) { Fill(dr, obj); } dr.Close(); } CacheHelper.Insert(cacheKey, obj); } return obj; } public override PostCollection ListPostsByAll() { string cacheKey = "ListPostsByAll"; PostCollection list = (PostCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListPostsByAll(); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); if (SecurityImport.UserCanViewPost(obj)) list.Add(obj); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override PostCollection ListPostsByLatest(int countOfPosts) { string cacheKey = "ListPostsByLatest." + countOfPosts; PostCollection list = (PostCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListPostsByLatest(countOfPosts); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); if (SecurityImport.UserCanViewPost(obj)) list.Add(obj); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override PostCollection ListPostsByCategory(string categoryid) { string cacheKey = "ListPostsByCategory." + categoryid; PostCollection list = (PostCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListPostsByCategory(categoryid); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); if (SecurityImport.UserCanViewPost(obj)) list.Add(obj); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override IList ListPostByRssFeed(int countOfPosts) { return ListPostsByLatest(countOfPosts); } public override Post SavePost(Post item) { if (!SecurityHelper.CurrentUserIsBlogOwner) throw new ApplicationException("You do not have permission to save post entries."); TimeZoneInformation info = TimeZoneInformation.FromName(BlogConfigurationSettings.TimeZoneName); DateTime dt1 = info.CurrentDateTime; bool isNew = false; bool newID = false; Post obj = new Post(); using (_SqlDL = new SQLiteDataHandler()) { if (item.Id == null || item.Id.ToString() == string.Empty) { newID = true; if (item.DateCreated == DateTime.MinValue) item.DateCreated = dt1; isNew = true; } try { int.Parse(item.Id); } catch (Exception) { newID = true; } if(newID) item.Id = _SqlDL.NewPostID().ToString(); if (item.DateModified == DateTime.MinValue) item.DateModified = dt1; if (isNew) { _SqlDL.InsertPost(item); } else { _SqlDL.UpdatePost(item); } _SqlDL.Commit(); IDataReader dr = _SqlDL.LoadPost(item.Id); if (dr.Read()) { Fill(dr, obj); } dr.Close(); } CacheHelper.InvalidateCache("ListPostsByAll"); return obj; } public override PostCollection ListPostsByMonth(int year, int month) { string monthStr = (month.ToString().Length==1?"0":"") + month + "," + year; PostCollection list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.PostsByMonthString(monthStr); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); list.Add(obj); } dr.Close(); } return list; } public override int GetCountOfPostsByMonth(int year, int month) { int retval = 0; string[] split; foreach (string str in PostsByMonthlyArchive()) { split = str.Split(','); if (month == int.Parse(split[0]) && year == int.Parse(split[1])) retval = int.Parse(split[2]); } return retval; } public override DateTime GetEarliestPostDate() { TimeZoneInformation info = TimeZoneInformation.FromName(BlogConfigurationSettings.TimeZoneName); DateTime dt; using (_SqlDL = new SQLiteDataHandler()) { dt = _SqlDL.EarliestPostDate(); } return info.FromUniversalTime(dt); } public override void SavePostCategories(string postId, string[] categoryIds) { using (_SqlDL = new SQLiteDataHandler()) { _SqlDL.DeletePostCategories(postId); _SqlDL.Commit(); foreach (string str in categoryIds) { _SqlDL.SavePostCategory(postId,str); } CacheHelper.InvalidateCache("ListCategoriesByPost." + postId); } } // Category Methods public override void DeleteCategory(string categoryId) { using (_SqlDL = new SQLiteDataHandler()) { _SqlDL.DeleteCategory(categoryId); } UpdateXMLCategories(); } public override CategoryCollection ListCategories() { string cacheKey = "ListCategories"; CategoryCollection list = (CategoryCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new CategoryCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListCategories(); while (dr.Read()) { Category category = new Category(); Fill(dr, category); list.Add(category); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override CategoryCollection ListCategoriesByPost(string postId) { string cacheKey = "ListCategoriesByPost." + postId; CategoryCollection list = (CategoryCollection)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new CategoryCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.ListCategoriesByPost(postId); while (dr.Read()) { Category category = new Category(); Fill(dr, category); list.Add(category); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list; } public override Category LoadCategory(string categoryId) { return LoadCategory(categoryId,false); } public override Category LoadCategory(string categoryId, bool forceRefresh) { string cacheKey = "Category." + categoryId; Category obj = (Category)HttpRuntime.Cache[cacheKey]; if (obj == null || forceRefresh) { obj = new Category(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.LoadCategory(categoryId); if (dr.Read()) { Fill(dr, obj); } dr.Close(); } CacheHelper.Insert(cacheKey, obj); } return obj; } public override Category SaveCategory(Category item) { using (_SqlDL = new SQLiteDataHandler()) { if (!SecurityHelper.CurrentUserIsBlogOwner) throw new ApplicationException("You do not have permission to save categies."); TimeZoneInformation info = TimeZoneInformation.FromName(BlogConfigurationSettings.TimeZoneName); DateTime dt1 = info.CurrentDateTime; bool isNew = false; if (item.Id == null || item.Id.ToString() == string.Empty) { item.DateCreated = dt1; isNew = true; } if (item.DateModified == DateTime.MinValue) item.DateModified = dt1; if (isNew) { _SqlDL.InsertCategory(item); } else { _SqlDL.UpdateCategory(item); } } UpdateXMLCategories(); return item; } public PostCollection SearchPosts(string searchPhrase, int limit) { PostCollection list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.SearchPosts(searchPhrase, limit); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); list.Add(obj); } dr.Close(); } return list; } public string[] PostsByMonthlyArchive() { string cacheKey = "sqlite_MonthlyArchiveList"; ArrayList list = (ArrayList)HttpRuntime.Cache[cacheKey]; if (list == null) { list = new ArrayList(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.PostsByMonthlyArchive(); while (dr.Read()) { string obj = dr.GetValue(0).ToString() + "," + dr.GetValue(1).ToString(); list.Add(obj); } dr.Close(); } CacheHelper.Insert(cacheKey, list); } return list.ToArray(typeof(string)) as string[]; } public PostCollection PostsByMonthString(string monthStr) { PostCollection list = new PostCollection(); using (_SqlDL = new SQLiteDataHandler()) { IDataReader dr = _SqlDL.PostsByMonthString(monthStr); while (dr.Read()) { Post obj = new Post(); Fill(dr, obj); list.Add(obj); } dr.Close(); } return list; } public virtual void Fill(IDataReader reader, object obj) { int curOrdinal; foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) { curOrdinal = reader.GetOrdinal(prop.Name); if (curOrdinal > -1) { try { if(prop.PropertyType == typeof(DateTime)) { TimeZoneInformation info = TimeZoneInformation.FromName(BlogConfigurationSettings.TimeZoneName); prop.SetValue(obj, info.FromUniversalTime((DateTime)Convert.ChangeType(reader.GetValue(curOrdinal), prop.PropertyType))); } else { prop.SetValue(obj, Convert.ChangeType(reader.GetValue(curOrdinal), prop.PropertyType)); } } catch (Exception) { //throw err; System.Diagnostics.Trace.WriteLine("Error setting property: "+prop.Name); } } else //does not exist in datareader { //TODO: Set to null System.Diagnostics.Trace.WriteLine("Property does not exist in reader: " + prop.Name); } } } /// /// Update Categories for the XML transformation on the main page /// public virtual void UpdateXMLCategories() { XmlDocument doc = FileHelper.GetCategories(Globals.BlogIndexDataFolderPath); XmlNode node; doc.RemoveAll(); node = doc.CreateElement("Categories"); doc.AppendChild(node); CacheHelper.InvalidateCache("ListCategories"); foreach(Category c in ListCategories()) { node = doc.CreateElement("Category"); c.Persist(node); doc.DocumentElement.AppendChild(node); } FileHelper.SaveCategories(Globals.BlogIndexDataFolderPath, doc); } } }