#include #include "../maintenance.h" #include #include #include #include #include #include class SiNetworkInformationMerger : public SiNetworkInformationParser { public: SiNetworkInformationMerger(DatabaseClient * co) : commonObjects(co) { } bool HandleTable(DVBSI::NetworkPtr n) { Logger()->messagebf(LOG_DEBUG, "Network Id: %d Name: %s", n->NetworkId, *n->Name); for (const auto & ts : n->TransportStreams) { Logger()->messagebf(LOG_DEBUG, "\tTransport Stream Id: %d Original Network Id: %d", ts->TransportStreamId, ts->OriginalNetworkId); for (const auto & s : ts->Services) { Logger()->messagebf(LOG_DEBUG, "\t\tService Id: %d Service Type: %d", s.ServiceId, s.Type); } if (ts->Terrestrial) { Logger()->messagebf(LOG_DEBUG, "\t\tDVB-T: Frequency: %d", ts->Terrestrial->Frequency); } } DatabaseClient::TxHelper tx(commonObjects); SqlMergeTask mergeNetwork("postgres", "networks"); auto ncs = CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeNetwork, _1, _2)); std::vector networks = { n }; mergeNetwork.sources.insert(new ContainerIterator>(&networks, ncs)); mergeNetwork.loadComplete(commonObjects); mergeNetwork.execute(NULL); SqlMergeTask mergeTransports("postgres", "transportstreams"); auto tscs = CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeTransports, _1, _2)); mergeTransports.sources.insert(new ContainerIterator(&n->TransportStreams, tscs)); mergeTransports.loadComplete(commonObjects); mergeTransports.execute(NULL); mergeDelivery("delivery_dvbt", n); mergeDelivery("delivery_dvbs", n); mergeDelivery("delivery_dvbc", n); SqlMergeTask mergeServices("postgres", "services"); auto scs = CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeServices, _1, _2)); for (const auto & s : n->TransportStreams) { mergeServices.sources.insert(new ContainerIterator(&s->Services, scs)); } mergeServices.loadComplete(commonObjects); mergeServices.execute(NULL); return false; } private: template void mergeDelivery(const std::string & table, DVBSI::NetworkPtr n) { SqlMergeTask merge("postgres", table); auto dcs = CreateColumns(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &merge, _1, _2)); std::vector dels; for (const auto & s : n->TransportStreams) { if (auto d = s.get()->*member) { dels.push_back(d); } } merge.sources.insert(new ContainerIterator(&dels, dcs)); merge.loadComplete(commonObjects); merge.execute(NULL); } DatabaseClient * commonObjects; }; void Maintenance::UpdateNetwork(short type, const Ice::Current & ice) { auto ic = ice.adapter->getCommunicator(); auto devs = P2PVR::DevicesPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("GlobalDevices"))); auto si = P2PVR::SIPrx::checkedCast(ice.adapter->createProxy(ic->stringToIdentity("SI"))); auto siparser = new SiNetworkInformationMerger(this); TemporarayIceAdapterObject parser(ice.adapter, siparser); if (!devs) { throw std::runtime_error("bad proxy(s)"); } auto transport = si->GetDeliveryForSi(); if (transport) { P2PVR::TunerPrx tuner; try { tuner = devs->GetTunerAny(transport); tuner->SendNetworkInformation(parser); devs->ReleaseTuner(tuner); return; } catch (const P2PVR::NoSuitableDeviceAvailable &) { Logger()->messagebf(LOG_WARNING, "%s: Failed to get a suitable tuner", __PRETTY_FUNCTION__); throw; } catch (const std::exception & ex) { Logger()->messagebf(LOG_WARNING, "%s: Failed to fetch network information: %s", __PRETTY_FUNCTION__, ex.what()); devs->ReleaseTuner(tuner); throw; } catch (...) { Logger()->messagebf(LOG_WARNING, "%s: Failed to fetch network information", __PRETTY_FUNCTION__); devs->ReleaseTuner(tuner); throw; } } // If we can't do that, do a complete scan auto tuner = devs->GetPrivateTuner(type); tuner->ScanAndSendNetworkInformation(parser); devs->ReleaseTuner(tuner); }