diff --git a/WotBlitzStatisticsPro.DataAccess/IWargamingAccountDataAccessor.cs b/WotBlitzStatisticsPro.DataAccess/IWargamingAccountDataAccessor.cs index 602ab04..b3ea862 100644 --- a/WotBlitzStatisticsPro.DataAccess/IWargamingAccountDataAccessor.cs +++ b/WotBlitzStatisticsPro.DataAccess/IWargamingAccountDataAccessor.cs @@ -6,5 +6,15 @@ namespace WotBlitzStatisticsPro.DataAccess public interface IWargamingAccountDataAccessor { Task ReadAccountInfo(long accountId); + + Task ReadTankInfo(long accountId, long tankId); + + Task AddOurUpdateAccountInfo(AccountInfo accountInfo); + + Task AddAccountInfoHistory(AccountInfoHistory accountInfoHistory); + + Task AddOrUpdateTankInfo(TankInfo tankInfo); + + Task AddTankInfoHistory(TankInfoHistory tankInfoHistory); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistory.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistory.cs index d89d414..9853f07 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistory.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistory.cs @@ -1,16 +1,28 @@ -namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts +using MongoDB.Bson.Serialization.Attributes; + +namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts { public class AccountInfoHistory { + public AccountInfoHistory(long accountId, int lastBattleTime) + { + AccountInfoHistoryId = new AccountInfoHistoryKey(accountId, lastBattleTime); + } + + [BsonId] + public AccountInfoHistoryKey AccountInfoHistoryId { get; set; } + /// /// Player account identifier /// - public long AccountId { get; set; } + [BsonIgnore] + public long AccountId => AccountInfoHistoryId.AccountId; /// /// Last battle time /// - public int LastBattleTime { get; set; } + [BsonIgnore] + public int LastBattleTime => AccountInfoHistoryId.LastBattleTime; /// /// Battles count diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs new file mode 100644 index 0000000..4a57e34 --- /dev/null +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs @@ -0,0 +1,52 @@ +using System; + +namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts +{ + public class AccountInfoHistoryKey : IEquatable + { + public AccountInfoHistoryKey() + { + + } + + public AccountInfoHistoryKey(long accountId, int lastBattleTime) + { + AccountId = accountId; + LastBattleTime = lastBattleTime; + } + + public long AccountId { get; set; } + + public int LastBattleTime { get; set; } + + public bool Equals(AccountInfoHistoryKey other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return AccountId == other.AccountId && LastBattleTime == other.LastBattleTime; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((AccountInfoHistoryKey) obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(AccountId, LastBattleTime); + } + + public static bool operator ==(AccountInfoHistoryKey left, AccountInfoHistoryKey right) + { + return Equals(left, right); + } + + public static bool operator !=(AccountInfoHistoryKey left, AccountInfoHistoryKey right) + { + return !Equals(left, right); + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs index 8331965..d9e00ea 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs @@ -1,18 +1,34 @@ -using WotBlitzStatisticsPro.Common.Model; +using MongoDB.Bson.Serialization.Attributes; +using WotBlitzStatisticsPro.Common.Model; namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts { public class TankInfo { + public TankInfo() + { + + } + + public TankInfo(long accountId, long tankId) + { + TankInfoId = new TankInfoKey(accountId, tankId); + } + + [BsonId] + public TankInfoKey TankInfoId { get; set; } + /// /// Player account identifier /// - public long AccountId { get; set; } + [BsonIgnore] + public long AccountId => TankInfoId.AccountId; /// /// Tank identifier /// - public long TankId { get; set; } + [BsonIgnore] + public long TankId => TankInfoId.TankId; public int BattleLifeTimeInSeconds { get; set; } diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs index d9db7d6..728abd4 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs @@ -1,21 +1,40 @@ -namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts +using MongoDB.Bson.Serialization.Attributes; + +namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts { public class TankInfoHistory { - /// - /// Player account identifier - /// - public long AccountId { get; set; } - /// - /// Tank identifier - /// - public long TankId { get; set; } + public TankInfoHistory() + { + + } + + public TankInfoHistory(long accountId, long tankId, int lastBattleTime) + { + TankInfoHistoryId = new TankInfoHistoryKey(accountId, tankId, lastBattleTime); + } + + [BsonId] + public TankInfoHistoryKey TankInfoHistoryId { get; set; } + + /// + /// Player account identifier + /// + [BsonIgnore] + public long AccountId => TankInfoHistoryId.AccountId; + + /// + /// Tank identifier + /// + [BsonIgnore] + public long TankId => TankInfoHistoryId.TankId; /// /// Last battle /// - public int LastBattleTime { get; set; } + [BsonIgnore] + public int LastBattleTime => TankInfoHistoryId.LastBattleTime; diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs new file mode 100644 index 0000000..7431cad --- /dev/null +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs @@ -0,0 +1,64 @@ +using System; + +namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts +{ + public class TankInfoHistoryKey : IEquatable + { + public TankInfoHistoryKey() + { + + } + + public TankInfoHistoryKey(long accountId, long tankId, int lastBattleTime) + { + AccountId = accountId; + TankId = tankId; + LastBattleTime = lastBattleTime; + } + + /// + /// Player account identifier + /// + public long AccountId { get; set; } + + /// + /// Tank identifier + /// + public long TankId { get; set; } + + /// + /// Last battle + /// + public int LastBattleTime { get; set; } + + public bool Equals(TankInfoHistoryKey other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return AccountId == other.AccountId && TankId == other.TankId && LastBattleTime == other.LastBattleTime; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((TankInfoHistoryKey) obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(AccountId, TankId, LastBattleTime); + } + + public static bool operator ==(TankInfoHistoryKey left, TankInfoHistoryKey right) + { + return Equals(left, right); + } + + public static bool operator !=(TankInfoHistoryKey left, TankInfoHistoryKey right) + { + return !Equals(left, right); + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs new file mode 100644 index 0000000..f2ee5a8 --- /dev/null +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs @@ -0,0 +1,58 @@ +using System; + +namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts +{ + public class TankInfoKey : IEquatable + { + public TankInfoKey() + { + + } + + public TankInfoKey(long accountId, long tankId) + { + AccountId = accountId; + TankId = tankId; + } + + /// + /// Player account identifier + /// + public long AccountId { get; set; } + + /// + /// Tank identifier + /// + public long TankId { get; set; } + + public bool Equals(TankInfoKey other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return AccountId == other.AccountId && TankId == other.TankId; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((TankInfoKey) obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(AccountId, TankId); + } + + public static bool operator ==(TankInfoKey left, TankInfoKey right) + { + return Equals(left, right); + } + + public static bool operator !=(TankInfoKey left, TankInfoKey right) + { + return !Equals(left, right); + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/WargamingAccountDataAccessor.cs b/WotBlitzStatisticsPro.DataAccess/WargamingAccountDataAccessor.cs index 4b3cc55..6ab9eb8 100644 --- a/WotBlitzStatisticsPro.DataAccess/WargamingAccountDataAccessor.cs +++ b/WotBlitzStatisticsPro.DataAccess/WargamingAccountDataAccessor.cs @@ -32,36 +32,36 @@ namespace WotBlitzStatisticsPro.DataAccess _database.GetCollection(AccountInfoCollectionName).Indexes .CreateMany(new[] {accountInfoRealmIndexModel, accountInfoLastBattleTimeIndexModel}); - // AccountInfoHistory AccountId+LastBattleTime - var accountInfoHistoryBuilder = Builders.IndexKeys; - var accountInfoHistoryIndexModel = new CreateIndexModel( - accountInfoHistoryBuilder.Combine( - Builders.IndexKeys.Ascending(h => h.AccountId), - Builders.IndexKeys.Ascending(h => h.LastBattleTime))); - _database.GetCollection(AccountInfoHistoryCollectionName).Indexes - .CreateOne(accountInfoHistoryIndexModel); + //// AccountInfoHistory AccountId+LastBattleTime + //var accountInfoHistoryBuilder = Builders.IndexKeys; + //var accountInfoHistoryIndexModel = new CreateIndexModel( + // accountInfoHistoryBuilder.Combine( + // Builders.IndexKeys.Ascending(h => h.AccountId), + // Builders.IndexKeys.Ascending(h => h.LastBattleTime))); + //_database.GetCollection(AccountInfoHistoryCollectionName).Indexes + // .CreateOne(accountInfoHistoryIndexModel); - // TankInfo AccountId+TankId, LastBattleTime - var tankInfoBuilder = Builders.IndexKeys; - var tankInfoIndexModel = new CreateIndexModel( - tankInfoBuilder.Combine( - Builders.IndexKeys.Ascending(h => h.AccountId), - Builders.IndexKeys.Ascending(h => h.TankId))); - var tankInfoLastBattleTimeIndexModel = - new CreateIndexModel(tankInfoBuilder.Ascending(t => t.LastBattleTime)); - _database.GetCollection(TankInfoCollectionName).Indexes - .CreateMany(new[] {tankInfoIndexModel, tankInfoLastBattleTimeIndexModel}); + //// TankInfo AccountId+TankId, LastBattleTime + //var tankInfoBuilder = Builders.IndexKeys; + //var tankInfoIndexModel = new CreateIndexModel( + // tankInfoBuilder.Combine( + // Builders.IndexKeys.Ascending(h => h.AccountId), + // Builders.IndexKeys.Ascending(h => h.TankId))); + //var tankInfoLastBattleTimeIndexModel = + // new CreateIndexModel(tankInfoBuilder.Ascending(t => t.LastBattleTime)); + //_database.GetCollection(TankInfoCollectionName).Indexes + // .CreateMany(new[] {tankInfoIndexModel, tankInfoLastBattleTimeIndexModel}); - // TankInfoHistory AccountId+TankId+LastBattleTime - var tankInfoHistoryBuilder = Builders.IndexKeys; - var tankInfoHistoryIndexModel = new CreateIndexModel( - tankInfoHistoryBuilder.Combine( - Builders.IndexKeys.Ascending(h => h.AccountId), - Builders.IndexKeys.Ascending(h => h.TankId), - Builders.IndexKeys.Ascending(h => h.LastBattleTime))); - _database.GetCollection(TankInfoHistoryCollectionName).Indexes - .CreateOne(tankInfoHistoryIndexModel); + //// TankInfoHistory AccountId+TankId+LastBattleTime + //var tankInfoHistoryBuilder = Builders.IndexKeys; + //var tankInfoHistoryIndexModel = new CreateIndexModel( + // tankInfoHistoryBuilder.Combine( + // Builders.IndexKeys.Ascending(h => h.AccountId), + // Builders.IndexKeys.Ascending(h => h.TankId), + // Builders.IndexKeys.Ascending(h => h.LastBattleTime))); + //_database.GetCollection(TankInfoHistoryCollectionName).Indexes + // .CreateOne(tankInfoHistoryIndexModel); } public async Task ReadAccountInfo(long accountId) @@ -70,5 +70,44 @@ namespace WotBlitzStatisticsPro.DataAccess .FindAsync(Builders.Filter.Where(a => a.AccountId == accountId)); return account.FirstOrDefault(); } + + public async Task ReadTankInfo(long accountId, long tankId) + { + var tank = await _database.GetCollection(TankInfoCollectionName) + .FindAsync(Builders.Filter.Where(t => t.TankInfoId == new TankInfoKey(accountId, tankId))); + return tank.FirstOrDefault(); + } + + public Task AddOurUpdateAccountInfo(AccountInfo accountInfo) + { + return _database.GetCollection(AccountInfoCollectionName) + .ReplaceOneAsync( + Builders.Filter.Where(a => a.AccountId == accountInfo.AccountId), + accountInfo, + new ReplaceOptions {IsUpsert = true} + ); + } + + public Task AddAccountInfoHistory(AccountInfoHistory accountInfoHistory) + { + return _database.GetCollection(AccountInfoHistoryCollectionName) + .InsertOneAsync(accountInfoHistory); + } + + public Task AddOrUpdateTankInfo(TankInfo tankInfo) + { + return _database.GetCollection(TankInfoCollectionName) + .ReplaceOneAsync( + Builders.Filter.Where(t => t.TankInfoId == new TankInfoKey(tankInfo.AccountId, tankInfo.TankId)), + tankInfo, + new ReplaceOptions { IsUpsert = true } + ); + } + + public Task AddTankInfoHistory(TankInfoHistory tankInfoHistory) + { + return _database.GetCollection(TankInfoHistoryCollectionName) + .InsertOneAsync(tankInfoHistory); + } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs index 55c5246..5ad16e0 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs @@ -17,7 +17,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations public Task Invoke(AccountInformationPipelineContext context, Func next) { if (context.DbAccountInfo == null || - context.DbAccountInfo.LastBattleTime >= context.AccountInfo.LastBattleTime) + context.DbAccountInfo.LastBattleTime < context.AccountInfo.LastBattleTime) { return next.Invoke(context); } diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs index 1029bd8..8dc262b 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs @@ -30,10 +30,8 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations context.AccountInfo = _mapper.Map(accountInfo); context.AccountInfo.Realm = context.RealmType; - context.AccountInfoHistory = - _mapper.Map(accountInfo.Statistics.All); - context.AccountInfoHistory.AccountId = context.AccountId; - context.AccountInfoHistory.LastBattleTime = context.AccountInfo.LastBattleTime; + context.AccountInfoHistory = new AccountInfoHistory(context.AccountId, context.AccountInfo.LastBattleTime); + _mapper.Map(accountInfo.Statistics.All, context.AccountInfoHistory); await next.Invoke(context); } diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs index 187a6d3..9b67fbd 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs @@ -32,11 +32,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations tanksInfo.ForEach(tank => { - context.Tanks.Add(_mapper.Map(tank)); - var stat = _mapper.Map(tank.All); - stat.AccountId = tank.AccountId; - stat.TankId = tank.TankId; - stat.LastBattleTime = tank.LastBattleTime; + var tankInfo = new TankInfo(tank.AccountId, tank.TankId); + _mapper.Map(tank, tankInfo); + context.Tanks.Add(tankInfo); + var stat = new TankInfoHistory(tank.AccountId, tank.TankId, tank.LastBattleTime); + _mapper.Map(tank.All, stat); context.TanksHistory[stat.TankId] = stat; }); diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs new file mode 100644 index 0000000..ad24975 --- /dev/null +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using WotBlitzStatisticsPro.DataAccess; +using WotBlitzStatisticsPro.Logic.Pipeline; + +namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations +{ + public class SaveAccountAndTanksOperation : IOperation + { + private readonly IWargamingAccountDataAccessor _accountDataAccessor; + private readonly ILogger _logger; + + public SaveAccountAndTanksOperation( + IWargamingAccountDataAccessor accountDataAccessor, + ILogger logger) + { + _accountDataAccessor = accountDataAccessor; + _logger = logger; + } + + public async Task Invoke(AccountInformationPipelineContext context, Func next) + { + await _accountDataAccessor.AddOurUpdateAccountInfo(context.AccountInfo); + await _accountDataAccessor.AddAccountInfoHistory(context.AccountInfoHistory); + + var tanksCount = 0; + var tankIdsAsString = new StringBuilder(); + + foreach (var tankInfo in context.Tanks) + { + var tankFromDb = await _accountDataAccessor.ReadTankInfo(tankInfo.AccountId, tankInfo.TankId); + if (tankFromDb == null || tankInfo.LastBattleTime > tankFromDb.LastBattleTime) + { + await _accountDataAccessor.AddOrUpdateTankInfo(tankInfo); + await _accountDataAccessor.AddTankInfoHistory(context.TanksHistory[tankInfo.TankId]); + tanksCount++; + tankIdsAsString.Append($" {tankInfo.TankId}; "); + } + } + + _logger.LogInformation($"Updated account {context.AccountInfo.AccountId} and {tanksCount} tanks: {tankIdsAsString}"); + + await next.Invoke(context); + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs index ec679ac..c51bed5 100644 --- a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs +++ b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs @@ -43,7 +43,7 @@ namespace WotBlitzStatisticsPro.Logic .AddOperation() .AddOperation() .AddOperation() - // ToDo: add operation for save info into DB + .AddOperation() .AddOperation() ; diff --git a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs index d576714..f81d029 100644 --- a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs +++ b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs @@ -65,6 +65,7 @@ namespace WotBlitzStatisticsPro.Logic services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(serviceProvider => new ServiceProviderOperationFactory(serviceProvider));