* denormalized flags to FlagCount

* don't query all votes for every quote that is rendered
This commit is contained in:
tmont 2011-02-27 01:41:07 +00:00
parent 140b1d6bcc
commit 540f34da3e
6 changed files with 36 additions and 16 deletions

View File

@ -13,9 +13,10 @@
<many-to-one name="Game" column="game_id" not-null="true" foreign-key="fk_quote_game" fetch="join" />
<!-- denormalization for performance purposes -->
<property name="Score" column="score" not-null="false" index="idx_score_upvotes" />
<property name="UpVotes" column="upvotes" not-null="false" index="idx_score_upvotes" />
<property name="DownVotes" column="downvotes" not-null="false" />
<property name="Score" column="score" not-null="true" index="idx_score_upvotes" />
<property name="UpVotes" column="upvotes" not-null="true" index="idx_score_upvotes" />
<property name="DownVotes" column="downvotes" not-null="true" />
<property name="FlagCount" column="flag_count" not-null="true" />
<set access="nosetter.camelcase" name="Categories" table="quote_category_map">
<key column="quote_id" />

View File

@ -48,23 +48,31 @@ namespace VideoGameQuotes.Api {
}
public virtual Quote AddFlag(string comment, QuoteFlagType type, User user) {
flags.Add(new QuoteFlag {
var flag = new QuoteFlag {
Comment = comment,
Type = type,
User = user,
Quote = this
});
};
if (flags.Add(flag)) {
FlagCount++;
}
return this;
}
public virtual Quote RemoveFlag(QuoteFlag flag) {
flags.Remove(flag);
if (flags.Remove(flag)) {
FlagCount--;
}
return this;
}
public virtual void ClearFlags() {
flags.Clear();
FlagCount = 0;
}
#endregion
@ -112,6 +120,7 @@ namespace VideoGameQuotes.Api {
public virtual int UpVotes { get; private set; }
public virtual int DownVotes { get; private set; }
public virtual int Score { get; private set; }
public virtual int FlagCount { get; private set; }
public virtual QuoteDto ToDto() {
return new QuoteDto {

View File

@ -81,6 +81,8 @@ namespace VideoGameQuotes.Web.Controllers {
};
return Json(this.CreateJsonResponse(null, data));
} catch (CannotVoteTwiceException) {
return Json(this.CreateJsonErrorResponse("You have already voted for this quote; you can reverse your vote by voting in the other direction"));
} catch {
return Json(this.CreateJsonErrorResponse("An error occurred while trying to process your vote"));
}
@ -195,7 +197,7 @@ namespace VideoGameQuotes.Web.Controllers {
try {
var quote = model.QuoteId > 0
? quoteService.GetQuote(model.QuoteId)
: new Quote {Creator = currentUserProvider.CurrentUser};
: new Quote { Creator = currentUserProvider.CurrentUser };
quote.Game = quoteService.GetGame(model.GameId);
quote.Text = model.QuoteText;
@ -214,7 +216,7 @@ namespace VideoGameQuotes.Web.Controllers {
quote = quoteService.SaveQuote(quote);
return RedirectToAction("Quote", new {id = quote.Id, text = quote.GetUrlFriendlyText()});
return RedirectToAction("Quote", new { id = quote.Id, text = quote.GetUrlFriendlyText() });
} catch (Exception e) {
ModelState.AddModelError("save", e.Message);
ResetEditQuoteModel(model);

View File

@ -6,15 +6,11 @@
<div class="quote-data clearfix">
<div class="quote-score-container">
<div class="vote-container">
<% if (!Model.VotedUp) { %>
<span class="vote-for" title="I like this quote">&#x25B2;</span>
<% } %>
</div>
<div class="quote-score" title="+<%= Model.Quote.UpVotes %>, -<%= Model.Quote.DownVotes %>"><%= Model.Quote.Score %></div>
<div class="vote-container">
<% if (!Model.VotedDown) { %>
<span class="vote-against" title="I hate this quote">&#x25BC;</span>
<% } %>
</div>
</div>
@ -36,7 +32,7 @@
<a class="quote-permalink" href="<%= Url.Action("quote", "quote", new { id = Model.Quote.Id, text = Model.Quote.GetUrlFriendlyText() }) %>" title="permanent link to this quote"></a>
<% if (Model.User != null && Model.User.Group >= UserGroup.Admin) { %>
<a class="edit-link" href="<%= Url.Action("edit", "quote", new { id = Model.Quote.Id }) %>" title="edit this quote"></a>
<small>(<%= Model.Quote.Flags.Count() %>)</small>
<small>(<%= Model.Quote.FlagCount %>)</small>
<% } %>
</p>
</div>

View File

@ -151,11 +151,19 @@ namespace VideoGameQuotes.Api.Tests.NHibernate {
.AddPublisher(kaga)
.AddPublisher(sega);
var zelda2 = new Game { Creator = creator, Name = "Zelda II: The Adventure of Link", Website = "http://en.wikipedia.org/wiki/Zelda_II:_The_Adventure_of_Link", Region = Region.NorthAmerica | Region.Japan | Region.PAL }
.AddSystem(nes)
.AddSystem(fds)
.AddSystem(gba)
.AddSystem(gcn)
.AddPublisher(nintendo);
using (var tx = session.BeginTransaction()) {
var repo = new NHibernateRepository<Game>(session);
repo.Save(loz);
repo.Save(crystalis);
repo.Save(zeroWing);
repo.Save(zelda2);
tx.Commit();
}
#endregion
@ -175,9 +183,12 @@ namespace VideoGameQuotes.Api.Tests.NHibernate {
var hopOnMyBack = new Quote { Creator = creator, Game = crystalis, Text = "Please hop on my back. I'll take you wherever you like." }
.AddCategory(dolphins);
var error = new Quote { Creator = creator, Game = zelda2, Text = "I am Error." };
using (var tx = session.BeginTransaction()) {
var repo = new NHibernateRepository<Quote>(session);
repo.Save(allYourBase);
repo.Save(error);
repo.Save(dangerousToGoAlone);
repo.Save(hopOnMyBack);
repo.Save(dodongo);

View File

@ -148,9 +148,10 @@ alter table quote_category_map drop foreign key FK5892F846C2AA09DD
modified DATETIME,
creator INTEGER not null,
game_id INTEGER not null,
score INTEGER,
upvotes INTEGER,
downvotes INTEGER,
score INTEGER not null,
upvotes INTEGER not null,
downvotes INTEGER not null,
flag_count INTEGER not null,
primary key (quote_id)
);