public async Task SaveSetting <T>(Action <T> updateAction) { using (var connection = new ConScope(_dataService)) using (var transaction = await connection.BeginTransaction()) { var name = GetSettingNameAttribute(typeof(T)); var existing = await GetSetting <T>(); updateAction(existing); var settingValue = _settingsSerializer.Serialize(existing); var setting = await connection.Connection.SingleAsync(connection.Connection.From <SettingV1>().Where(x => x.Name == name)); if (setting == null) { setting = new SettingV1 { Name = name, Settings = settingValue }; await connection.Connection.SaveAsync(setting); } else { setting.Settings = settingValue; await connection.Connection.UpdateAsync(setting); } transaction.Commit(); } }
public async Task <Account> GetOrCreateAccount(AccountIdentification id) { using (var con = new ConScope(_dataService)) using (var trans = await con.BeginTransaction()) { var account = await GetAccount(id); if (account == null) { if (!id.GlobalUserId.HasValue) { throw new Exception("Can only auto create account when using global user id."); } account = new Account { GlobalUserId = id.GlobalUserId.Value }; await con.Connection.SaveAsync(account); trans.Commit(); _logger.LogInformation("Created account {AccountId} for global user {GlobalUserId", account.Id, id.GlobalUserId); } return(account); } }
public async Task <JobTask> DequeueJob() { JobV1 result; using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { result = await connection.Connection.SingleAsync( connection.Connection.From <JobV1>() .Where(x => x.Status == JobStatus.Queued) .OrderBy(x => x.QueuedOn) .Take(1)); if (result == null) { return(null); } result.Status = JobStatus.Processing; await connection.Connection.UpdateAsync(result); transaction.Commit(); } } return(new JobTask { JobId = result.Id, Type = Type.GetType(result.JobType), Data = JsonConvert.DeserializeObject(result.JobData, Type.GetType(result.JobDataType), (JsonSerializerSettings)null) }); }
public async Task MarkJobSucceeded(int jobId) { JobV1 job; using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { job = await connection.Connection.SingleByIdAsync <JobV1>(jobId); if (job == null) { throw new Exception($"Invalid job id {jobId}"); } if (job.Status != JobStatus.Processing) { throw new Exception($"Can't mark a job {jobId} as completed because it wasn't marked as processing."); } await connection.Connection.DeleteAsync(job); transaction.Commit(); } } await _jobSucceeded.Publish(this, new JobSucceededEvent(new JobTask { JobId = job.Id, Type = Type.GetType(job.JobType), Data = JsonConvert.DeserializeObject(job.JobData, Type.GetType(job.JobDataType)) })); }
public async Task Enqueue <T, TData>(TData data) where T : IJob where TData : new() { var job = new JobV1 { QueuedOn = DateTimeOffset.UtcNow, JobType = typeof(T).AssemblyQualifiedName, JobDataType = typeof(TData).AssemblyQualifiedName, JobData = JsonConvert.SerializeObject(data) }; using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { await connection.Connection.SaveAsync(job); transaction.Commit(); } } await _jobEnqueued.Publish(this, new JobEnqueuedEvent(new JobTask { JobId = job.Id, Type = typeof(T), Data = data })); }
public async Task <Transaction> AddTransaction(Guid accountId, decimal amount, string title, string metaData, Guid?payPalOrderId) { using (var con = new ConScope(_dataService)) using (var trans = await con.BeginTransaction()) { // Let's update the total on the account object. var runningTotal = await con.Connection.SingleAsync <decimal>( con.Connection.From <Transaction>() .Select(x => new { Sum = Sql.Sum(x.Amount) })); runningTotal += amount; var transaction = new Transaction { AccountId = accountId, Date = DateTimeOffset.UtcNow, Amount = amount, CurrentBalance = runningTotal, Title = title, MetaData = metaData, PayPalOrderId = payPalOrderId }; await con.Connection.SaveAsync(transaction); await con.Connection.UpdateOnlyAsync(() => new Account { CurrentBalance = runningTotal }, x => x.Id == accountId); trans.Commit(); return(transaction); } }
public async Task ReQueueProcessingJobs() { using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { connection.Connection.UpdateOnly(() => new JobV1 { Status = JobStatus.Queued }, x => x.Status == JobStatus.Processing); transaction.Commit(); } } }
public async Task CapturePendingOrder(string orderId, string payerId) { Order order; { var client = _payPalClientProvider.BuildHttpClient(); var request = new OrdersCaptureRequest(orderId); request.RequestBody(new OrderActionRequest()); var response = await client.Execute(request); if (response.StatusCode != HttpStatusCode.Created) { _logger.LogError("Invalid status code from PayPal order capture: status: {Status} response: {Response}", response.StatusCode, SerializePayPalType(response.Result <object>())); throw new Exception("Invalid PayPal response"); } order = response.Result <Order>(); if (order.Status != "COMPLETED") { _logger.LogError("The order from PayPal wasn't marked as COMPELTED: {Response}", SerializePayPalType(response.Result <object>())); throw new Exception("The order from PayPal wasn't marked as COMPELTED"); } } using (var con = new ConScope(_dataService)) using (var trans = await con.BeginTransaction()) { var pendingOrder = con.Connection.Single <PayPalOrder>(x => x.PayPalOrderId == orderId); if (pendingOrder.OrderStatus == PayPalOrderStatus.Completed) { throw new Exception($"Attempted to update order {orderId} as completed, but it is already marked as completed."); } pendingOrder.OrderStatus = PayPalOrderStatus.Completed; pendingOrder.PayPalPayerId = payerId; pendingOrder.PayPalOrderJson = SerializePayPalType(order); await con.Connection.SaveAsync(pendingOrder); await _transactionsService.AddTransaction(pendingOrder.AccountId, pendingOrder.Amount, "PayPal reload", pendingOrder.PayPalOrderJson, pendingOrder.Id); trans.Commit(); } }
public async Task CancelPendingOrder(string orderId) { using (var con = new ConScope(_dataService)) using (var trans = await con.BeginTransaction()) { var pendingOrder = await con.Connection.SingleAsync <PayPalOrder>(x => x.PayPalOrderId == orderId); if (pendingOrder == null) { throw new Exception($"No pending paypal order to cancel with id {orderId}"); } if (pendingOrder.OrderStatus == PayPalOrderStatus.Completed) { throw new Exception($"The order {orderId} was already completed."); } await con.Connection.DeleteByIdAsync <PayPalOrder>(pendingOrder.Id); trans.Commit(); } }
public async Task RemoveProblematicJobs() { using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { var jobs = await connection.Connection.SelectAsync(connection.Connection.From <JobV1>()); foreach (var job in jobs) { try { var jobType = Type.GetType(job.JobType); if (jobType == null) { throw new Exception($"Invalid job type: {job.JobType}"); } var jobDataType = Type.GetType(job.JobDataType); if (jobDataType == null) { throw new Exception($"Invalid job type: {job.JobDataType}"); } JsonConvert.DeserializeObject(job.JobData, Type.GetType(job.JobDataType), (JsonSerializerSettings)null); } catch (Exception ex) { _logger.LogError(ex, "Detected problematic job, deleting"); await connection.Connection.DeleteByIdAsync <JobV1>(job.Id); } } transaction.Commit(); } } }
public async Task <IdentityResult> CreateAsync(User user, CancellationToken cancellationToken) { using (var connection = new ConScope(_dataService)) { using (var transaction = await connection.BeginTransaction()) { var existing = await connection.Connection.SingleAsync <User>(x => x.EmailNormalized == user.EmailNormalized, cancellationToken); if (existing != null) { return(IdentityResult.Failed(new IdentityError { Description = "Email already in use." })); } existing = await connection.Connection.SingleAsync <User>( x => x.UserNameNormalized == user.UserNameNormalized, cancellationToken); if (existing != null) { return(IdentityResult.Failed(new IdentityError { Description = "User name already in use." })); } user.Id = Guid.NewGuid().ToString(); await connection.Connection.SaveAsync(user, token : cancellationToken); transaction.Commit(); return(IdentityResult.Success); } } }