Skip to content
Browse files

Refactored results into view model and save query

  • Loading branch information...
1 parent 382d9ed commit 70c1e74c89a3f99245d35b5f42b24bbd37e4a66d @dlidstrom committed Mar 5, 2012
View
3 .gitignore
@@ -30,4 +30,5 @@ _ReSharper*/
.packages
Words.Web/App_Data/words.txt
-packages/
+packages/
+Words.Web/Words.Web.Publish.xml
View
48 Words.Web/Controllers/HomeController.cs
@@ -1,22 +1,52 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-using System.Web.Mvc;
-
-namespace Words.Web.Controllers
+namespace Words.Web.Controllers
{
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Web.Mvc;
+ using Words.Web.Models;
+ using Words.Web.ViewModels;
+
public class HomeController : Controller
{
+ /// <summary>
+ /// See http://forums.asp.net/t/1671805.aspx/1.
+ /// </summary>
+ /// <param name="q"></param>
+ /// <returns></returns>
public ActionResult Index(string q)
{
if (q == null)
return View();
+ ResultsViewModel results;
+ double millis = 0;
+ int nodes = 0;
if (string.IsNullOrWhiteSpace(q))
- return View(Enumerable.Empty<Words.Match>().ToList());
+ results = new ResultsViewModel(Enumerable.Empty<Words.Match>(), 0);
+ else
+ {
+ var sw = Stopwatch.StartNew();
+ var matches = MvcApplication.WordFinder.Matches(q, 2);
+ sw.Stop();
+ millis = 1000.0 * sw.ElapsedTicks / Stopwatch.Frequency;
+ nodes = MvcApplication.WordFinder.Nodes;
+ results = new ResultsViewModel(matches, millis);
+ }
+
+ // save query
+ using (var session = MvcApplication.DocumentStore.OpenSession())
+ {
+ session.Store(new Query
+ {
+ Text = q,
+ Nodes = nodes,
+ ElapsedMilliseconds = millis
+ });
+
+ session.SaveChanges();
+ }
- return View(MvcApplication.WordFinder.Matches(q, 2));
+ return View(results);
}
}
}
View
63 Words.Web/Global.asax.cs
@@ -1,22 +1,30 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-using System.Web.Mvc;
-using System.Web.Routing;
-using System.IO;
-using System.Text;
-
-namespace Words.Web
+namespace Words.Web
{
+ using System;
+ using System.IO;
+ using System.Text;
+ using System.Web;
+ using System.Web.Mvc;
+ using System.Web.Routing;
+ using Raven.Client;
+ using Raven.Client.Document;
+ using Raven.Client.Embedded;
+
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
-
public class MvcApplication : HttpApplication
{
+#if DEBUG
+ private static readonly bool isDebug = true;
+#else
+ private static readonly bool isDebug = false;
+#endif
private static WordFinder wordFinder;
+ private static IDocumentStore documentStore;
- public static WordFinder WordFinder
+ public static bool IsDebug { get { return isDebug; } }
+
+ public static Words.WordFinder WordFinder
{
get
{
@@ -34,6 +42,29 @@ public static WordFinder WordFinder
}
}
+ public static IDocumentStore DocumentStore
+ {
+ get
+ {
+ if (documentStore == null)
+ {
+ if (MvcApplication.IsDebug)
+ documentStore = new DocumentStore { ConnectionStringName = "RavenDB" };
+ else
+ {
+ documentStore = new EmbeddableDocumentStore
+ {
+ DataDirectory = Path.Combine(AppDomain.CurrentDomain.GetData("DataDirectory").ToString(), "Database")
+ };
+ }
+
+ documentStore.Initialize();
+ }
+
+ return documentStore;
+ }
+ }
+
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
@@ -44,11 +75,9 @@ public static void RegisterRoutes(RouteCollection routes)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
- "Default", // Route name
- "{controller}/{action}/{id}", // URL with parameters
- new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
- );
-
+ name: "Default",
+ url: "{controller}/{action}/{id}",
+ defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
protected void Application_Start()
View
14 Words.Web/Models/Query.cs
@@ -0,0 +1,14 @@
+namespace Words.Web.Models
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ public class Query
+ {
+ public string Text { get; set; }
+ public int Nodes { get; set; }
+ public double ElapsedMilliseconds { get; set; }
+ }
+}
View
24 Words.Web/ViewModels/ResultsViewModel.cs
@@ -0,0 +1,24 @@
+namespace Words.Web.ViewModels
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ public class ResultsViewModel
+ {
+ public ResultsViewModel(IEnumerable<Match> matches, double elapsedMilliseconds)
+ {
+ Words = matches.Where(m => m.Type == MatchType.Word).Select(m => m.Value).ToList();
+ Anagrams = matches.Where(m => m.Type == MatchType.Anagram).Select(m => m.Value).ToList();
+ Near = matches.Where(m => m.Type == MatchType.Near).Select(m => m.Value).ToList();
+ ElapsedMilliseconds = elapsedMilliseconds;
+ }
+
+ public int Count { get { return Words.Count + Anagrams.Count + Near.Count; } }
+ public double ElapsedMilliseconds { get; set; }
+ public List<string> Words { get; private set; }
+ public List<string> Anagrams { get; private set; }
+ public List<string> Near { get; private set; }
+ }
+}
View
55 Words.Web/Views/Home/Index.cshtml
@@ -1,7 +1,7 @@
-@model List<Words.Match>
+@model ResultsViewModel
@{
- ViewBag.Title = "Index";
+ ViewBag.Title = "Krysshjälpen";
}
<h2>Sök</h2>
@@ -24,36 +24,47 @@
@if (Model != null)
{
- if (Model.Count == 0)
+ <p>Sökningen tog @(string.Format("{0:F2} ms", Model.ElapsedMilliseconds)).
+ @if (Model.Count == 0)
{
- <p>Hittade 0 resultat.</p>
+ <text>Hittade 0 resultat.</text>
}
else
{
- <p>Hittade @Model.Count resultat:</p>
+ <text>Hittade @Model.Count resultat:</text>
}
-
- <h3>Ord</h3>
- <ul>
- @foreach (var item in Model.Where(m => m.Type == Words.MatchType.Word))
- {
- <li>@item.Value</li>
+ </p>
+
+ if (Model.Words.Count > 0)
+ {
+ <h3>Ord</h3>
+ <ul>
+ @foreach (var item in Model.Words)
+ {
+ <li>@item</li>
+ }
+ </ul>
}
- </ul>
- <h3>Anagram</h3>
- <ul>
- @foreach (var item in Model.Where(m => m.Type == Words.MatchType.Anagram))
+ if (Model.Anagrams.Count > 0)
{
- <li>@item.Value</li>
+ <h3>Anagram</h3>
+ <ul>
+ @foreach (var item in Model.Anagrams)
+ {
+ <li>@item</li>
+ }
+ </ul>
}
- </ul>
- <h3>Nära</h3>
- <ul>
- @foreach (var item in Model.Where(m => m.Type == Words.MatchType.Near))
+ if (Model.Near.Count > 0)
{
- <li>@item.Value</li>
+ <h3>Nära</h3>
+ <ul>
+ @foreach (var item in Model.Near)
+ {
+ <li>@item</li>
+ }
+ </ul>
}
- </ul>
}
View
1 Words.Web/Views/Web.config
@@ -16,6 +16,7 @@
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
+ <add namespace="Words.Web.ViewModels" />
</namespaces>
</pages>
</system.web.webPages.razor>
View
25 Words.Web/Web.config
@@ -1,16 +1,14 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
-
<configuration>
<appSettings>
- <add key="webpages:Version" value="1.0.0.0"/>
- <add key="ClientValidationEnabled" value="true"/>
- <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
+ <add key="webpages:Version" value="1.0.0.0" />
+ <add key="ClientValidationEnabled" value="true" />
+ <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
-
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
@@ -21,28 +19,24 @@
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>
-
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
-
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
- <add namespace="System.Web.WebPages"/>
+ <add namespace="System.Web.WebPages" />
</namespaces>
</pages>
</system.web>
-
<system.webServer>
- <validation validateIntegratedModeConfiguration="false"/>
- <modules runAllManagedModulesForAllRequests="true"/>
+ <validation validateIntegratedModeConfiguration="false" />
+ <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
-
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
@@ -51,4 +45,7 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
-</configuration>
+ <connectionStrings>
+ <add name="RavenDB" connectionString="Url=http://localhost:8081" />
+ </connectionStrings>
+</configuration>
View
64 Words.Web/Words.Web.csproj
@@ -37,6 +37,58 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="AsyncCtpLibrary">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\AsyncCtpLibrary.dll</HintPath>
+ </Reference>
+ <Reference Include="BouncyCastle.Crypto">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\BouncyCastle.Crypto.dll</HintPath>
+ </Reference>
+ <Reference Include="Esent.Interop">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Esent.Interop.dll</HintPath>
+ </Reference>
+ <Reference Include="ICSharpCode.NRefactory">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\ICSharpCode.NRefactory.dll</HintPath>
+ </Reference>
+ <Reference Include="Lucene.Net">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Lucene.Net.dll</HintPath>
+ </Reference>
+ <Reference Include="Lucene.Net.Contrib.Spatial">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Lucene.Net.Contrib.Spatial.dll</HintPath>
+ </Reference>
+ <Reference Include="Lucene.Net.Contrib.SpellChecker">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Lucene.Net.Contrib.SpellChecker.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\packages\Newtonsoft.Json.4.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="NLog">
+ <HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Abstractions">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Abstractions.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Client.Embedded">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Client.Embedded.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Client.Lightweight">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Client.Lightweight.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Client.MvcIntegration">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Client.MvcIntegration.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Database">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Database.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Munin">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Munin.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Storage.Esent">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Storage.Esent.dll</HintPath>
+ </Reference>
+ <Reference Include="Raven.Storage.Managed">
+ <HintPath>..\packages\RavenDB-Embedded.1.0.701\lib\net40\Raven.Storage.Managed.dll</HintPath>
+ </Reference>
+ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
@@ -66,9 +118,12 @@
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
+ <Compile Include="Models\Query.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ViewModels\ResultsViewModel.cs" />
</ItemGroup>
<ItemGroup>
+ <Content Include="App_Data\words.txt" />
<Content Include="Content\bootstrap\css\bootstrap-responsive.css" />
<Content Include="Content\bootstrap\css\bootstrap-responsive.min.css" />
<Content Include="Content\bootstrap\css\bootstrap.css" />
@@ -90,11 +145,7 @@
<Content Include="Views\Shared\Error.cshtml" />
<Content Include="Views\Shared\_Layout.cshtml" />
</ItemGroup>
- <ItemGroup>
- <Folder Include="App_Data\" />
- <Folder Include="Models\" />
- <Folder Include="ViewModels\" />
- </ItemGroup>
+ <ItemGroup />
<ItemGroup>
<ProjectReference Include="..\Words\Words.csproj">
<Project>{4A632808-53E5-404A-BA3B-335918984902}</Project>
@@ -104,6 +155,9 @@
<ItemGroup>
<Content Include="Views\Home\Index.cshtml" />
</ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config" />
+ </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<Import Project="$(ProgramFiles)\MSBuild\StyleCop\v4.7\StyleCop.targets" />
View
6 Words.Web/packages.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="4.0.8" />
+ <package id="NLog" version="2.0.0.2000" />
+ <package id="RavenDB-Embedded" version="1.0.701" />
+</packages>

0 comments on commit 70c1e74

Please sign in to comment.
Something went wrong with that request. Please try again.