* denormalized flags to FlagCount
* don't query all votes for every quote that is rendered
This commit is contained in:
parent
140b1d6bcc
commit
540f34da3e
@ -13,9 +13,10 @@
|
|||||||
<many-to-one name="Game" column="game_id" not-null="true" foreign-key="fk_quote_game" fetch="join" />
|
<many-to-one name="Game" column="game_id" not-null="true" foreign-key="fk_quote_game" fetch="join" />
|
||||||
|
|
||||||
<!-- denormalization for performance purposes -->
|
<!-- denormalization for performance purposes -->
|
||||||
<property name="Score" column="score" not-null="false" index="idx_score_upvotes" />
|
<property name="Score" column="score" not-null="true" index="idx_score_upvotes" />
|
||||||
<property name="UpVotes" column="upvotes" not-null="false" index="idx_score_upvotes" />
|
<property name="UpVotes" column="upvotes" not-null="true" index="idx_score_upvotes" />
|
||||||
<property name="DownVotes" column="downvotes" not-null="false" />
|
<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">
|
<set access="nosetter.camelcase" name="Categories" table="quote_category_map">
|
||||||
<key column="quote_id" />
|
<key column="quote_id" />
|
||||||
|
@ -48,23 +48,31 @@ namespace VideoGameQuotes.Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public virtual Quote AddFlag(string comment, QuoteFlagType type, User user) {
|
public virtual Quote AddFlag(string comment, QuoteFlagType type, User user) {
|
||||||
flags.Add(new QuoteFlag {
|
var flag = new QuoteFlag {
|
||||||
Comment = comment,
|
Comment = comment,
|
||||||
Type = type,
|
Type = type,
|
||||||
User = user,
|
User = user,
|
||||||
Quote = this
|
Quote = this
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (flags.Add(flag)) {
|
||||||
|
FlagCount++;
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Quote RemoveFlag(QuoteFlag flag) {
|
public virtual Quote RemoveFlag(QuoteFlag flag) {
|
||||||
flags.Remove(flag);
|
if (flags.Remove(flag)) {
|
||||||
|
FlagCount--;
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ClearFlags() {
|
public virtual void ClearFlags() {
|
||||||
flags.Clear();
|
flags.Clear();
|
||||||
|
FlagCount = 0;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -112,6 +120,7 @@ namespace VideoGameQuotes.Api {
|
|||||||
public virtual int UpVotes { get; private set; }
|
public virtual int UpVotes { get; private set; }
|
||||||
public virtual int DownVotes { get; private set; }
|
public virtual int DownVotes { get; private set; }
|
||||||
public virtual int Score { get; private set; }
|
public virtual int Score { get; private set; }
|
||||||
|
public virtual int FlagCount { get; private set; }
|
||||||
|
|
||||||
public virtual QuoteDto ToDto() {
|
public virtual QuoteDto ToDto() {
|
||||||
return new QuoteDto {
|
return new QuoteDto {
|
||||||
|
@ -81,6 +81,8 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return Json(this.CreateJsonResponse(null, data));
|
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 {
|
} catch {
|
||||||
return Json(this.CreateJsonErrorResponse("An error occurred while trying to process your vote"));
|
return Json(this.CreateJsonErrorResponse("An error occurred while trying to process your vote"));
|
||||||
}
|
}
|
||||||
@ -195,7 +197,7 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
try {
|
try {
|
||||||
var quote = model.QuoteId > 0
|
var quote = model.QuoteId > 0
|
||||||
? quoteService.GetQuote(model.QuoteId)
|
? quoteService.GetQuote(model.QuoteId)
|
||||||
: new Quote {Creator = currentUserProvider.CurrentUser};
|
: new Quote { Creator = currentUserProvider.CurrentUser };
|
||||||
|
|
||||||
quote.Game = quoteService.GetGame(model.GameId);
|
quote.Game = quoteService.GetGame(model.GameId);
|
||||||
quote.Text = model.QuoteText;
|
quote.Text = model.QuoteText;
|
||||||
@ -214,7 +216,7 @@ namespace VideoGameQuotes.Web.Controllers {
|
|||||||
|
|
||||||
quote = quoteService.SaveQuote(quote);
|
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) {
|
} catch (Exception e) {
|
||||||
ModelState.AddModelError("save", e.Message);
|
ModelState.AddModelError("save", e.Message);
|
||||||
ResetEditQuoteModel(model);
|
ResetEditQuoteModel(model);
|
||||||
|
@ -6,15 +6,11 @@
|
|||||||
<div class="quote-data clearfix">
|
<div class="quote-data clearfix">
|
||||||
<div class="quote-score-container">
|
<div class="quote-score-container">
|
||||||
<div class="vote-container">
|
<div class="vote-container">
|
||||||
<% if (!Model.VotedUp) { %>
|
|
||||||
<span class="vote-for" title="I like this quote">▲</span>
|
<span class="vote-for" title="I like this quote">▲</span>
|
||||||
<% } %>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="quote-score" title="+<%= Model.Quote.UpVotes %>, -<%= Model.Quote.DownVotes %>"><%= Model.Quote.Score %></div>
|
<div class="quote-score" title="+<%= Model.Quote.UpVotes %>, -<%= Model.Quote.DownVotes %>"><%= Model.Quote.Score %></div>
|
||||||
<div class="vote-container">
|
<div class="vote-container">
|
||||||
<% if (!Model.VotedDown) { %>
|
|
||||||
<span class="vote-against" title="I hate this quote">▼</span>
|
<span class="vote-against" title="I hate this quote">▼</span>
|
||||||
<% } %>
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
<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) { %>
|
<% 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>
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -151,11 +151,19 @@ namespace VideoGameQuotes.Api.Tests.NHibernate {
|
|||||||
.AddPublisher(kaga)
|
.AddPublisher(kaga)
|
||||||
.AddPublisher(sega);
|
.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()) {
|
using (var tx = session.BeginTransaction()) {
|
||||||
var repo = new NHibernateRepository<Game>(session);
|
var repo = new NHibernateRepository<Game>(session);
|
||||||
repo.Save(loz);
|
repo.Save(loz);
|
||||||
repo.Save(crystalis);
|
repo.Save(crystalis);
|
||||||
repo.Save(zeroWing);
|
repo.Save(zeroWing);
|
||||||
|
repo.Save(zelda2);
|
||||||
tx.Commit();
|
tx.Commit();
|
||||||
}
|
}
|
||||||
#endregion
|
#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." }
|
var hopOnMyBack = new Quote { Creator = creator, Game = crystalis, Text = "Please hop on my back. I'll take you wherever you like." }
|
||||||
.AddCategory(dolphins);
|
.AddCategory(dolphins);
|
||||||
|
|
||||||
|
var error = new Quote { Creator = creator, Game = zelda2, Text = "I am Error." };
|
||||||
|
|
||||||
using (var tx = session.BeginTransaction()) {
|
using (var tx = session.BeginTransaction()) {
|
||||||
var repo = new NHibernateRepository<Quote>(session);
|
var repo = new NHibernateRepository<Quote>(session);
|
||||||
repo.Save(allYourBase);
|
repo.Save(allYourBase);
|
||||||
|
repo.Save(error);
|
||||||
repo.Save(dangerousToGoAlone);
|
repo.Save(dangerousToGoAlone);
|
||||||
repo.Save(hopOnMyBack);
|
repo.Save(hopOnMyBack);
|
||||||
repo.Save(dodongo);
|
repo.Save(dodongo);
|
||||||
|
@ -148,9 +148,10 @@ alter table quote_category_map drop foreign key FK5892F846C2AA09DD
|
|||||||
modified DATETIME,
|
modified DATETIME,
|
||||||
creator INTEGER not null,
|
creator INTEGER not null,
|
||||||
game_id INTEGER not null,
|
game_id INTEGER not null,
|
||||||
score INTEGER,
|
score INTEGER not null,
|
||||||
upvotes INTEGER,
|
upvotes INTEGER not null,
|
||||||
downvotes INTEGER,
|
downvotes INTEGER not null,
|
||||||
|
flag_count INTEGER not null,
|
||||||
primary key (quote_id)
|
primary key (quote_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user