public void TestDifference() { var mapCli = new NewsMap { channelIds = new[] {1, 3}, records = new[] { new NewsMapRecord(new DateTime(2013, 12, 2), 141), new NewsMapRecord(new DateTime(2013, 12, 3), 102), new NewsMapRecord(new DateTime(2013, 12, 4), 151), new NewsMapRecord(new DateTime(2013, 12, 5), 151), new NewsMapRecord(new DateTime(2013, 12, 6), 150), } }; var mapSrv = MakeTestMap(); NewsMap mapDiff = null; try { mapDiff = mapCli.MakeMapOfLackedNews(mapSrv); } catch (Exception ex) { Assert.Fail("Failed to make NewsMap diff: {0}", ex); } Assert.AreEqual(5, mapDiff.channelIds[0], "lacked channels"); Assert.AreEqual(3, mapDiff.records.Length, "records lacked - count is OK"); }
public static NewsMap LoadFromFile(string path) { if (!File.Exists(path)) return null; var doc = new XmlDocument(); try { doc.Load(path); } catch (Exception ex) { Logger.Error("NewsMap.LoadFromFile() error: ", ex); return null; } if (doc.DocumentElement == null) return null; var map = new NewsMap(); var records = new List<NewsMapRecord>(); map.channelIds = doc.DocumentElement.GetAttributeString("channels").ToIntArrayUniform(); foreach (XmlElement node in doc.DocumentElement) { DateTime date; if (!DateTime.TryParseExact(node.GetAttributeString("date"), "ddMMyyyy", CultureProvider.Common, DateTimeStyles.None, out date)) continue; var count = node.GetAttributeString("records", "0").ToIntSafe() ?? 0; records.Add(new NewsMapRecord { date = date, recordsCount = count }); } map.records = records.ToArray(); return map; }
public NewsMap GetNewsMap(int accountId) { var map = new NewsMap { channelIds = new int[0], records = new NewsMapRecord[0] }; if (!channelsByAccount.ContainsKey(accountId)) return map; map.channelIds = channelsByAccount[accountId]; // посчитать количество записей на дату var records = new Dictionary<DateTime, NewsMapRecord>(); foreach (var chan in map.channelIds) { var list = newsByChannel[chan]; foreach (var news in list) { var date = news.Time.Date; if (!records.ContainsKey(date)) records.Add(date, new NewsMapRecord(date, 1)); else records[date] = new NewsMapRecord(date, records[date].recordsCount + 1); } } map.records = records.Values.OrderBy(r => r.date).ToArray(); return map; }
public bool AreSame(NewsMap map) { if (map.channelIds.Length != channelIds.Length || map.records.Length != records.Length) return false; if (!map.channelIds.SequenceEqual(channelIds)) return false; if (!map.records.SequenceEqual(records)) return false; return true; }
public NewsMap MakeMapOfLackedNews(NewsMap serverMap) { var resulted = new NewsMap { channelIds = serverMap.channelIds.Where(channelId => !channelIds.Any(id => id == channelId)).ToArray(), records = (from record in serverMap.records let existRec = records.FirstOrDefault(r => r.date == record.date) where existRec.recordsCount < record.recordsCount select record).ToArray() }; return(resulted); }
private NewsCache() { syncCompletedEvent = new ManualResetEventSlim(false); mapPath = NewsLocalStorage.newsPath + "\\news_map.xml"; NewsLocalStorage.Instance.EnsureNewsPath(); // подкачать карту новостей (канал - дата - количество новостей) map = NewsMap.LoadFromFile(mapPath) ?? new NewsMap { channelIds = new int[0], records = new NewsMapRecord[0] }; }
public bool AreSame(NewsMap map) { if (map.channelIds.Length != channelIds.Length || map.records.Length != records.Length) { return(false); } if (!map.channelIds.SequenceEqual(channelIds)) { return(false); } if (!map.records.SequenceEqual(records)) { return(false); } return(true); }
public static NewsMap LoadFromFile(string path) { if (!File.Exists(path)) { return(null); } var doc = new XmlDocument(); try { doc.Load(path); } catch (Exception ex) { Logger.Error("NewsMap.LoadFromFile() error: ", ex); return(null); } if (doc.DocumentElement == null) { return(null); } var map = new NewsMap(); var records = new List <NewsMapRecord>(); map.channelIds = doc.DocumentElement.GetAttributeString("channels").ToIntArrayUniform(); foreach (XmlElement node in doc.DocumentElement) { DateTime date; if (!DateTime.TryParseExact(node.GetAttributeString("date"), "ddMMyyyy", CultureProvider.Common, DateTimeStyles.None, out date)) { continue; } var count = node.GetAttributeString("records", "0").ToIntSafe() ?? 0; records.Add(new NewsMapRecord { date = date, recordsCount = count }); } map.records = records.ToArray(); return(map); }
private void ActualizeSync(object accountIdObj) { var totalNews = 0; try { if (isTerminating) return; var accountId = (int)accountIdObj; if (accountId == 0) { var accountData = AccountStatus.Instance.AccountData; if (accountData != null) accountId = accountData.ID; if (accountId == 0) return; } // получить от сервера карту новостей NewsMap serverNewsMap = null; try { using (var proxy = new NewsStorageProxy(TerminalBindings.BindingNewsStorage)) { serverNewsMap = proxy.GetNewsMap(accountId); } } catch (Exception ex) { Logger.ErrorFormat("NewsCache({0}) - ошибка получения карты новостей: {1}", accountId, ex); } if (serverNewsMap == null) return; if (isTerminating) return; // сформировать список каналов / дат, на которые нужно подкачать новости var lackMap = map.MakeMapOfLackedNews(serverNewsMap); if (lackMap.records.Length == 0 || serverNewsMap.channelIds.Length == 0) return; // подкачать новости по указанным каналам за указанные даты var numFailsLeft = StopAskingServerAfterFails + 1; using (var proxy = new NewsStorageProxy(TerminalBindings.BindingNewsStorage)) foreach (var rec in lackMap.records) { if (isTerminating) break; try { var news = proxy.GetNews(accountId, rec.date, serverNewsMap.channelIds); if (news == null || news.Count == 0) continue; totalNews += news.Count; // обновить кеш новостей NewsLocalStorage.Instance.UpdateNews(news); } catch (Exception ex) { numFailsLeft--; if (numFailsLeft == 0) break; Logger.Error("Ошибка в NewsCache.ActualizeSync()", ex); } } // сохранить кешированные новости NewsLocalStorage.Instance.SaveNewsInFiles(); // обновить карту новостей map = NewsLocalStorage.Instance.MakeNewsMap(); //serverNewsMap; map.SaveInFile(mapPath); } finally { syncCompletedEvent.Set(); } if (actualizationCompleted != null && !isTerminating) actualizationCompleted(totalNews); }
public NewsMap MakeMapOfLackedNews(NewsMap serverMap) { var resulted = new NewsMap { channelIds = serverMap.channelIds.Where(channelId => !channelIds.Any(id => id == channelId)).ToArray(), records = (from record in serverMap.records let existRec = records.FirstOrDefault(r => r.date == record.date) where existRec.recordsCount < record.recordsCount select record).ToArray() }; return resulted; }
public NewsMap GetNewsMap(int accountId) { var channels = GetChannelsByAccount(accountId); if (channels == null) return null; var map = new NewsMap { channelIds = channels.ToArray() }; // сформировать записи - дата - количество новостей по указанным каналам // запрос вида // select DateNews, COUNT(*) as Count from NEWS where Channel = 1 group by DateNews order by DateNews try { using (var cn = new SqlConnection(connectionString)) { cn.Open(); DbCommand cmd = cn.CreateCommand(); cmd.Connection = cn; cmd.CommandText = string.Format("select DateNews, COUNT(*) as Count" + " from NEWS where Channel in ({0}) group by DateNews order by DateNews", string.Join(",", channels)); using (var dr = cmd.ExecuteReader()) { var recordsList = new List<NewsMapRecord>(); while (dr.Read()) { recordsList.Add(new NewsMapRecord((DateTime)dr["DateNews"], (int)dr["Count"])); } map.records = recordsList.ToArray(); } } } catch (Exception ex) { Logger.Error("DbNewsStorage.GetNewsMap: возникла ошибка ", ex); return null; } return map; }