generated from NetCoreTemplates/blazor-vue
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor DbWrites into multiple commands
- Loading branch information
Showing
27 changed files
with
775 additions
and
453 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class AnswerAddedToPostCommand(IDbConnection db) : IExecuteCommandAsync<AnswerAddedToPost> | ||
{ | ||
public async Task ExecuteAsync(AnswerAddedToPost request) | ||
{ | ||
await db.UpdateAddAsync(() => new Post { | ||
AnswerCount = 1, | ||
}, x => x.Id == request.Id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.Messaging; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CompletePostJobsCommand(IDbConnection Db, ModelWorkerQueue modelWorkers, IMessageProducer mqClient) : IExecuteCommandAsync<CompletePostJobs> | ||
{ | ||
public async Task ExecuteAsync(CompletePostJobs request) | ||
{ | ||
var jobIds = request.Ids; | ||
await Db.UpdateOnlyAsync(() => new PostJob { | ||
CompletedDate = DateTime.UtcNow, | ||
}, | ||
x => jobIds.Contains(x.Id)); | ||
var postJobs = await Db.SelectAsync(Db.From<PostJob>() | ||
.Where(x => jobIds.Contains(x.Id))); | ||
|
||
foreach (var postJob in postJobs) | ||
{ | ||
// If there's no outstanding model answer jobs for this post, add a rank job | ||
if (!await Db.ExistsAsync(Db.From<PostJob>() | ||
.Where(x => x.PostId == postJob.PostId && x.CompletedDate == null))) | ||
{ | ||
var rankJob = new PostJob | ||
{ | ||
PostId = postJob.PostId, | ||
Model = "rank", | ||
Title = postJob.Title, | ||
CreatedDate = DateTime.UtcNow, | ||
CreatedBy = nameof(DbWrites), | ||
}; | ||
await Db.InsertAsync(rankJob); | ||
modelWorkers.Enqueue(rankJob); | ||
mqClient.Publish(new SearchTasks { AddPostToIndex = postJob.PostId }); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CreateAnswerCommand(AppConfig appConfig, IDbConnection db) : IExecuteCommandAsync<Post> | ||
{ | ||
public async Task ExecuteAsync(Post answer) | ||
{ | ||
var postId = answer.ParentId!.Value; | ||
var refId = $"{postId}-{answer.CreatedBy}"; | ||
if (!await db.ExistsAsync(db.From<StatTotals>().Where(x => x.Id == refId))) | ||
{ | ||
await db.InsertAsync(new StatTotals | ||
{ | ||
Id = refId, | ||
PostId = postId, | ||
ViewCount = 0, | ||
FavoriteCount = 0, | ||
UpVotes = 0, | ||
DownVotes = 0, | ||
StartingUpVotes = 0, | ||
CreatedBy = answer.CreatedBy, | ||
}); | ||
} | ||
|
||
var post = await db.SingleByIdAsync<Post>(postId); | ||
if (post?.CreatedBy != null) | ||
{ | ||
if (post.CreatedBy != answer.CreatedBy) | ||
{ | ||
await db.InsertAsync(new Notification | ||
{ | ||
UserName = post.CreatedBy, | ||
Type = NotificationType.NewAnswer, | ||
RefId = refId, | ||
PostId = postId, | ||
CreatedDate = answer.CreationDate, | ||
Summary = answer.Summary.SubstringWithEllipsis(0, 100), | ||
RefUserName = answer.CreatedBy, | ||
}); | ||
appConfig.IncrUnreadNotificationsFor(post.CreatedBy); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(answer.Body)) | ||
{ | ||
var cleanBody = answer.Body.StripHtml().Trim(); | ||
var userNameMentions = cleanBody.FindUserNameMentions() | ||
.Where(x => x != post.CreatedBy && x != answer.CreatedBy).ToList(); | ||
if (userNameMentions.Count > 0) | ||
{ | ||
var existingUsers = await db.SelectAsync(db.From<ApplicationUser>() | ||
.Where(x => userNameMentions.Contains(x.UserName!))); | ||
|
||
foreach (var existingUser in existingUsers) | ||
{ | ||
var firstMentionPos = cleanBody.IndexOf(existingUser.UserName!, StringComparison.Ordinal); | ||
if (firstMentionPos < 0) continue; | ||
|
||
var startPos = Math.Max(0, firstMentionPos - 50); | ||
await db.InsertAsync(new Notification | ||
{ | ||
UserName = existingUser.UserName!, | ||
Type = NotificationType.AnswerMention, | ||
RefId = $"{postId}", | ||
PostId = postId, | ||
CreatedDate = answer.CreationDate, | ||
Summary = cleanBody.SubstringWithEllipsis(startPos, 100), | ||
RefUserName = answer.CreatedBy, | ||
}); | ||
appConfig.IncrUnreadNotificationsFor(existingUser.UserName!); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CreateNotificationCommand(AppConfig appConfig, IDbConnection db) : IExecuteCommandAsync<Notification> | ||
{ | ||
public async Task ExecuteAsync(Notification request) | ||
{ | ||
await db.InsertAsync(request); | ||
appConfig.IncrUnreadNotificationsFor(request.UserName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using System.Data; | ||
using Microsoft.Extensions.Logging; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CreatePostCommand(ILogger log, AppConfig appConfig, IDbConnection db) : IExecuteCommandAsync<Post> | ||
{ | ||
public async Task ExecuteAsync(Post post) | ||
{ | ||
var body = post.Body; | ||
post.Body = null; | ||
post.Id = (int)await db.InsertAsync(post, selectIdentity: true); | ||
var createdBy = post.CreatedBy; | ||
if (createdBy != null && post.PostTypeId == 1) | ||
{ | ||
await appConfig.ResetUserQuestionsAsync(db, createdBy); | ||
} | ||
|
||
try | ||
{ | ||
await db.InsertAsync(new StatTotals | ||
{ | ||
Id = $"{post.Id}", | ||
PostId = post.Id, | ||
UpVotes = 0, | ||
DownVotes = 0, | ||
StartingUpVotes = 0, | ||
CreatedBy = post.CreatedBy, | ||
}); | ||
} | ||
catch (Exception e) | ||
{ | ||
log.LogWarning("Couldn't insert StatTotals for Post {PostId}: '{Message}', updating instead...", post.Id, | ||
e.Message); | ||
await db.UpdateOnlyAsync(() => new StatTotals | ||
{ | ||
PostId = post.Id, | ||
CreatedBy = post.CreatedBy, | ||
}, x => x.Id == $"{post.Id}"); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(body)) | ||
{ | ||
var cleanBody = body.StripHtml().Trim(); | ||
var userNameMentions = cleanBody.FindUserNameMentions() | ||
.Where(x => x != createdBy).ToList(); | ||
if (userNameMentions.Count > 0) | ||
{ | ||
var existingUsers = await db.SelectAsync(db.From<ApplicationUser>() | ||
.Where(x => userNameMentions.Contains(x.UserName!))); | ||
|
||
foreach (var existingUser in existingUsers) | ||
{ | ||
var firstMentionPos = cleanBody.IndexOf(existingUser.UserName!, StringComparison.Ordinal); | ||
if (firstMentionPos < 0) continue; | ||
|
||
var startPos = Math.Max(0, firstMentionPos - 50); | ||
await db.InsertAsync(new Notification | ||
{ | ||
UserName = existingUser.UserName!, | ||
Type = NotificationType.QuestionMention, | ||
RefId = $"{post.Id}", | ||
PostId = post.Id, | ||
CreatedDate = post.CreationDate, | ||
Summary = cleanBody.SubstringWithEllipsis(startPos, 100), | ||
RefUserName = createdBy, | ||
}); | ||
appConfig.IncrUnreadNotificationsFor(existingUser.UserName!); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CreatePostJobsCommand(IDbConnection db, ModelWorkerQueue modelWorkers) : IExecuteCommandAsync<CreatePostJobs> | ||
{ | ||
public async Task ExecuteAsync(CreatePostJobs request) | ||
{ | ||
await db.SaveAllAsync(request.PostJobs); | ||
request.PostJobs.ForEach(modelWorkers.Enqueue); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.Messaging; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class CreatePostVotesCommand(IDbConnection db, IMessageProducer mqClient) : IExecuteCommandAsync<Vote> | ||
{ | ||
public async Task ExecuteAsync(Vote vote) | ||
{ | ||
if (string.IsNullOrEmpty(vote.RefId)) | ||
throw new ArgumentNullException(nameof(vote.RefId)); | ||
if (string.IsNullOrEmpty(vote.UserName)) | ||
throw new ArgumentNullException(nameof(vote.UserName)); | ||
|
||
var isAnswer = vote.RefId.IndexOf('-') >= 0; | ||
var voteUp = isAnswer ? AchievementType.AnswerUpVote : AchievementType.QuestionUpVote; | ||
var voteDown = isAnswer ? AchievementType.AnswerDownVote : AchievementType.QuestionDownVote; | ||
|
||
var rowsDeleted = await db.DeleteAsync<Vote>(new { vote.RefId, vote.UserName }); | ||
if (rowsDeleted > 0 && vote.RefUserName != null) | ||
{ | ||
// If they rescinded their previous vote, also remove the Ref User's previous achievement for that Q or A | ||
await db.ExecuteNonQueryAsync( | ||
"DELETE FROM Achievement WHERE UserName = @TargetUser AND RefUserName = @VoterUserName AND RefId = @RefId AND Type IN (@voteUp,@voteDown)", | ||
new { TargetUser = vote.RefUserName, VoterUserName = vote.UserName , vote.RefId, voteUp, voteDown }); | ||
} | ||
|
||
if (vote.Score != 0) | ||
{ | ||
await db.InsertAsync(vote); | ||
|
||
if (vote.RefUserName != null) | ||
{ | ||
await db.InsertAsync(new Achievement | ||
{ | ||
UserName = vote.RefUserName, | ||
RefUserName = vote.UserName, | ||
PostId = vote.PostId, | ||
RefId = vote.RefId, | ||
Type = vote.Score > 0 ? voteUp : voteDown, | ||
Score = vote.Score > 0 ? 10 : -1, // 10 points for UpVote, -1 point for DownVote | ||
CreatedDate = DateTime.UtcNow, | ||
}); | ||
} | ||
} | ||
|
||
mqClient.Publish(new RenderComponent { | ||
RegenerateMeta = vote.PostId | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class DeleteCommentCommand(AppConfig appConfig, IDbConnection db) : IExecuteCommandAsync<DeleteComment> | ||
{ | ||
public async Task ExecuteAsync(DeleteComment request) | ||
{ | ||
var refId = $"{request.Id}-{request.Created}"; | ||
var rowsAffected = await db.DeleteAsync(db.From<Notification>() | ||
.Where(x => x.RefId == refId && x.RefUserName == request.CreatedBy)); | ||
if (rowsAffected > 0) | ||
{ | ||
appConfig.ResetUsersUnreadNotifications(db); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class DeletePostCommand(AppConfig appConfig, IDbConnection db) : IExecuteCommandAsync<DeletePost> | ||
{ | ||
public async Task ExecuteAsync(DeletePost request) | ||
{ | ||
foreach (var postId in request.Ids) | ||
{ | ||
await db.DeleteAsync<PostJob>(x => x.PostId == postId); | ||
await db.DeleteAsync<Vote>(x => x.PostId == postId); | ||
await db.DeleteByIdAsync<Post>(postId); | ||
appConfig.ResetInitialPostId(db); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System.Data; | ||
using MyApp.Data; | ||
using MyApp.ServiceModel; | ||
using ServiceStack.OrmLite; | ||
|
||
namespace MyApp.ServiceInterface.App; | ||
|
||
public class FailJobCommand(IDbConnection db, ModelWorkerQueue modelWorkers) : IExecuteCommandAsync<FailJob> | ||
{ | ||
public async Task ExecuteAsync(FailJob request) | ||
{ | ||
await db.UpdateAddAsync(() => new PostJob { | ||
Error = request.Error, | ||
RetryCount = 1, | ||
}, | ||
x => x.PostId == request.Id); | ||
var postJob = await db.SingleByIdAsync<PostJob>(request.Id); | ||
if (postJob != null) | ||
{ | ||
if (postJob.RetryCount > 3) | ||
{ | ||
await db.UpdateOnlyAsync(() => | ||
new PostJob { CompletedDate = DateTime.UtcNow }, | ||
x => x.PostId == request.Id); | ||
} | ||
else | ||
{ | ||
modelWorkers.Enqueue(postJob); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.