private void FillPlayerGameInfoTable() { if (!Schema.Table(handRecordsTableName).Exists()) { return; } using (var session = ModelEntities.OpenStatelessSession()) { using (var transaction = session.BeginTransaction()) { var sqlQuery = session .CreateSQLQuery($@"insert into {playerGameInfoTableName} (PlayerId, GameInfoId) select PlayerId, GameInfoId from {handRecordsTableName} group by PlayerId, GameInfoId"); var result = sqlQuery.ExecuteUpdate(); LogProvider.Log.Info($"Inserted {result} rows into '{playerGameInfoTableName}'"); transaction.Commit(); } } }
protected void CleanUpDatabase() { using (var perfScope = new PerformanceMonitor("CleanUpDatabase")) { using (var session = ModelEntities.OpenStatelessSession()) { using (var transaction = session.BeginTransaction()) { // order is important because of foreign keys var tablesToCleanUp = new string[] { "Tournaments", "HandNotes", "PlayerGameInfo", "HandsPlayers", "PlayerNotes", "HandHistories", "GameInfo", "Players", }; tablesToCleanUp.ForEach(x => session.CreateSQLQuery($"DELETE FROM \"{x}\"").ExecuteUpdate()); transaction.Commit(); } } } }
private void FillPlayerNetWonTable() { if (!Schema.Table(handRecordsTableName).Exists()) { return; } using (var session = ModelEntities.OpenStatelessSession()) { using (var transaction = session.BeginTransaction()) { var currencyId = (int)Currency.USD; var sqlQuery = session .CreateSQLQuery($@"insert into {playerNetWonTableName} (PlayerId, Currency, NetWon) select h.PlayerId, {currencyId}, sum(h.NetWon) from {handRecordsTableName} h join GameInfo g on h.GameInfoId = g.GameInfoId where g.IsTournament = 0 and NetWon <> 0 group by PlayerId"); var result = sqlQuery.ExecuteUpdate(); LogProvider.Log.Info($"Inserted {result} rows into '{playerNetWonTableName}'"); transaction.Commit(); } } }
static void PrepareStatisticMigration() { Console.WriteLine("Preparing to migration"); Console.WriteLine("Removing inconsistent"); using (var session = ModelEntities.OpenStatelessSession()) { using (var transation = session.BeginTransaction()) { var players = session.Query <Players>().ToArray(); var playersGrouped = players.GroupBy(x => new { x.Playername, x.PokersiteId }).Select(x => new { PlayerKey = x.Key, Players = x.ToArray() }).ToArray(); var inconsistentPlayes = playersGrouped.Where(x => x.Players.Length > 1).ToArray(); inconsistentPlayes.ForEach(x => { var playersToDelete = x.Players.Skip(1).ToArray(); playersToDelete.ForEach(player => { session.Delete(player); }); }); transation.Commit(); } } }
private void ClearAllNotes() { using (var session = ModelEntities.OpenStatelessSession()) { using (var transaction = session.BeginTransaction()) { session.CreateSQLQuery($"DELETE FROM \"PlayerNotes\" WHERE IsAutoNote=1").ExecuteUpdate(); transaction.Commit(); } } }
public void TournamentsAreImportedForEachPlayer(string tournamentNumber, int expectedCount) { using (var perfScope = new PerformanceMonitor("TournamentsAreImportedForEachPlayer")) { using (var session = ModelEntities.OpenStatelessSession()) { var tournaments = session.Query <Tournaments>() .Where(x => x.Tourneynumber == tournamentNumber) .ToList(); Assert.That(tournaments.Count, Is.EqualTo(expectedCount)); } } }
/// <summary> /// Prepares dictionary with hand numbers and table sizes /// </summary> private void PrepareHandHistoryTableSizeMap() { LogProvider.Log.Info(this, "Loading hand histories map."); using (var session = ModelEntities.OpenStatelessSession()) { handHistoryNumberTableSize = (from handHistory in session.Query <Handhistory>() join gameInfo in session.Query <Gametypes>() on handHistory.GametypeId equals gameInfo.GametypeId let handNumberPokerSiteKey = new HandNumberPokerSiteKey(handHistory.Gamenumber, handHistory.PokersiteId) select new { HandNumberPokerSiteKey = handNumberPokerSiteKey, TableSize = gameInfo.Tablesize }) .ToDictionary(x => x.HandNumberPokerSiteKey, x => x.TableSize); LogProvider.Log.Info(this, $"Loaded {handHistoryNumberTableSize.Count} hand histories."); } }
public void TournamentsTableSizeIsImported(string tournamentNumber, string playerName, int tableSize) { using (var perfScope = new PerformanceMonitor("TournamentsTableSizeIsImported")) { using (var session = ModelEntities.OpenStatelessSession()) { var tournament = session.Query <Tournaments>() .SingleOrDefault(x => x.Tourneynumber == tournamentNumber && x.Player.Playername == playerName); Assert.IsNotNull(tournament, $"Tournament data for '{playerName}' has not been found in tournament '{tournamentNumber}'"); Assert.That(tournament.Tablesize, Is.EqualTo(tableSize), $"Tournament table size doesn't match for '{playerName}' in tournament '{tournamentNumber}' [{(EnumPokerSites)tournament.SiteId}]"); } } }
private void FillHandsPlayersTable() { MigrationUtils.SetStatusMessage("Preparing data for migration"); using (var session = ModelEntities.OpenStatelessSession()) { LogProvider.Log.Info("Preparing data to insert."); var playersId = session.Query <Players>() .Select(x => x.PlayerId).ToArray(); var handsQuery = session.Query <Handhistory>() .Select(x => new { x.HandhistoryId, x.Gamenumber, x.PokersiteId }); var hands = new Dictionary <HandHistoryKey, int>(); foreach (var hand in handsQuery) { var handKey = new HandHistoryKey(hand.Gamenumber, hand.PokersiteId); if (!hands.ContainsKey(handKey)) { hands.Add(handKey, hand.HandhistoryId); } } var statisticFiles = new HashSet <string>(); foreach (var playerId in playersId) { var playerStatsFiles = playerStatisticRepository.GetPlayerFiles(playerId); statisticFiles.AddRange(playerStatsFiles); } var conn = session.Connection as SQLiteConnection; if (fastModeAllowedHands >= hands.Count) { InsertInFastMode(statisticFiles, hands, conn); return; } InsertInLowMemoryMode(statisticFiles, hands, conn); } }
/// <summary> /// Builds players dictionary /// </summary> private void BuildPlayersDictonary() { playersDictionary = new Dictionary <PlayerPokerSiteKey, Players>(); using (var session = ModelEntities.OpenStatelessSession()) { var players = session.Query <Players>().ToArray(); players.ForEach(player => { var playerPokerSiteKey = new PlayerPokerSiteKey(player.Playername, player.PokersiteId); if (!playersDictionary.ContainsKey(playerPokerSiteKey)) { playersDictionary.Add(playerPokerSiteKey, player); } }); } }
/// <summary> /// Truncates the specified table /// </summary> /// <param name="tableName">Table to truncate</param> public static void TruncateTable(string tableName) { LogProvider.Log.Info($"Truncating {tableName}"); try { using (var session = ModelEntities.OpenStatelessSession()) { var sqlQuery = session .CreateSQLQuery($"delete from {tableName}"); sqlQuery.ExecuteUpdate(); } } catch (Exception e) { LogProvider.Log.Error(typeof(MigrationUtils), $"Could not truncate '{tableName}'", e); throw; } }
/// <summary> /// Deletes notes before the specified date /// </summary> /// <param name="sinceDate"></param> public void DeletesNotes(DateTime?beforeDate) { try { using (var session = ModelEntities.OpenStatelessSession()) { using (var transaction = session.BeginTransaction()) { var date = beforeDate.HasValue ? beforeDate : DateTime.MaxValue; var entitiesToDelete = session.Query <Playernotes>().Where(x => x.IsAutoNote && x.Timestamp <= date).ToArray(); LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"Deleting {entitiesToDelete.Length} notes."); var progress = 0; for (var i = 0; i < entitiesToDelete.Length; i++) { session.Delete(entitiesToDelete[i]); var currentProgress = i * 100 / entitiesToDelete.Length; if (progress < currentProgress) { progress = currentProgress; ProgressChanged?.Invoke(this, new NoteProcessingServiceProgressChangedEventArgs(progress)); } } transaction.Commit(); } LogProvider.Log.Info(CustomModulesNames.PlayerXRay, "Notes have been deleted."); } } catch (Exception e) { LogProvider.Log.Error(CustomModulesNames.PlayerXRay, "Notes haven't been deleted.", e); } }
public void ProcessNotes(IEnumerable <NoteObject> notes, CancellationTokenSource cancellationTokenSource) { try { if (!licenseService.IsRegistered || (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested)) { return; } var currentPlayerIds = new HashSet <int>(storageModel.PlayerSelectedItem.PlayerIds); var noteService = ServiceLocator.Current.GetInstance <IPlayerNotesService>() as IPlayerXRayNoteService; var sinceDate = noteService.CurrentNotesAppSettings.IsNoteCreationSinceDate ? noteService.CurrentNotesAppSettings.NoteCreationSinceDate : (DateTime?)null; var isAdvancedLogEnabled = noteService.CurrentNotesAppSettings.IsAdvancedLogEnabled; var takesNotesOnHero = noteService.CurrentNotesAppSettings.TakesNotesOnHero; using (var session = ModelEntities.OpenStatelessSession()) { BuildPlayersDictonary(session); BuildPlayersNotesDictonary(session); var entitiesCount = sinceDate != null? session.Query <Handhistory>().Count(x => x.Handtimestamp >= sinceDate.Value) : session.Query <Handhistory>().Count(); var progressCounter = 0; var progress = 0; var numOfQueries = (int)Math.Ceiling((double)entitiesCount / handHistoryRowsPerQuery); LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"Processing notes [{notes.Count()}] for {entitiesCount} hands."); for (var i = 0; i < numOfQueries; i++) { if (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested) { LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"The note processing has been canceled [{i}/{numOfQueries}]."); break; } using (var pf = new PerformanceMonitor($"Proccesing notes [{i}/{numOfQueries} iteration].", isAdvancedLogEnabled, CustomModulesNames.PlayerXRay)) { var numOfRowToStartQuery = i * handHistoryRowsPerQuery; var handHistories = sinceDate != null? session.Query <Handhistory>() .Where(x => x.Handtimestamp >= sinceDate.Value) .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray() : session.Query <Handhistory>() .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray(); var notesToInsert = new ConcurrentBag <Playernotes>(); Parallel.ForEach(handHistories, handHistory => { try { var parsingResult = ParseHandHistory(handHistory); if (parsingResult != null) { var matchInfo = new GameMatchInfo { GameType = parsingResult.Source.GameDescription.GameType, CashBuyIn = !parsingResult.Source.GameDescription.IsTournament ? Utils.ConvertToCents(parsingResult.Source.GameDescription.Limit.BigBlind) : 0, TournamentBuyIn = parsingResult.Source.GameDescription.IsTournament ? parsingResult.Source.GameDescription.Tournament.BuyIn.PrizePoolValue : 0 }; if (!Limit.IsMatch(matchInfo)) { return; } var playerStatisticCreationInfo = new PlayerStatisticCreationInfo { ParsingResult = parsingResult }; foreach (var player in parsingResult.Players) { // skip notes for current player (need to check setting) if (!takesNotesOnHero && currentPlayerIds.Contains(player.PlayerId)) { continue; } var calculatedEquity = new Dictionary <string, Dictionary <Street, decimal> >(); if (player.PlayerId != 0) { var playerNoteKey = new PlayerPokerSiteKey(player.PlayerId, player.PokersiteId); playerStatisticCreationInfo.Player = player; var playerStatistic = BuildPlayerStatistic(playerStatisticCreationInfo); var playerNotes = ProcessHand(notes, playerStatistic, parsingResult.Source); if (playerNotes.Count() == 0) { continue; } // if player has no notes, then just save all new notes if (!playersNotesDictionary.ContainsKey(playerNoteKey) || (playersNotesDictionary.ContainsKey(playerNoteKey) && !playersNotesDictionary[playerNoteKey].ContainsKey(handHistory.Gamenumber))) { playerNotes.ForEach(note => notesToInsert.Add(note)); continue; } var existingNotes = playersNotesDictionary[playerNoteKey][handHistory.Gamenumber]; var notesToAdd = (from playerNote in playerNotes join existingNote in existingNotes on playerNote.Note equals existingNote.Note into gj from note in gj.DefaultIfEmpty() where note == null select playerNote).ToArray(); notesToAdd.ForEach(note => notesToInsert.Add(note)); } } ; } } catch (Exception hhEx) { LogProvider.Log.Error(CustomModulesNames.PlayerXRay, $"Hand history {handHistory.Gamenumber} has not been processed", hhEx); } // reporting progress progressCounter++; var currentProgress = progressCounter * 100 / entitiesCount; if (progress < currentProgress) { progress = currentProgress; ProgressChanged?.Invoke(this, new NoteProcessingServiceProgressChangedEventArgs(progress)); } }); using (var transaction = session.BeginTransaction()) { notesToInsert.ForEach(x => session.Insert(x)); transaction.Commit(); } } } LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"Notes have been processed."); } } catch (Exception e) { LogProvider.Log.Error(CustomModulesNames.PlayerXRay, "Notes have not been processed.", e); } }
public async Task ExportHands(string folder, IEnumerable <HandExportInfo> exportInfo, IDHProgress progress, bool useCommonExporter) { await Task.Run(() => { try { var handsGroupedBySite = exportInfo .GroupBy(x => x.Site) .ToDictionary(x => x.Key, x => x.Select(p => p.HandNumber).ToArray()); var exportedHands = 0; var totalExportedHands = exportInfo.Count(); LogProvider.Log.Info(this, $"Starting export of {totalExportedHands} hands."); progress.Report(new LocalizableString("Progress_ExportingHands", exportedHands, totalExportedHands), 0); using (var session = ModelEntities.OpenStatelessSession()) { foreach (var siteHands in handsGroupedBySite) { LogProvider.Log.Info(this, $"Exporting {siteHands.Value.Length} hands of {siteHands.Key} site."); var serviceName = useCommonExporter ? HandExportPreparingServiceProvider.Common : HandExportPreparingServiceProvider.GetServiceName(siteHands.Key); var preparingService = ServiceLocator.Current.GetInstance <IHandExportPreparingService>(serviceName); var queriesCount = (int)Math.Ceiling((double)siteHands.Value.Length / HandPerQuery); for (var i = 0; i < queriesCount; i++) { if (progress.CancellationToken.IsCancellationRequested) { LogProvider.Log.Info(this, "Exporting cancelled by user."); LogProvider.Log.Info(this, $"Successfully exported {exportedHands} hands."); return; } var handsToQuery = siteHands.Value.Skip(i *HandPerQuery).Take(HandPerQuery).ToArray(); var restriction = Restrictions.Disjunction(); restriction.Add(Restrictions.Conjunction() .Add(Restrictions.On <Handhistory>(x => x.Gamenumber).IsIn(handsToQuery)) .Add(Restrictions.Where <Handhistory>(x => x.PokersiteId == (short)siteHands.Key))); var hands = session.QueryOver <Handhistory>().Where(restriction) .Select(x => x.HandhistoryVal) .List <string>(); preparingService.WriteHandsToFile(folder, hands, siteHands.Key); exportedHands += hands.Count; progress.Report(new LocalizableString("Progress_ExportingHands", exportedHands, exportInfo.Count()), 0); } } } LogProvider.Log.Info(this, $"Successfully exported {exportedHands} hands."); } catch (Exception e) { throw new DHInternalException(new NonLocalizableString("Export service failed to export hands."), e); } }); }
/// <summary> /// Imports hand histories stored in DB /// </summary> private void ImportHandHistories() { using (var session = ModelEntities.OpenStatelessSession()) { var entitiesCount = session.Query <Handhistory>().Count(); var numOfQueries = (int)Math.Ceiling((double)entitiesCount / handHistoryRowsPerQuery); progress?.Report(new LocalizableString("Progress_RebuildingStatistics_Status", 0, entitiesCount)); var progressResult = 0; for (var i = 0; i < numOfQueries; i++) { var numOfRowToStartQuery = i * handHistoryRowsPerQuery; var handHistories = session.Query <Handhistory>() .OrderBy(x => x.Handtimestamp) .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray(); // close opened handles var minDateOfHand = handHistories.MinOrDefault(x => x.Handtimestamp); if (minDateOfHand.HasValue) { ClosePlayerstatisticStreams(minDateOfHand.Value); } Parallel.ForEach(handHistories, handHistory => { var parsingResult = ParseHandHistory(handHistory); if (parsingResult != null) { var playerStatisticCreationInfo = new PlayerStatisticCreationInfo { ParsingResult = parsingResult }; parsingResult.Players.ForEach(player => { var calculatedEquity = new Dictionary <string, Dictionary <Street, decimal> >(); if (player.PlayerId != 0) { playerStatisticCreationInfo.Player = player; BuildPlayerStatistic(handHistory, playerStatisticCreationInfo); } }); } }); GC.Collect(); progressResult += handHistories.Length; progress?.Report(new LocalizableString("Progress_RebuildingStatistics_Status", progressResult, entitiesCount)); } } }