using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Data.SqlTypes;
namespace dasBlog.Storage.SqlServer{
public interface ITextEntryStorageProvider : IStorageProvider<dasBlog.Storage.TextEntry> { }
public class TextEntryStorageProvider : ITextEntryStorageProvider, IInitStorageProvider
{
private dasBlogStorageSqlDataContext readContext;
private string connectionString;
private bool initialized;
public TextEntryStorageProvider()
{
}
public void Initialize(string initData)
{
if (string.IsNullOrEmpty(initData))
{
throw new ArgumentNullException("initData");
}
else
{
connectionString = initData;
// set the read context
readContext = new dasBlogStorageSqlDataContext(initData);
readContext.DeferredLoadingEnabled = false;
readContext.ObjectTrackingEnabled = false;
initialized = true;
}
}
private void EnsureInit()
{
lock (this)
{
if (!initialized)
{
Initialize(Properties.Settings.Default.dasBlogStorageSqlConnectionString);
}
}
}
public IEnumerable<dasBlog.Storage.TextEntry> Select(Moniker moniker, MonikerMatch contextMatch, QueryDescription query)
{
if (moniker == null) throw new ArgumentNullException("moniker");
EnsureInit();
if (query == null)
{
if (contextMatch == MonikerMatch.Exact)
{
return from TextEntry t in readContext.TextEntries
where t.ContextKey == moniker.ItemPath
orderby t.Created descending
select ToStorageTextEntry(t);
}
else
{
return from TextEntry t in readContext.TextEntries
where moniker.ToString() == t.ContextKey.Substring(0, moniker.ToString().Length)
orderby t.Created descending
select ToStorageTextEntry(t);
}
}
else
{
var args = new Dictionary<string, string>();
foreach (QueryArgument arg in query.Arguments)
{
args.Add(arg.Name, arg.Value);
}
if (query.QueryName == IdOnlyQueryDescription.Name)
{
if (contextMatch == MonikerMatch.Exact)
{
return from TextEntry t in readContext.TextEntries
where t.ContextKey == moniker.ItemPath
orderby t.Created descending
select new dasBlog.Storage.TextEntry
{
Id = new Moniker(new Moniker(t.ContextKey), t.Id.ToString()),
Title = t.Title,
Created = t.Created
};
}
else
{
return from TextEntry t in readContext.TextEntries
where moniker.ToString() == t.ContextKey.Substring(0, moniker.ToString().Length)
orderby t.Created descending
select new dasBlog.Storage.TextEntry
{
Id = new Moniker(new Moniker(t.ContextKey), t.Id.ToString()),
Title = t.Title,
Created = t.Created
};
}
}
else if (query.QueryName == DateRangeQueryDescription.Name)
{
DateTime @from =
args[DateRangeQueryDescription.FromArgument] != null ?
DateTime.Parse(args[DateRangeQueryDescription.FromArgument]).ToSqlRange() :
DateTimeTools.SqlMin;
DateTime @to =
args[DateRangeQueryDescription.ToArgument] != null ?
DateTime.Parse(args[DateRangeQueryDescription.ToArgument]).ToSqlRange() :
DateTimeTools.SqlMax;
if (contextMatch == MonikerMatch.Exact)
{
return from TextEntry t in readContext.TextEntries
where
t.ContextKey == moniker.ItemPath &&
t.Created < @to &&
t.Created > @from
orderby t.Created descending
select ToStorageTextEntry(t);
}
else
{
return from TextEntry t in readContext.TextEntries
where
moniker.ToString() == t.ContextKey.Substring(0, moniker.ToString().Length) &&
t.Created < @to &&
t.Created > @from
orderby t.Created descending
select ToStorageTextEntry(t);
}
}
else if (query.QueryName == TagQueryDescription.Name)
{
if (contextMatch == MonikerMatch.Exact)
{
return from TaggedEntry te in readContext.TaggedEntries
from TextEntry tx in readContext.TextEntries
where
tx.ContextKey == te.ContextKey &&
tx.Id == te.Id &&
tx.ContextKey == moniker.ItemPath &&
te.Tag == (string)args[TagQueryDescription.TagArgument]
orderby te.TextEntry.Created descending
select ToStorageTextEntry(tx);
}
else
{
return from TaggedEntry te in readContext.TaggedEntries
from TextEntry tx in readContext.TextEntries
where
tx.ContextKey == te.ContextKey &&
tx.Id == te.Id &&
moniker.ToString() == tx.ContextKey.Substring(0, moniker.ToString().Length) &&
te.Tag == (string)args[TagQueryDescription.TagArgument]
orderby te.TextEntry.Created descending
select ToStorageTextEntry(tx);
}
}
else if (query.QueryName == ContentQueryDescription.Name)
{
if (contextMatch == MonikerMatch.Exact)
{
return from TextEntry t in readContext.TextEntries
where
t.ContextKey == moniker.ToString() &&
t.Content.Contains((string)args[ContentQueryDescription.SnippetArgument])
orderby t.Created descending
select ToStorageTextEntry(t);
}
else
{
return from TextEntry t in readContext.TextEntries
where
moniker.ToString() == t.ContextKey.Substring(0, moniker.ToString().Length) &&
t.Content.Contains((string)args[ContentQueryDescription.SnippetArgument])
orderby t.Created descending
select ToStorageTextEntry(t);
}
}
else
{
if ( query.QueryName == null )
throw new ArgumentException("query",
string.Format("Query name cannot be null"));
else
throw new ArgumentOutOfRangeException("query",
string.Format("Unsupported query '{0}'", query.QueryName));
}
}
}
public dasBlog.Storage.TextEntry Get(Moniker itemId)
{
if (itemId == null) throw new ArgumentNullException("itemId");
EnsureInit();
var result = from TextEntry t in readContext.TextEntries
where t.ContextKey == itemId.ItemPath &&
t.Id == itemId.ItemId
select ToStorageTextEntry(t);
if (result == null || result.Count() == 0)
{
return null;
}
else
{
return result.First();
}
}
public void Delete(Moniker itemId)
{
if (itemId == null) throw new ArgumentNullException("itemId");
EnsureInit();
using (var writeContext = new dasBlogStorageSqlDataContext(connectionString))
{
writeContext.TaggedEntries.RemoveAll<TaggedEntry>(from TaggedEntry t in writeContext.TaggedEntries
where
t.ContextKey == itemId.ItemPath &&
t.Id == itemId.ItemId
select t);
writeContext.TextEntries.RemoveAll<TextEntry>(from TextEntry t in writeContext.TextEntries
where t.ContextKey == itemId.ItemPath &&
t.Id == itemId.ItemId
select t);
writeContext.SubmitChanges();
}
}
public Moniker Store(Moniker moniker, dasBlog.Storage.TextEntry item)
{
Moniker result = null;
if (moniker == null) throw new ArgumentNullException("contextId");
if (item == null) throw new ArgumentNullException("item");
EnsureInit();
using (var writeContext = new dasBlogStorageSqlDataContext(connectionString))
{
if (moniker.ItemId != null)
{
var existingEntry = writeContext.TextEntries.Single((textEntry) => textEntry.ContextKey == moniker.ItemPath &&
textEntry.Id == moniker.ItemId);
if (existingEntry != null)
{
UpdateFromStorageTextEntry(existingEntry, item);
if (item.Categories.Count > 0)
{
UpdateTags(item, writeContext, existingEntry);
}
else
{
existingEntry.TaggedEntries.Clear();
existingEntry.Tags = "";
}
result = moniker;
}
else
{
var newEntry = FromStorageTextEntry(item);
newEntry.ContextKey = moniker.ItemPath;
newEntry.Id = Guid.NewGuid().ToString();
writeContext.TextEntries.Add(newEntry);
if (item.Categories.Count > 0)
{
UpdateTags(item, writeContext, newEntry);
}
else
{
newEntry.Tags = "";
}
result = moniker;
}
}
else
{
var newEntry = FromStorageTextEntry(item);
newEntry.ContextKey = moniker.ItemPath;
newEntry.Id = Guid.NewGuid().ToString();
writeContext.TextEntries.Add(newEntry);
if (item.Categories.Count > 0)
{
UpdateTags(item, writeContext, newEntry);
}
else
{
newEntry.Tags = "";
}
result = new Moniker(moniker, newEntry.Id);
}
writeContext.SubmitChanges();
return result;
}
}
private static void UpdateTags(dasBlog.Storage.TextEntry item, dasBlogStorageSqlDataContext dc, TextEntry existingEntry)
{
existingEntry.TaggedEntries.AddRange(
from string tag
in item.Categories
where existingEntry.TaggedEntries.Count((te) => tag == te.Tag) == 0
select new TaggedEntry { Tag = tag }
);
IEnumerable<TaggedEntry> entriesToRemove = from TaggedEntry te in existingEntry.TaggedEntries
where !item.Categories.Contains(te.Tag)
select te;
foreach (TaggedEntry te2 in entriesToRemove)
{
existingEntry.TaggedEntries.Remove(te2);
dc.TaggedEntries.Remove(te2);
}
existingEntry.Tags = item.CategoriesAsString;
}
dasBlog.Storage.TextEntry ToStorageTextEntry(TextEntry t)
{
return new dasBlog.Storage.TextEntry
{
Content = t.Content,
ContentType = t.ContentType,
CategoriesAsString = t.Tags,
Created = t.Created.ToSqlRange(),
LastChange = t.LastUpdate.ToSqlRangeOrMin(),
Id = new Moniker(new Moniker(t.ContextKey), t.Id.ToString()),
Summary = t.Summary,
Title = t.Title,
Language = t.Languages,
AllowComments = t.AllowComments,
Featured = t.Featured,
Parent = t.Parent,
Published = t.Published,
Reference = t.Reference,
Syndicated = t.Syndicated,
Author = new AuthorDescription{ Url = t.AuthorUrl, Email = t.AuthorEmail, DisplayName = t.AuthorName }
};
}
TextEntry FromStorageTextEntry(dasBlog.Storage.TextEntry item)
{
Moniker uri = item.Id != null ? item.Id : null;
return new TextEntry
{
Content = item.Content,
ContentType = item.ContentType.Truncate(10),
LastUpdate = item.Created,
Created = item.Created,
Published = item.Published,
Languages = item.Language,
Title = item.Title.Truncate(150),
Summary = item.Summary.Truncate(300),
AllowComments = item.AllowComments,
Featured = item.Featured,
Parent = item.Parent.Truncate(255),
Reference = item.Reference,
Syndicated = item.Syndicated,
AuthorEmail = item.Author!=null?item.Author.Email:null,
AuthorUrl = item.Author!=null?item.Author.Url:null,
AuthorName = item.Author != null ? item.Author.DisplayName : null,
ContextKey = uri != null ? uri.ItemPath : null,
Id = uri != null && uri.ItemId != null ? uri.ItemId : null
};
}
void UpdateFromStorageTextEntry(TextEntry textEntry, dasBlog.Storage.TextEntry item)
{
textEntry.Content = item.Content;
textEntry.ContentType = item.ContentType.Truncate(10);
textEntry.LastUpdate = item.Created;
textEntry.Created = item.Created;
textEntry.Published = item.Published;
textEntry.Languages = item.Language;
textEntry.Title = item.Title.Truncate(150);
textEntry.Summary = item.Summary.Truncate(300);
textEntry.AllowComments = item.AllowComments;
textEntry.Featured = item.Featured;
textEntry.Parent = item.Parent.Truncate(255);
textEntry.Reference = item.Reference;
textEntry.Syndicated = item.Syndicated;
textEntry.AuthorEmail = item.Author!=null?item.Author.Email:null;
textEntry.AuthorUrl = item.Author!=null?item.Author.Url:null;
textEntry.AuthorName = item.Author != null ? item.Author.DisplayName : null;
}
public IEnumerable<PropertyAggregate> Aggregate(Moniker contextId, MonikerMatch contextMatch, string propertyName)
{
if ( propertyName == null ) throw new ArgumentNullException("propertyName");
if ( contextId == null ) throw new ArgumentNullException("contextId");
EnsureInit();
if (string.Compare(propertyName, "tag", true) == 0)
{
if (contextMatch == MonikerMatch.Exact)
{
return
from te in readContext.TaggedEntries
where te.ContextKey == contextId.ItemPath
group te by te.Tag into tags
orderby tags.Key
select new PropertyAggregate { Value = tags.Key, Count = tags.Count() };
}
else
{
return
from te in readContext.TaggedEntries
where contextId.ToString() == te.ContextKey.Substring(0, contextId.ToString().Length)
group te by te.Tag into tags
orderby tags.Key
select new PropertyAggregate { Value = tags.Key, Count = tags.Count() };
}
}
else if (string.Compare(propertyName, "datecreated", true) == 0)
{
if (contextMatch == MonikerMatch.Exact)
{
return
from t in readContext.TextEntries
where t.ContextKey == contextId.ItemPath
group t by t.Created.Date
into dates
orderby dates.Key
select new PropertyAggregate { Value = dates.Key.ToString(), Count = dates.Count() };
}
else
{
return
from t in readContext.TextEntries
where contextId.ToString() == t.ContextKey.Substring(0, contextId.ToString().Length)
group t by t.Created.Date
into dates
orderby dates.Key
select new PropertyAggregate { Value = dates.Key.ToString(), Count = dates.Count() };
}
}
else
{
throw new ArgumentOutOfRangeException("propertyName",
string.Format("Unsupported property '{0}'", propertyName));
}
}
}
}
|