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();
                }
            }
        }
Пример #2
0
        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();
                }
            }
        }
Пример #4
0
        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();
                }
            }
        }
Пример #5
0
 private void ClearAllNotes()
 {
     using (var session = ModelEntities.OpenStatelessSession())
     {
         using (var transaction = session.BeginTransaction())
         {
             session.CreateSQLQuery($"DELETE FROM \"PlayerNotes\" WHERE IsAutoNote=1").ExecuteUpdate();
             transaction.Commit();
         }
     }
 }
Пример #6
0
        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));
                }
            }
        }
Пример #7
0
        /// <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.");
            }
        }
Пример #8
0
        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}]");
                }
            }
        }
Пример #9
0
        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);
                    }
                });
            }
        }
Пример #11
0
        /// <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;
            }
        }
Пример #12
0
        /// <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);
            }
        }
Пример #13
0
        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);
            }
        }
Пример #14
0
        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));
                }
            }
        }