Got ChildrenAsTable working as extensions on DynamicDocument with supporting unit tests.

Have updated the ChildrenAsTable code for Node as well to use the same base code, this should
also fix some issues with generating a datatable correctly when a content type is changed, previously
the cache was not cleared for Alias to name mapping.
This commit is contained in:
Shannon Deminick
2012-09-20 12:42:43 +07:00
parent 6e4929b84d
commit a48b996571
38 changed files with 1296 additions and 205 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
@@ -16,14 +17,12 @@ namespace Umbraco.Core
/// </summary>
internal static class DataTableExtensions
{
private static readonly Hashtable AliasToNames = new Hashtable();
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
/// <summary>
/// Creates a DataTable with the specified alias and columns and uses a callback to populate the headers.
/// </summary>
/// <param name="alias"></param>
/// <param name="tableAlias"></param>
/// <param name="getHeaders"></param>
/// <param name="rowData"> </param>
/// <returns></returns>
@@ -32,36 +31,27 @@ namespace Umbraco.Core
/// DynamicDocument extensions for legacy reasons.
/// </remarks>
public static DataTable GenerateDataTable(
string alias,
string tableAlias,
Func<string, IEnumerable<KeyValuePair<string, string>>> getHeaders,
Func<IEnumerable<Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>>> rowData)
{
var dt = new DataTable(alias);
var dt = new DataTable(tableAlias);
//get the standard column headers from the standard data (not user data)
var tableData = rowData();
var standardColHeaders = tableData.SelectMany(x => x.Item1).Select(x => x.Key).Distinct();
var userPropColHeaders = new List<string>();
// get user property column headers
var propertyHeaders = GetPropertyHeaders(alias, getHeaders);
var ide = propertyHeaders.GetEnumerator();
while (ide.MoveNext())
{
userPropColHeaders.Add(ide.Value.ToString());
}
//get all row data
var tableData = rowData().ToArray();
//now add all the columns, standard val headers first, then user val headers
foreach (var dc in standardColHeaders.Union(userPropColHeaders).Select(c => new DataColumn(c)))
//get all headers
var propertyHeaders = GetPropertyHeaders(tableAlias, getHeaders);
foreach(var h in propertyHeaders)
{
dt.Columns.Add(dc);
dt.Columns.Add(new DataColumn(h.Value));
}
//add row data
foreach(var r in rowData())
foreach(var r in tableData)
{
dt.PopulateRow(
(Hashtable)AliasToNames[alias],
propertyHeaders,
r.Item1,
r.Item2);
}
@@ -101,29 +91,16 @@ namespace Umbraco.Core
));
}
private static Hashtable GetPropertyHeaders(string alias, Func<string, IEnumerable<KeyValuePair<string, string>>> getHeaders)
{
using (var l = new UpgradeableReadLock(Lock))
{
if (AliasToNames.ContainsKey(alias))
return (Hashtable)AliasToNames[alias];
l.UpgradeToWriteLock();
var headers = getHeaders(alias);
var def = new Hashtable();
foreach (var pt in headers)
def.Add(pt.Key, pt.Value);
AliasToNames.Add(alias, def);
return def;
}
private static IDictionary<string, string> GetPropertyHeaders(string alias, Func<string, IEnumerable<KeyValuePair<string, string>>> getHeaders)
{
var headers = getHeaders(alias);
var def = headers.ToDictionary(pt => pt.Key, pt => pt.Value);
return def;
}
private static void PopulateRow(
this DataTable dt,
IDictionary aliasesToNames,
IDictionary<string, string> aliasesToNames,
IEnumerable<KeyValuePair<string, object>> standardVals,
IEnumerable<KeyValuePair<string, object>> userPropertyVals)
{
@@ -134,7 +111,7 @@ namespace Umbraco.Core
}
foreach (var p in userPropertyVals.Where(p => p.Value != null))
{
dr[aliasesToNames[p.Key].ToString()] = p.Value;
dr[aliasesToNames[p.Key]] = p.Value;
}
dt.Rows.Add(dr);
}