bool CEpg::Load(void) { bool bReturn = false; CSingleLock lock(m_critSection); CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "Epg - %s - could not open the database", __FUNCTION__); return bReturn; } int iEntriesLoaded = database->Get(this); if (iEntriesLoaded <= 0) { CLog::Log(LOGNOTICE, "Epg - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); } else { CLog::Log(LOGDEBUG, "Epg - %s - %d entries loaded for table '%s'.", __FUNCTION__, size(), m_strName.c_str()); Sort(); bReturn = true; } database->Close(); return bReturn; }
bool CEpgInfoTag::Persist(bool bSingleUpdate /* = true */) { bool bReturn = false; #if EPG_DEBUGGING CLog::Log(LOGDEBUG, "Epg - %s - Infotag '%s' %s, persisting...", __FUNCTION__, m_strTitle.c_str(), m_iBroadcastId > 0 ? "has changes" : "is new"); #endif CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || (bSingleUpdate && !database->IsOpen())) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return bReturn; } int iId = database->Persist(*this, bSingleUpdate); if (iId >= 0) { bReturn = true; if (iId > 0) m_iBroadcastId = iId; } return bReturn; }
bool CEpgInfoTag::Persist(bool bSingleUpdate /* = true */, bool bLastUpdate /* = false */) { bool bReturn = false; if (!m_bChanged) return true; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return bReturn; } int iId = database->Persist(*this, bSingleUpdate, bLastUpdate); if (iId >= 0) { bReturn = true; if (iId > 0) { m_iBroadcastId = iId; m_bChanged = false; } } database->Close(); return bReturn; }
CDateTime CEpg::GetLastScanTime(void) { CDateTime lastScanTime; { CSingleLock lock(m_critSection); if (!m_lastScanTime.IsValid()) { if (!CSettings::Get().GetBool("epg.ignoredbforclient")) { CEpgDatabase *database = g_EpgContainer.GetDatabase(); CDateTime dtReturn; dtReturn.SetValid(false); if (database && database->IsOpen()) database->GetLastEpgScanTime(m_iEpgID, &m_lastScanTime); } if (!m_lastScanTime.IsValid()) { m_lastScanTime.SetDateTime(0, 0, 0, 0, 0, 0); m_lastScanTime.SetValid(true); } } lastScanTime = m_lastScanTime; } return m_lastScanTime; }
bool CEpg::PersistTags(void) const { bool bReturn = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "EPG - %s - could not load the database", __FUNCTION__); return bReturn; } time_t iStart, iEnd; GetFirstDate().GetAsTime(iStart); GetLastDate().GetAsTime(iEnd); database->Delete(*this, iStart, iEnd); if (size() > 0) { for (unsigned int iTagPtr = 0; iTagPtr < size(); iTagPtr++) bReturn = at(iTagPtr)->Persist() && bReturn; } else { /* Return true if we have no tags, so that no error is logged */ bReturn = true; } return bReturn; }
bool CEpg::Load(void) { bool bReturn(false); CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->IsOpen()) { CLog::Log(LOGERROR, "EPG - %s - could not open the database", __FUNCTION__); return bReturn; } CSingleLock lock(m_critSection); int iEntriesLoaded = database->Get(*this); if (iEntriesLoaded <= 0) { CLog::Log(LOGDEBUG, "EPG - %s - no database entries found for table '%s'.", __FUNCTION__, m_strName.c_str()); } else { m_lastScanTime = GetLastScanTime(); #if EPG_DEBUGGING CLog::Log(LOGDEBUG, "EPG - %s - %d entries loaded for table '%s'.", __FUNCTION__, (int) m_tags.size(), m_strName.c_str()); #endif bReturn = true; } m_bLoaded = true; return bReturn; }
CDateTime CEpg::GetLastScanTime(void) { CDateTime lastScanTime; { CSingleLock lock(m_critSection); if (!m_lastScanTime.IsValid()) { if (!CSettings::GetInstance().GetBool(CSettings::SETTING_EPG_IGNOREDBFORCLIENT)) { CEpgDatabase *database = g_EpgContainer.GetDatabase(); CDateTime dtReturn; dtReturn.SetValid(false); if (database && database->IsOpen()) database->GetLastEpgScanTime(m_iEpgID, &m_lastScanTime); } if (!m_lastScanTime.IsValid()) { m_lastScanTime.SetDateTime(1970, 1, 1, 0, 0, 0); assert(m_lastScanTime.IsValid()); } } lastScanTime = m_lastScanTime; } return m_lastScanTime; }
const CDateTime &CEpg::GetLastScanTime(void) { CSingleLock lock(m_critSection); if (!m_lastScanTime.IsValid()) { if (!g_guiSettings.GetBool("epg.ignoredbforclient")) { CEpgDatabase *database = g_EpgContainer.GetDatabase(); CDateTime dtReturn; dtReturn.SetValid(false); if (database && database->Open()) { database->GetLastEpgScanTime(m_iEpgID, &m_lastScanTime); database->Close(); } } if (!m_lastScanTime.IsValid()) { m_lastScanTime.SetDateTime(0, 0, 0, 0, 0, 0); m_lastScanTime.SetValid(true); } } return m_lastScanTime; }
bool CEpg::Persist(bool bPersistTags /* = false */, bool bQueueWrite /* = false */) { bool bReturn = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return bReturn; } CSingleLock lock(m_critSection); int iId = database->Persist(*this, bQueueWrite); if (iId >= 0) { if (iId > 0) m_iEpgID = iId; if (bPersistTags) bReturn = PersistTags(bQueueWrite); else bReturn = true; } database->Close(); return bReturn; }
bool CEpg::UpdateEntries(const CEpg &epg, bool bStoreInDb /* = true */) { bool bReturn(false); CEpgDatabase *database = g_EpgContainer.GetDatabase(); CSingleLock lock(m_critSection); if (epg.size() > 0) { if (bStoreInDb) { if (!database || !database->Open()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return bReturn; } database->BeginTransaction(); } CLog::Log(LOGDEBUG, "%s - %u entries in memory before merging", __FUNCTION__, size()); /* copy over tags */ for (unsigned int iTagPtr = 0; iTagPtr < epg.size(); iTagPtr++) { UpdateEntry(*epg.at(iTagPtr), bStoreInDb, false); } Sort(); CLog::Log(LOGDEBUG, "%s - %u entries in memory after merging and before fixing", __FUNCTION__, size()); FixOverlappingEvents(bStoreInDb); m_nowActive = NULL; CLog::Log(LOGDEBUG, "%s - %u entries in memory after fixing", __FUNCTION__, size()); /* update the last scan time of this table */ m_lastScanTime = CDateTime::GetCurrentDateTime().GetAsUTCDateTime(); /* update the first and last date */ UpdateFirstAndLastDates(); //m_bTagsChanged = true; /* persist changes */ if (bStoreInDb) { bReturn = database->CommitTransaction(); database->Close(); if (bReturn) Persist(true); } else bReturn = true; } else { if (bStoreInDb) bReturn = Persist(true); else bReturn = true; } return bReturn; }
bool CEpg::UpdateEntries(const CEpg &epg, bool bStoreInDb /* = true */) { bool bReturn(false); CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (epg.m_tags.size() > 0) { if (bStoreInDb) { if (!database || !database->IsOpen()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return bReturn; } database->BeginTransaction(); } { CSingleLock lock(m_critSection); CLog::Log(LOGDEBUG, "%s - %zu entries in memory before merging", __FUNCTION__, m_tags.size()); /* copy over tags */ for (map<CDateTime, CEpgInfoTagPtr>::const_iterator it = epg.m_tags.begin(); it != epg.m_tags.end(); it++) UpdateEntry(*it->second, bStoreInDb, false); CLog::Log(LOGDEBUG, "%s - %zu entries in memory after merging and before fixing", __FUNCTION__, m_tags.size()); FixOverlappingEvents(bStoreInDb); CLog::Log(LOGDEBUG, "%s - %zu entries in memory after fixing", __FUNCTION__, m_tags.size()); /* update the last scan time of this table */ m_lastScanTime = CDateTime::GetCurrentDateTime().GetAsUTCDateTime(); SetChanged(); } /* persist changes */ if (bStoreInDb) { bReturn = database->CommitTransaction(); if (bReturn) Persist(true); } else bReturn = true; } else { if (bStoreInDb) bReturn = Persist(true); else bReturn = true; } NotifyObservers(ObservableMessageEpg); return bReturn; }
bool CEpg::FixOverlappingEvents(bool bUpdateDb /* = false */) { bool bReturn(false); CEpgInfoTag *previousTag(NULL), *currentTag(NULL); CEpgDatabase *database = g_EpgContainer.GetDatabase(); for (int iPtr = size() - 1; iPtr >= 0; iPtr--) { if (!previousTag) { previousTag = at(iPtr); continue; } currentTag = at(iPtr); if (previousTag->StartAsUTC() <= currentTag->StartAsUTC()) { if (bUpdateDb) { if (!database || !database->Open()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); bReturn = false; continue; } bReturn = database->Delete(*currentTag); } else bReturn = true; if (m_nowActive && *m_nowActive == *currentTag) m_nowActive = NULL; delete currentTag; erase(begin() + iPtr); } else if (previousTag->StartAsUTC() < currentTag->EndAsUTC()) { currentTag->SetEndFromUTC(previousTag->StartAsUTC()); if (bUpdateDb) bReturn = currentTag->Persist(); else bReturn = true; previousTag = at(iPtr); } else { previousTag = at(iPtr); } } return bReturn; }
bool CEpg::FixOverlappingEvents(bool bStore /* = true */) { bool bReturn = false; CEpgDatabase *database = NULL; if (bStore) { database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "EPG - %s - could not open the database", __FUNCTION__); return bReturn; } } bReturn = true; CEpgInfoTag *previousTag = NULL; CSingleLock lock(m_critSection); for (unsigned int ptr = 0; ptr < size(); ptr++) { /* skip the first entry or if previousTag is NULL */ if (previousTag == NULL) { previousTag = at(ptr); continue; } CEpgInfoTag *currentTag = at(ptr); /* the previous tag ends after the current tag starts. * the start time of the current tag is leading, so change the time of the previous tag */ if (previousTag->End() > currentTag->Start()) { CLog::Log(LOGDEBUG, "EPG - %s - event '%s' ends after event '%s' starts. changing the end time of '%s' to the start time of '%s': '%s'", __FUNCTION__, previousTag->Title().c_str(), currentTag->Title().c_str(), previousTag->Title().c_str(), currentTag->Title().c_str(), currentTag->Start().GetAsLocalizedDateTime(false, false).c_str()); previousTag->SetEnd(currentTag->Start()); if (bStore) bReturn = previousTag->Persist(false, false) && bReturn; } previousTag = at(ptr); } return bReturn; }
bool CEpg::Update(time_t start, time_t end, int iUpdateTime, bool bStoreInDb /* = true */) { bool bGrabSuccess = true; bool bUpdate = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (bStoreInDb && (!database || !database->Open())) { CLog::Log(LOGERROR, "Epg - %s - cannot open the database", __FUNCTION__); return false; } CSingleLock lock(m_critSection); /* get the last update time from the database */ if (!m_lastScanTime.IsValid() && bStoreInDb) database->GetLastEpgScanTime(m_iEpgID, &m_lastScanTime); /* check if we have to update */ time_t iNow = 0; time_t iLastUpdate = 0; CDateTime::GetCurrentDateTime().GetAsTime(iNow); m_lastScanTime.GetAsTime(iLastUpdate); bUpdate = (iNow > iLastUpdate + iUpdateTime); if (bUpdate) { m_bInhibitSorting = true; bGrabSuccess = UpdateFromScraper(start, end); m_bInhibitSorting = false; /* store the loaded EPG entries in the database */ if (bGrabSuccess && size() > 0) { Sort(); FixOverlappingEvents(false); if (bStoreInDb) { database->PersistLastEpgScanTime(m_iEpgID, true); database->Persist(*this, true); PersistTags(true); database->CommitInsertQueries(); } m_lastScanTime = CDateTime::GetCurrentDateTime(); } else { m_lastScanTime = CDateTime::GetCurrentDateTime() - CDateTimeSpan(0, 0, 0, iUpdateTime + 300); /* try again in 5 minutes */ } } if (bStoreInDb) database->Close(); return bGrabSuccess; }
bool CEpg::PersistTags(void) const { bool bReturn = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->IsOpen()) { CLog::Log(LOGERROR, "EPG - %s - could not load the database", __FUNCTION__); return bReturn; } CDateTime first = GetFirstDate(); CDateTime last = GetLastDate(); time_t iStart(0), iEnd(0); if (first.IsValid()) first.GetAsTime(iStart); if (last.IsValid()) last.GetAsTime(iEnd); database->Delete(*this, iStart, iEnd); if (m_tags.size() > 0) { for (map<CDateTime, CEpgInfoTag *>::const_iterator it = m_tags.begin(); it != m_tags.end(); it++) { if (!it->second->Persist()) { CLog::Log(LOGERROR, "failed to persist epg tag %d", it->second->UniqueBroadcastID()); bReturn = false; } } } else { /* Return true if we have no tags, so that no error is logged */ bReturn = true; } return bReturn; }
bool CEpg::PersistTags(bool bQueueWrite /* = false */) const { bool bReturn = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "EPG - %s - could not load the database", __FUNCTION__); return bReturn; } for (unsigned int iTagPtr = 0; iTagPtr < size(); iTagPtr++) { at(iTagPtr)->Persist(false); } if (!bQueueWrite) bReturn = database->CommitInsertQueries(); else bReturn = true; return bReturn; }
bool CEpg::Persist(bool bUpdateLastScanTime /* = false */) { if (g_guiSettings.GetBool("epg.ignoredbforclient")) return true; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->Open()) { CLog::Log(LOGERROR, "%s - could not open the database", __FUNCTION__); return false; } CEpg epgCopy; { CSingleLock lock(m_critSection); epgCopy = *this; m_bChanged = false; m_bTagsChanged = false; } database->BeginTransaction(); if (epgCopy.m_iEpgID <= 0 || epgCopy.m_bChanged) { int iId = database->Persist(epgCopy); if (iId > 0) { epgCopy.m_iEpgID = iId; epgCopy.m_bChanged = false; if (m_iEpgID != epgCopy.m_iEpgID) { CSingleLock lock(m_critSection); m_iEpgID = epgCopy.m_iEpgID; } } } bool bReturn(true); if (bUpdateLastScanTime) bReturn = database->PersistLastEpgScanTime(epgCopy.m_iEpgID); database->CommitTransaction(); database->Close(); return bReturn; }
bool CEpg::Persist(void) { if (CSettings::GetInstance().GetBool(CSettings::SETTING_EPG_IGNOREDBFORCLIENT) || !NeedsSave()) return true; #if EPG_DEBUGGING CLog::Log(LOGDEBUG, "persist table '%s' (#%d) changed=%d deleted=%d", Name().c_str(), m_iEpgID, m_changedTags.size(), m_deletedTags.size()); #endif CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (!database || !database->IsOpen()) { CLog::Log(LOGERROR, "EPG - %s - could not open the database", __FUNCTION__); return false; } { CSingleLock lock(m_critSection); if (m_iEpgID <= 0 || m_bChanged) { int iId = database->Persist(*this, m_iEpgID > 0); if (iId > 0) m_iEpgID = iId; } for (std::map<int, CEpgInfoTagPtr>::iterator it = m_deletedTags.begin(); it != m_deletedTags.end(); ++it) database->Delete(*it->second); for (std::map<int, CEpgInfoTagPtr>::iterator it = m_changedTags.begin(); it != m_changedTags.end(); ++it) it->second->Persist(false); if (m_bUpdateLastScanTime) database->PersistLastEpgScanTime(m_iEpgID, true); m_deletedTags.clear(); m_changedTags.clear(); m_bChanged = false; m_bTagsChanged = false; m_bUpdateLastScanTime = false; } return database->CommitInsertQueries(); }