public async Task <User> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken) { using (var connection = new ConScope(_dataService)) { return(await connection.Connection.SingleAsync <User>(x => x.EmailNormalized == normalizedEmail, cancellationToken)); } }
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 <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 <User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken) { using (var connection = new ConScope(_dataService)) { return(await connection.Connection.SingleAsync <User>(x => x.UserName.ToUpper() == normalizedUserName, cancellationToken)); } }
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 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 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 Can_update_settings() { var setting = new TestSetting { NameProperty = "lando", Value = 5 }; await _settingsService.SaveSetting(setting); setting = new TestSetting { NameProperty = "landocalrissian", Value = 10 }; await _settingsService.SaveSetting(setting); using (var conScope = new ConScope(GetDataService())) { (await conScope.Connection.CountAsync(conScope.Connection.From <SettingV1>().Where(x => x.Name == "dbname"))).Should().Be(1); } setting = await _settingsService.GetSetting <TestSetting>(); setting.NameProperty.Should().Be("landocalrissian"); }
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 <User> FindByIdAsync(string userId, CancellationToken cancellationToken) { using (var connection = new ConScope(_dataService)) { return(await connection.Connection.SingleByIdAsync <User>(userId, cancellationToken)); } }
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 <List <JobTask> > GetAllJobs() { using (var connection = new ConScope(_dataService)) { var jobs = await connection.Connection.SelectAsync(connection.Connection.From <JobV1>() .OrderBy(x => x.QueuedOn)); return(jobs.Select(x => new JobTask { JobId = x.Id, Type = Type.GetType(x.JobType), Data = JsonConvert.DeserializeObject(x.JobData, Type.GetType(x.JobDataType), (JsonSerializerSettings)null) }).ToList()); } }
public async Task <T> GetSetting <T>() { var name = GetSettingNameAttribute(typeof(T)); using (var connection = new ConScope(_dataService)) { var setting = await connection.Connection.SingleAsync(connection.Connection.From <SettingV1>().Where(x => x.Name == name)); if (setting == null || string.IsNullOrEmpty(setting.Settings)) { return((T)Activator.CreateInstance(typeof(T))); } return(_settingsSerializer.Deserialize <T>(setting.Settings)); } }
public int?GetCurrentVersion() { using (var conScope = new ConScope(_dataService)) { var db = conScope.Connection; db.CreateTableIfNotExists <Migration>(); var migrations = db.Select <Migration>().ToList(); if (migrations.Count == 0) { return(null); } return(migrations.OrderByDescending(x => x.Version).First().Version); } }
public async Task <Account> GetAccount(AccountIdentification id) { using (var con = new ConScope(_dataService)) { if (id.Id.HasValue) { return(await con.Connection.SingleAsync <Account>(id.Id)); } if (id.GlobalUserId.HasValue) { return(await con.Connection.SingleAsync <Account>(x => x.GlobalUserId == id.GlobalUserId)); } throw new Exception("Invalid id"); } }
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 <SeekedList <Transaction> > GetTransactions(Guid?accountId = null, int?skip = null, int?take = null) { using (var con = new ConScope(_dataService)) { var query = con.Connection.From <Transaction>(); if (accountId.HasValue) { query.Where(x => x.AccountId == accountId); } long?count = null; if (!skip.HasValue && !take.HasValue) { // We are returning all the items, not need to do additional DB query. } else { count = await con.Connection.CountAsync(query); } query.OrderByDescending(x => x.Date); if (skip.HasValue) { query.Skip(skip.Value); } if (take.HasValue) { query.Take(take.Value); } var results = await con.Connection.SelectAsync(query); if (!count.HasValue) { count = results.Count; } return(new SeekedList <Transaction>(results, skip, take, count.Value)); } }
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 <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); } } }
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 <PayPalOrder> CreatePendingOrder(Guid accountId, decimal amount) { // TODO: Make this range configurable. if (amount <= 0 || amount > 500) { throw new Exception("Invalid amount."); } _logger.LogInformation("Creating pending paypal order for {AccountId} for {Amount}", accountId, amount); var account = await _accountsService.GetAccount(AccountIdentification.ById(accountId)); account.NotNull(); var potentialOrderId = Guid.NewGuid(); string paypalOrderId; { var client = _payPalClientProvider.BuildHttpClient(); var request = new OrdersCreateRequest(); request.Prefer("return=representation"); request.RequestBody(new OrderRequest { CheckoutPaymentIntent = "CAPTURE", PurchaseUnits = new List <PurchaseUnitRequest> { new PurchaseUnitRequest { ReferenceId = potentialOrderId.ToString(), AmountWithBreakdown = new AmountWithBreakdown { Value = amount.ToString(CultureInfo.InvariantCulture), CurrencyCode = "USD" } } } }); var response = await client.Execute(request); if (response.StatusCode != HttpStatusCode.Created) { _logger.LogError("Invalid status code from PayPal order create: status: {Status} response: {Response}", response.StatusCode, SerializePayPalType(response.Result <object>())); throw new Exception("Invalid PayPal response"); } paypalOrderId = response.Result <Order>().Id; } // Great, we created a PayPal order, let's add the record into the database. using (var con = new ConScope(_dataService)) { var pendingOrder = new PayPalOrder { Id = potentialOrderId, OrderStatus = PayPalOrderStatus.Pending, PayPalOrderId = paypalOrderId, AccountId = account.Id, Amount = amount }; await con.Connection.InsertAsync(pendingOrder); return(pendingOrder); } }