DataHelper.cs :  » Bloggers » SubText » Subtext » Framework » Data » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Bloggers » SubText 
SubText » Subtext » Framework » Data » DataHelper.cs
#region Disclaimer/Info

///////////////////////////////////////////////////////////////////////////////////////////////////
// Subtext WebLog
// 
// Subtext is an open source weblog system that is a fork of the .TEXT
// weblog system.
//
// For updated news and information please visit http://subtextproject.com/
// Subtext is hosted at Google Code at http://code.google.com/p/subtext/
// The development mailing list is at subtext@googlegroups.com 
//
// This project is licensed under the BSD license.  See the License.txt file for more information.
///////////////////////////////////////////////////////////////////////////////////////////////////

#endregion

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Net;
using Subtext.Extensibility;
using Subtext.Extensibility.Interfaces;
using Subtext.Framework.Components;
using Subtext.Framework.Configuration;

//Need to remove Global.X calls ...just seems unclean
//Maybe create a another class formatter ...Format.Entry(ref Entry entry) 
//or, Instead of Globals.PostUrl(int id) --> Globals.PostUrl(ref Entry entry)
//...

namespace Subtext.Framework.Data{
    /// <summary>
    /// Contains helper methods for getting blog entries from the database 
    /// into objects such as <see cref="Entry" />
    /// </summary>
    public static class DataHelper
    {
        public static IEnumerable<T> ReadEnumerable<T>(this IDataReader reader, Func<IDataReader, T> map)
        {
            while(reader.Read())
            {
                yield return map(reader);
            }
        }

        public static IPagedCollection<T> ReadPagedCollection<T>(this IDataReader reader, Func<IDataReader, T> map)
        {
            var collection = new PagedCollection<T>(reader.ReadEnumerable(map).ToList());
            reader.NextResult();
            reader.Read();
            collection.MaxItems = reader.ReadValue<int>("TotalRecords");
            return collection;
        }

        public static T ReadObject<T>(this IDataReader reader, params string[] exclusionList) where T : new()
        {
            var item = new T();
            reader.ReadObject(item, exclusionList);
            return item;
        }

        public static T ReadObject<T>(this IDataReader reader, T item, params string[] exclusionList)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(item);
            foreach(PropertyDescriptor property in properties)
            {
                if(property.IsReadOnly)
                {
                    continue;
                }

                if(!property.PropertyType.IsReadablePropertyType())
                {
                    continue;
                }

                if(exclusionList != null && exclusionList.IsExcluded(property.Name))
                {
                    continue;
                }

                // We need to catch this exception in cases when we're upgrading and the column might not exist yet.
                // It'd be nice to have a cleaner way of doing this.
                try
                {
                    object value = reader[property.Name];
                    if(value != DBNull.Value)
                    {
                        if(property.PropertyType != typeof(Uri))
                        {
                            property.SetValue(item, value);    
                        }
                        else
                        {
                            var url = value as string;
                            if(!String.IsNullOrEmpty(url))
                            {
                                Uri uri;
                                if(Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri))
                                {
                                    property.SetValue(item, uri);
                                }
                            }
                        }
                    }
                }
                catch(IndexOutOfRangeException)
                {
                    if(typeof(T) != typeof(HostInfo))
                    {
                        throw;
                    }
                }
            }
            return item;
        }

        public static T ReadValue<T>(this IDataReader reader, string columnName)
        {
            return reader.ReadValue(columnName, default(T));
        }

        public static T ReadValue<T>(this IDataReader reader, string columnName, T defaultValue)
        {
            return reader.ReadValue(columnName, value => (T)value, defaultValue);
        }

        public static T ReadValue<T>(this IDataReader reader, string columnName, Func<object, T> map, T defaultValue)
        {
            try
            {
                object value = reader[columnName];
                if(value != null && value != DBNull.Value)
                {
                    return map(value);
                }
                return defaultValue;
            }
            catch(FormatException)
            {
                return defaultValue;
            }
            catch(IndexOutOfRangeException)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// Checks the value type and returns null if the 
        /// value is "null-equivalent".
        /// </summary>
        public static int? NullIfMinValue(this int value)
        {
            if(NullValue.IsNull(value))
            {
                return null;
            }
            return value;
        }

        public static DateTime? NullIfEmpty(this DateTime dateTime)
        {
            if(NullValue.IsNull(dateTime))
            {
                return null;
            }
            return dateTime;
        }

        public static Referrer ReadReferrer(IDataReader reader, Blog blog)
        {
            var refer = reader.ReadObject<Referrer>();
            refer.BlogId = blog.Id;
            return refer;
        }

        internal static ICollection<Entry> ReadEntryCollection(this IDataReader reader)
        {
            return reader.ReadEntryCollection(true /* buildLinks */);
        }

        internal static ICollection<Entry> ReadEntryCollection(this IDataReader reader, bool buildLinks)
        {
            return reader.ReadEntryCollection<Entry, List<Entry>>(r => r.ReadEnumerable(innerReader => innerReader.ReadEntry(buildLinks)).ToList());
        }

        internal static TCollection ReadEntryCollection<TEntry, TCollection>(this IDataReader reader, Func<IDataReader, TCollection> collectionFunc) where TCollection : ICollection<TEntry> where TEntry : Entry
        {
            var entries = collectionFunc(reader);
            if(entries.Count > 0 && reader.NextResult())
            {
                var categories = reader.ReadEnumerable(r => new { EntryId = r.ReadValue<int>("PostId"), Title = r.ReadValue<string>("Title") });
                entries.Accumulate(categories, entry => entry.Id, category => category.EntryId, (entry, category) => entry.Categories.Add(category.Title));
            }
            return entries;
        }

        internal static ICollection<TItem> ReadCollection<TItem>(this IDataReader reader, Func<IDataReader, TItem> map)
        {
            return reader.ReadEnumerable(map).ToList();
        }

        internal static ICollection<TItem> ReadCollection<TItem>(this IDataReader reader) where TItem : new()
        {
            return reader.ReadCollection(r => r.ReadObject<TItem>());
        }

        //Crappy. Need to clean up all of the entry references
        public static EntryStatsView ReadEntryStatsView(this IDataReader reader)
        {
            var entry = new EntryStatsView
            {
                PostType = ((PostType)reader.ReadValue<int>("PostType")),
                WebCount = reader.ReadValue("WebCount", 0),
                AggCount = reader.ReadValue("AggCount", 0),
                WebLastUpdated = reader.ReadValue<DateTime>("WebLastUpdated"),
                AggLastUpdated = reader.ReadValue<DateTime>("AggLastUpdated"),
                Author = reader.ReadValue<string>("Author"),
                Email = reader.ReadValue<string>("Email"),
                DateCreated = reader.ReadValue<DateTime>("DateCreated"),
                DateModified = reader.ReadValue<DateTime>("DateUpdated"),
                Id = reader.ReadValue<int>("ID"),
                Description = reader.ReadValue<string>("Description"),
                EntryName = reader.ReadValue<string>("EntryName"),
                FeedBackCount = reader.ReadValue<int>("FeedBackCount"),
                Body = reader.ReadValue<string>("Text"),
                Title = reader.ReadValue<string>("Title"),
                PostConfig = (PostConfig)(reader.ReadValue<int>("PostConfig")),
                DateSyndicated = reader.ReadValue<DateTime>("DateSyndicated")
            };

            return entry;
        }

        public static Entry ReadEntry(this IDataReader reader)
        {
            return ReadEntry(reader, true);
        }

        /// <summary>
        /// Only use this when loading a SINGLE entry from a reader.
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static Entry ReadEntryWithCategories(IDataReader reader)
        {
            Entry entry = reader.ReadEntry();
            if(reader.NextResult())
            {
                entry.Categories.AddRange(reader.ReadEnumerable(r => r.ReadValue<string>("Title")).Distinct(StringComparer.Ordinal));
            }
            return entry;
        }

        internal static FeedbackItem ReadFeedbackItem(this IDataReader reader, Entry entry)
        {
            var feedbackItem = new FeedbackItem((FeedbackType)reader.ReadValue<int>("FeedbackType"));
            ReadFeedbackItem(reader, feedbackItem);
            feedbackItem.Entry = entry;
            return feedbackItem;
        }

        internal static FeedbackItem ReadFeedbackItem(this IDataReader reader)
        {
            var feedbackItem = new FeedbackItem((FeedbackType)reader.ReadValue<int>("FeedbackType"));
            ReadFeedbackItem(reader, feedbackItem);
            return feedbackItem;
        }

        private static void ReadFeedbackItem(this IDataReader reader, FeedbackItem feedbackItem)
        {
            feedbackItem.Id = reader.ReadValue<int>("Id");
            feedbackItem.Title = reader.ReadValue<string>("Title");
            feedbackItem.Body = reader.ReadValue<string>("Body");
            feedbackItem.EntryId = reader.ReadValue<int>("EntryId");
            feedbackItem.Author = reader.ReadValue<string>("Author") ?? string.Empty;
            feedbackItem.IsBlogAuthor = reader.ReadValue<bool>("IsBlogAuthor");
            feedbackItem.Email = reader.ReadValue<string>("Email");
            feedbackItem.SourceUrl = ReadUri(reader, "Url");
            feedbackItem.FeedbackType = (FeedbackType)reader.ReadValue<int>("FeedbackType");
            feedbackItem.Status = (FeedbackStatusFlag)reader.ReadValue<int>("StatusFlag");
            feedbackItem.CreatedViaCommentApi = reader.ReadValue<bool>("CommentAPI");
            feedbackItem.Referrer = reader.ReadValue<string>("Referrer");
            feedbackItem.IpAddress = reader.ReadIpAddress("IpAddress");
            feedbackItem.UserAgent = reader.ReadValue<string>("UserAgent");
            feedbackItem.ChecksumHash = reader.ReadValue<string>("FeedbackChecksumHash");
            feedbackItem.DateCreated = reader.ReadValue<DateTime>("DateCreated");
            feedbackItem.DateModified = reader.ReadValue<DateTime>("DateModified");
            feedbackItem.ParentEntryName = reader.ReadValue<string>("ParentEntryName");
            feedbackItem.ParentDateCreated = reader.ReadValue<DateTime>("ParentEntryCreateDate");
            feedbackItem.ParentDateSyndicated = reader.ReadValue<DateTime>("ParentEntryDateSyndicated");
        }

        public static Entry ReadEntry(this IDataReader reader, bool buildLinks)
        {
            var entry = new Entry((PostType)reader.ReadValue<int>("PostType"), null);
            reader.ReadEntry(entry, buildLinks);
            return entry;
        }

        public static Entry ReadEntry(this IDataReader reader, Entry entry, bool buildLinks)
        {
            return reader.ReadEntry(entry, buildLinks, false);
        }

        public static Entry ReadEntry(this IDataReader reader, Entry entry, bool buildLinks, bool includeBlog)
        {
            entry.Author = reader.ReadValue<string>("Author");
            entry.Email = reader.ReadValue<string>("Email");
            entry.DateCreated = reader.ReadValue<DateTime>("DateCreated");
            entry.DateModified = reader.ReadValue<DateTime>("DateUpdated");

            entry.Id = reader.ReadValue<int>("ID");
            entry.Description = reader.ReadValue<string>("Description");
            entry.EntryName = reader.ReadValue<string>("EntryName");

            entry.FeedBackCount = reader.ReadValue("FeedBackCount", 0);
            entry.Body = reader.ReadValue<string>("Text");
            entry.Title = reader.ReadValue<string>("Title");
            entry.PostConfig = (PostConfig)(reader.ReadValue("PostConfig", (int)PostConfig.None));
            entry.DateSyndicated = reader.ReadValue<DateTime>("DateSyndicated");

            var withEnclosure = reader.ReadValue<bool>("EnclosureEnabled");
            if(withEnclosure)
            {
                entry.Enclosure = ReadEnclosure(reader);
            }

            if(includeBlog)
            {
                entry.Blog = ReadBlog(reader);
            }
            return entry;
        }

        public static Blog ReadBlog(this IDataReader reader)
        {
            return reader.ReadBlog(string.Empty);
        }

        public static Blog ReadBlog(this IDataReader reader, string prefix)
        {
            var info = new Blog
            {
                Author = reader.ReadValue<string>(prefix + "Author"),
                Id = reader.ReadValue<int>(prefix + "BlogId"),
                Email = reader.ReadValue<string>(prefix + "Email"),
                Password = reader.ReadValue<string>(prefix + "Password"),
                SubTitle = reader.ReadValue<string>(prefix + "SubTitle"),
                Title = reader.ReadValue<string>(prefix + "Title"),
                UserName = reader.ReadValue<string>(prefix + "UserName"),
                TimeZoneId = reader.ReadValue<string>(prefix + "TimeZoneId"),
                ItemCount = reader.ReadValue<int>(prefix + "ItemCount"),
                CategoryListPostCount = reader.ReadValue<int>(prefix + "CategoryListPostCount"),
                Language = reader.ReadValue<string>(prefix + "Language"),
                PostCount = reader.ReadValue<int>(prefix + "PostCount"),
                CommentCount = reader.ReadValue<int>(prefix + "CommentCount"),
                StoryCount = reader.ReadValue<int>(prefix + "StoryCount"),
                PingTrackCount = reader.ReadValue<int>(prefix + "PingTrackCount"),
                News = reader.ReadValue<string>(prefix + "News"),
                TrackingCode = reader.ReadValue<string>(prefix + "TrackingCode"),
                LastUpdated = reader.ReadValue(prefix + "LastUpdated", new DateTime(2003, 1, 1)),
                Host = reader.ReadValue<string>(prefix + "Host"),
                Subfolder = reader.ReadValue<string>(prefix + "Application"),
                Flag = (ConfigurationFlags)(reader.ReadValue<int>(prefix + "Flag")),
                Skin = new SkinConfig
                {
                    TemplateFolder = reader.ReadValue<string>(prefix + "Skin"),
                    SkinStyleSheet = reader.ReadValue<string>(prefix + "SkinCssFile"),
                    CustomCssText = reader.ReadValue<string>(prefix + "SecondaryCss")
                },
                MobileSkin = new SkinConfig
                {
                    TemplateFolder = reader.ReadValue<string>(prefix + "MobileSkin"),
                    SkinStyleSheet = reader.ReadValue<string>(prefix + "MobileSkinCssFile")
                },
                OpenIdUrl = reader.ReadValue<string>(prefix + "OpenIdUrl"),
                OpenIdServer = reader.ReadValue<string>(prefix + "OpenIdServer"),
                OpenIdDelegate = reader.ReadValue<string>(prefix + "OpenIdDelegate"),
                CardSpaceHash = reader.ReadValue<string>(prefix + "CardSpaceHash"),
                LicenseUrl = reader.ReadValue<string>(prefix + "LicenseUrl"),
                DaysTillCommentsClose = reader.ReadValue(prefix + "DaysTillCommentsClose", int.MaxValue),
                CommentDelayInMinutes = reader.ReadValue<int>(prefix + "CommentDelayInMinutes"),
                NumberOfRecentComments = reader.ReadValue<int>(prefix + "NumberOfRecentComments"),
                RecentCommentsLength = reader.ReadValue<int>(prefix + "RecentCommentsLength"),
                FeedbackSpamServiceKey = reader.ReadValue<string>(prefix + "AkismetAPIKey"),
                RssProxyUrl = reader.ReadValue<string>(prefix + "FeedBurnerName"),
                BlogGroupId = reader.ReadValue<int>(prefix + "BlogGroupId"),
                BlogGroupTitle = reader.ReadValue<string>(prefix + "BlogGroupTitle")
            };
            return info;
        }

        public static ICollection<ArchiveCount> ReadArchiveCount(IDataReader reader)
        {
            const string dateformat = "{0:00}/{1:00}/{2:0000}";
            var acc = new Collection<ArchiveCount>();
            while(reader.Read())
            {
                var ac = new ArchiveCount();
                string dt = string.Format(CultureInfo.InvariantCulture,
                                          dateformat,
                                          reader.ReadValue<int>("Month"),
                                          reader.ReadValue<int>("Day"),
                                          reader.ReadValue<int>("Year"));
                // FIX: BUG SF1423271 Archives Links
                DateTime parsedDate;
                if(
                    !DateTime.TryParseExact(dt, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal,
                                            out parsedDate))
                {
                    break;
                }

                ac.Date = parsedDate;
                ac.Count = reader.ReadValue<int>("Count");
                //TODO: This broke the unit tests: ac.Title = reader.ReadValue<string>("Title");
                //TODO: This broke the unit tests: ac.Id = reader.ReadValue<int>("Id");
                acc.Add(ac);
            }
            return acc;
        }

        public static Image ReadImage(this IDataReader reader)
        {
            return ReadImage(reader, false, false);
        }

        public static Image ReadImage(this IDataReader reader, bool includeBlog, bool includeCategory)
        {
            var image = reader.ReadObject<Image>("CategoryTitle", "LocalDirectoryPath");

            if(includeBlog)
            {
                image.Blog = reader.ReadBlog("Blog.");
            }
            if(includeCategory)
            {
                image.CategoryTitle = reader.ReadValue<string>("Category.Title");
            }
            return image;
        }

        public static IDictionary<string, int> ReadTags(IDataReader reader)
        {
            var tags = new SortedDictionary<string, int>();
            while(reader.Read())
            {
                tags.Add(
                    reader.ReadValue<string>("Name"),
                    reader.ReadValue<int>("TagCount"));
            }
            return tags;
        }

        private static bool IsExcluded(this IEnumerable<string> exclusionList, string propertyName)
        {
            return exclusionList.Any(excludedProperty => excludedProperty == propertyName);
        }

        private static bool IsReadablePropertyType(this Type t)
        {
            bool isReadable = t.IsPrimitive ||
                              t == typeof(DateTime) ||
                              t == typeof(string) ||
                              t == typeof(Uri);

            if(!isReadable)
            {
                //Maybe it's a nullable.
                Type underlyingType = Nullable.GetUnderlyingType(t);
                if(underlyingType != null)
                {
                    return IsReadablePropertyType(underlyingType);
                }
            }
            return isReadable;
        }

        /// <summary>
        /// Reads the string.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="columnName">Name of the coumn.</param>
        /// <returns></returns>
        public static IPAddress ReadIpAddress(this IDataReader reader, string columnName)
        {
            return reader.ReadValue(columnName, value => IPAddress.Parse((string)value), IPAddress.None);
        }

        /// <summary>
        /// Reads an URI from the database.
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static Uri ReadUri(this IDataReader reader, string columnName)
        {
            return reader.ReadValue(columnName, value => new Uri((string)value), null);
        }

        public static SqlParameter MakeInParam(string paramName, object value)
        {
            return new SqlParameter(paramName, value);
        }

        /// <summary>
        /// Make input param.
        /// </summary>
        public static SqlParameter MakeOutParam(string paramName, SqlDbType dbType, int size)
        {
            return MakeParam(paramName, dbType, size, ParameterDirection.Output, null);
        }

        /// <summary>
        /// Make stored procedure param.
        /// </summary>
        public static SqlParameter MakeParam(string paramName, SqlDbType dbType, Int32 size,
                                             ParameterDirection direction, object value)
        {
            SqlParameter param = size > 0 ? new SqlParameter(paramName, dbType, size) : new SqlParameter(paramName, dbType);

            param.Direction = direction;
            if(!(direction == ParameterDirection.Output && value == null))
            {
                param.Value = value;
            }

            return param;
        }

        // Expects that the caller will dispose of the reader.
        public static ICollection<LinkCategory> ReadLinkCategories(this IDataReader reader, bool includeLinks)
        {
            var categories = reader.ReadEnumerable(r => r.ReadLinkCategory()).ToList();
            
            if(includeLinks && reader.NextResult())
            {
                var links = reader.ReadEnumerable(r => r.ReadObject<Link>());
                categories.Accumulate(links, category => category.Id, link => link.CategoryId, (category, link) => category.Links.Add(link));
            }

            return categories;
        }

        public static LinkCategory ReadLinkCategory(this IDataReader reader)
        {
            var lc = new LinkCategory(reader.ReadValue<int>("CategoryId"), reader.ReadValue<string>("Title")) { IsActive = (bool)reader["Active"] };
            if(reader["CategoryType"] != DBNull.Value)
            {
                lc.CategoryType = (CategoryType)((byte)reader["CategoryType"]);
            }
            if(reader["Description"] != DBNull.Value)
            {
                lc.Description = reader.ReadValue<string>("Description");
            }
            lc.BlogId = reader["BlogId"] != DBNull.Value ? reader.ReadValue<int>("BlogId") : Config.CurrentBlog.Id;
            return lc;
        }

        public static Enclosure ReadEnclosure(this IDataReader reader)
        {
            var enclosure = new Enclosure
            {
                Id = reader.ReadValue<int>("EnclosureId"),
                Title = reader.ReadValue<string>("EnclosureTitle"),
                Url = reader.ReadValue<string>("EnclosureUrl"),
                MimeType = reader.ReadValue<string>("EnclosureMimeType"),
                Size = reader.ReadValue<long>("EnclosureSize"),
                EntryId = reader.ReadValue<int>("ID"),
                AddToFeed = reader.ReadValue<bool>("AddToFeed"),
                ShowWithPost = reader.ReadValue<bool>("ShowWithPost")
            };

            return enclosure;
        }
    }

    /// <summary>
    /// Sort direction.
    /// </summary>
    public enum SortDirection
    {
        None = 0,
        /// <summary>Sort ascending</summary>
        Ascending,
        /// <summary>Sort descending</summary>
        Descending
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.