Skip to content

Commit

Permalink
Date fixes and boolean fix
Browse files Browse the repository at this point in the history
  • Loading branch information
base33 committed Jan 27, 2016
1 parent 43bc46f commit 8da9e49
Show file tree
Hide file tree
Showing 17 changed files with 1,597 additions and 37 deletions.
Binary file modified Blog/bin/Blog.dll
Binary file not shown.
Binary file modified Blog/bin/Blog.pdb
Binary file not shown.
Binary file modified Blog/bin/Umbraco.Examine.Linq.dll
Binary file not shown.
Binary file modified Blog/bin/Umbraco.Examine.Linq.pdb
Binary file not shown.
Binary file modified Blog/obj/Debug/Blog.csprojResolveAssemblyReference.cache
Binary file not shown.
Binary file modified Blog/obj/Debug/Blog.dll
Binary file not shown.
Binary file modified Blog/obj/Debug/Blog.pdb
Binary file not shown.
Binary file modified Umbraco.Examine.Linq.Sandbox/App_Data/Umbraco.sdf
Binary file not shown.
1,441 changes: 1,441 additions & 0 deletions Umbraco.Examine.Linq.Sandbox/Umbraco.Examine.Linq.Sandbox.csproj

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions Umbraco.Examine.Linq.Sandbox/Views/BlogOverview.cshtml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
@using ConcreteContentTypes.Core.Extensions
@using UmbracoNS = Umbraco;
@using UmbracoNS = Umbraco
@using Umbraco.Examine.Linq.Extensions

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage

@{
Layout = "Master.cshtml";

var CurrentPage = (Umbraco.Core.Models.IPublishedContent)base.CurrentPage;

var results = new Umbraco.Examine.Linq.Index<Umbraco.Examine.Linq.Sandbox.Models.Content.BlogPost>(new Umbraco.Examine.Linq.Sandbox.Mapper.ConcreteMapper<Umbraco.Examine.Linq.Sandbox.Models.Content.BlogPost>())
.Where(c => c.CreateDate < DateTime.Now);
}

<div role="content">
Expand All @@ -15,13 +19,14 @@
<div class="container">

<div class="row">
@foreach (var post in new UmbracoNS.Examine.Linq.Sandbox.Repositories.BlogRepository().GetAllBlogPosts())
@*foreach (var post in new UmbracoNS.Examine.Linq.Sandbox.Repositories.BlogRepository().GetAllBlogPosts())*@
@foreach (var post in results)
{
<div class="col-sm-6">
<div class="content equal">
<a href="@post.Url">
<div class="date">@post.Author.Name @post.CreateDate.ToLongDateString()</div>
<h2>@post.Name</h2>
<div class="date">@post.Author.Name @post.CreateDate.ToLongDateString() @post.CreateDate.ToString("HH:mm:ss")</div>
<h2>@post.Name @post.Author.Id</h2>
<p>@Umbraco.Truncate(post.Introduction, 240, true)</p>
</a>
</div>
Expand Down
Binary file not shown.
125 changes: 102 additions & 23 deletions Umbraco.Examine.Linq/ExpressionTreeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ protected override System.Linq.Expressions.Expression VisitBinaryExpression(Syst
currentPart.Append("eq");
break;
case ExpressionType.NotEqual:
currentPart.Append("ne");
inverseMode = true;
break;

Expand Down Expand Up @@ -156,65 +157,97 @@ protected override Expression VisitConstantExpression(ConstantExpression express
if(expression.Value is string)
{
value = expression.Value.ToString();
if (value.Contains(' '))
value = string.Format("\"{0}\"", value);
operation = currentPart.ToString().Substring(currentPart.Length - 2);
if (operation == "eq" || operation == "ne")
{
if (value.Contains(' '))
value = string.Format("\"{0}\"", value);
}
else
{
operation = "";
}
}
else if (expression.Value is string[])
value = string.Join(" ", (string[])expression.Value);
else if (expression.Value is IEnumerable<string>)
value = string.Join(" ", (IEnumerable<string>)expression.Value);
else if (expression.Value is DateTime)
{
var formattedDateTime = ((DateTime)expression.Value).ToString("yyyyMMddHHmmssfff", CultureInfo.InvariantCulture);//((DateTime)expression.Value).ToString("o");
string fieldName = currentPart.ToString().Substring(0, currentPart.Length - 3); //-3 to remove colon

string minRange = shouldFormatLegacyDate(fieldName) || true ? "00000000000000000" : formatDateTime(fieldName, DateTime.MinValue);
string maxRange = shouldFormatLegacyDate(fieldName) || true ? "99999999999999999" : formatDateTime(fieldName, DateTime.MaxValue);

operation = currentPart.ToString().Substring(currentPart.Length - 2);

if (operation == "eq")
{
value = formattedDateTime;
var formattedDateTime = formatDateTime(fieldName, (DateTime)expression.Value);
value = $"\"{formattedDateTime}\"";
}
else if (operation == "ne")
{
string fieldName = currentPart.ToString().Substring(0, currentPart.Length - 2);
var formattedDateTime = formatDateTime("createDate", (DateTime)expression.Value, true);
//we will do a < and then >
operation = "gt";
handleRangeOperation(formattedDateTime, "\\-99999999999999999", "99999999999999999", operation, ref value);
handleRangeOperation(formattedDateTime, minRange, maxRange, operation, ref value);

//we want to now create the greater than expression
value += " OR " + fieldName;
operation = "lt";
handleRangeOperation(formattedDateTime, "\\-99999999999999999", "99999999999999999", operation, ref value);
formattedDateTime = formatDateTime(fieldName, (DateTime)expression.Value);
handleRangeOperation(formattedDateTime, minRange, maxRange, operation, ref value);
}
else
{
handleRangeOperation(formattedDateTime, "\\-99999999999999999", "99999999999999999", operation, ref value);
var formattedDateTime = formatDateTime(fieldName, (DateTime)expression.Value);
if (operation == "gt")
{
formattedDateTime = formatDateTime(fieldName, (DateTime)expression.Value, true);
handleRangeOperation(formattedDateTime, minRange, maxRange, operation, ref value);
}
else
handleRangeOperation(formattedDateTime, minRange, maxRange, operation, ref value);
}
}
else if(expression.Value is int || expression.Value is double)
{
var formattedInt = expression.Value is double ? (Convert.ToInt64((double)expression.Value)).ToString() : ((int)expression.Value).ToString();
operation = currentPart.ToString().Substring(currentPart.Length - 2);
if(operation == "eq")
{
var formattedInt = expression.Value is double ? (Convert.ToInt64((double)expression.Value)).ToString() : ((int)expression.Value).ToString();
value = formattedInt;
}
else if (operation == "ne")
{
var formattedGt = expression.Value is double ? (Convert.ToInt64((double)expression.Value - 1)).ToString() : ((int)expression.Value - 1).ToString();
var formattedLt = expression.Value is double ? (Convert.ToInt64((double)expression.Value + 1)).ToString() : ((int)expression.Value + 1).ToString();
string fieldName = currentPart.ToString().Substring(0, currentPart.Length - 2);
//we will do a < and then >
operation = "gt";
handleRangeOperation(formattedInt, "\\-99999999999999999", "99999999999999999", operation, ref value);
handleRangeOperation(formattedGt, "\\-99999999999999999", "99999999999999999", operation, ref value);

//we want to now create the greater than expression
value += " OR " + fieldName;
operation = "lt";
handleRangeOperation(formattedInt, "\\-99999999999999999", "99999999999999999", operation, ref value);
handleRangeOperation(formattedLt, "\\-99999999999999999", "99999999999999999", operation, ref value);
}
else
{
string formattedInt = "";
if(operation == "gt")
formattedInt = expression.Value is double ? (Convert.ToInt64((double)expression.Value - 1)).ToString() : ((int)expression.Value - 1).ToString();
else if(operation == "lt")
formattedInt = expression.Value is double ? (Convert.ToInt64((double)expression.Value + 1)).ToString() : ((int)expression.Value + 1).ToString();
handleRangeOperation(formattedInt, "\\-99999999999999999", "99999999999999999", operation, ref value);
}
}
else if (expression.Value is bool || expression.Value is Boolean)
value = ((bool)expression.Value) ? "1" : "0";
{
operation = currentPart.ToString().Substring(currentPart.Length - 2);
value = ((bool)expression.Value) && !inverseMode ? "1" : "0";
}
else
value = expression.Value.ToString();

Expand All @@ -235,7 +268,7 @@ protected override Expression VisitMethodCallExpression(MethodCallExpression exp
{
case "Contains":
bracketsEnabled = false;
currentPart.Append(inverseMode ? "-" : "+");
currentPart.Append(inverseMode ? "-" : "");
VisitExpression(expression.Object);
if(expression.Arguments.Count == 3)
{
Expand Down Expand Up @@ -297,29 +330,48 @@ protected override Expression VisitMethodCallExpression(MethodCallExpression exp
}
bracketsEnabled = true;
break;
case "IsWithinRange":
//in this instance, the first argument is an expression to the value,
//so we will disable brackets and visit the expression
bracketsEnabled = false;
DateTime fromDate = (DateTime)((ConstantExpression)expression.Arguments[1]).Value;
DateTime toDate = (DateTime)((ConstantExpression)expression.Arguments[2]).Value;
VisitExpression(expression.Arguments[0]);
var fieldName = currentPart.ToString().Split(':')[0];
//below we offset the date by a minute to be inclusive of the dates being filtered. Lucene doesn't include the min and max in the results
currentPart.AppendFormat("[{0} TO {1}]", formatDateTime("", fromDate.AddMinutes(-1), true), formatDateTime(fieldName, toDate.AddMinutes(1)));
bracketsEnabled = true;
break;
case "StartsWith":
bracketsEnabled = false;
VisitExpression(expression.Object);
currentPart.Append("^");
VisitExpression(expression.Arguments[0]);
bracketsEnabled = true;
break;
case "Equals":
bracketsEnabled = false;
VisitExpression(expression.Object);
VisitExpression(expression.Arguments[0]);
bracketsEnabled = true;
break;
case "Boost":
bracketsEnabled = false;
VisitExpression(expression.Arguments[0]);
VisitExpression(expression.Object);
addEndBracket();
//addEndBracket();
currentPart.AppendFormat("^{0}", expression.Arguments[1]);
bracketsEnabled = false;
break;
case "Fuzzy":
bracketsEnabled = false;
fuzzy = (double)((ConstantExpression)expression.Arguments[1]).Value;
if(expression.Arguments.Any())
if (expression.Arguments.Any())
VisitExpression(expression.Arguments[0]);
VisitExpression(expression.Object);
fuzzy = 0;
bracketsEnabled = false;
break;
case "Equals":
bracketsEnabled = false;
VisitExpression(expression.Object);
VisitExpression(expression.Arguments[0]);
bracketsEnabled = true;
break;
}

query.Append(currentPart);
Expand All @@ -329,6 +381,35 @@ protected override Expression VisitMethodCallExpression(MethodCallExpression exp
return expression;
}

protected string formatDateTime(string fieldName, DateTime date, bool isFrom = false)
{

return shouldFormatLegacyDate(fieldName)
? toDateLegacy(date)
: isFrom ? toDateFromFormat(date) : toDateISO8601(date);
}

protected bool shouldFormatLegacyDate(string fieldName)
{
var legacyDateTimeFields = new[] { "createDate", "updateDate" };
return legacyDateTimeFields.Contains(fieldName);
}

protected string toDateISO8601(DateTime date)
{
return date.ToString("yyyy-MM-ddTHH:mm:ss");
}

protected string toDateLegacy(DateTime date)
{
return date.ToString("yyyyMMddHHmmssfff", CultureInfo.InvariantCulture);
}

protected string toDateFromFormat(DateTime date)
{
return date.ToString("yyyy-MM-ddTHHmmssfff");
}

protected bool handleRangeOperation(string formattedValue, string defaultMinValue, string defaultMaxValue, string operation, ref string value)
{
switch (operation)
Expand All @@ -337,14 +418,12 @@ protected bool handleRangeOperation(string formattedValue, string defaultMinValu
value += string.Format("[{0} TO {1}]", defaultMinValue, formattedValue);
break;
case "lt":
formattedValue = (Int64.Parse(formattedValue) - 1).ToString();//-1 on the formattedValue to do less than
value += string.Format("[{0} TO {1}]", defaultMinValue, formattedValue);
break;
case "ge":
value += string.Format("[{0} TO {1}]", formattedValue, defaultMaxValue);
break;
case "gt":
formattedValue = (Int64.Parse(formattedValue) + 1).ToString();//-1 on the formattedValue to do less than
value += string.Format("[{0} TO {1}]", formattedValue, defaultMaxValue);
break;
default: //is equals
Expand Down
8 changes: 4 additions & 4 deletions Umbraco.Examine.Linq/Extensions/ClassTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Umbraco.Examine.Linq.Extensions
{
public static class ClassTypes
{
//public static DateTime Boost(this DateTime value, int boost)
//{
// return value;
//}
public static bool IsWithinRange(this DateTime value, DateTime from, DateTime to)
{
return value > from && value < to;
}
}
}
4 changes: 2 additions & 2 deletions Umbraco.Examine.Linq/Index.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ namespace Umbraco.Examine.Linq
public class Index<T> : QueryableBase<T>
{
public Index(IMapper<T> mapper)
: base(new DefaultQueryProvider(typeof(Index<>), QueryParser.CreateDefault(), new Executor<T>(new UmbracoSearch("ExternalSearcher"), mapper)))
: base(new DefaultQueryProvider(typeof(Index<>), QueryParser.CreateDefault(), new Executor<T>(new LuceneSearch("ExternalSearcher"), mapper)))
{

}

public Index(string indexName = "ExternalSearcher", IMapper<T> mapper = null)
: base(new DefaultQueryProvider(typeof(Index<>), QueryParser.CreateDefault(), new Executor<T>(new UmbracoSearch(indexName), mapper)))
: base(new DefaultQueryProvider(typeof(Index<>), QueryParser.CreateDefault(), new Executor<T>(new LuceneSearch(indexName), mapper)))
{

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@

namespace Umbraco.Examine.Linq.SearchProviders
{
public class UmbracoSearch : ISearcher
public class ExamineSearch : ISearcher
{
protected string IndexName { get; set; }

public static Dictionary<string, ISearchCriteria> searchQueryCache { get; set; }

static UmbracoSearch()
static ExamineSearch()
{
searchQueryCache = new Dictionary<string, ISearchCriteria>();
}

public UmbracoSearch(string indexName)
public ExamineSearch(string indexName)
{
IndexName = indexName;
}
Expand Down
34 changes: 34 additions & 0 deletions Umbraco.Examine.Linq/SearchProviders/LuceneSearch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Examine;
using Examine.LuceneEngine.Providers;
using Examine.SearchCriteria;

namespace Umbraco.Examine.Linq.SearchProviders
{
public class LuceneSearch : ISearcher
{
protected string IndexName { get; set; }

public static Dictionary<string, ISearchCriteria> searchQueryCache { get; set; }

static LuceneSearch()
{
searchQueryCache = new Dictionary<string, ISearchCriteria>();
}

public LuceneSearch(string indexName)
{
IndexName = indexName;
}

public IEnumerable<SearchResult> Search(string query)
{
LuceneSearcher searcher = ExamineManager.Instance.SearchProviderCollection[IndexName] as LuceneSearcher;
return searcher.Search(searcher.CreateSearchCriteria().RawQuery(query)).ToList();
}
}
}
3 changes: 2 additions & 1 deletion Umbraco.Examine.Linq/Umbraco.Examine.Linq.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@
<Compile Include="Models\Result.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryModelVisitor.cs" />
<Compile Include="SearchProviders\UmbracoSearch.cs" />
<Compile Include="SearchProviders\ExamineSearch.cs" />
<Compile Include="SearchProviders\LuceneSearch.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
Expand Down

0 comments on commit 8da9e49

Please sign in to comment.