diff options
Diffstat (limited to 'p2pvr/daemon/schedules.cpp')
-rw-r--r-- | p2pvr/daemon/schedules.cpp | 228 |
1 files changed, 47 insertions, 181 deletions
diff --git a/p2pvr/daemon/schedules.cpp b/p2pvr/daemon/schedules.cpp index dab3917..5e3881d 100644 --- a/p2pvr/daemon/schedules.cpp +++ b/p2pvr/daemon/schedules.cpp @@ -1,18 +1,22 @@ #include <pch.hpp> #include "schedules.h" -#include "sqlContainerCreator.h" #include <rdbmsDataSource.h> #include <logger.h> #include <Ice/Ice.h> #include <sqlVariableBinder.h> #include <sqlMergeTask.h> #include "p2Helpers.h" +#include "commonHelpers.h" #include "containerIterator.h" #include "resources.h" -#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> #include <instanceStore.impl.h> +#include "sqlSelectDeserializer.h" +#include <slicer/slicer.h> +#include <p2pvr-int.h> +#include <privateExecContext.h> -ResourceString(Schedules_GetCandidates, sql_Schedules_GetCandidates); +ResourceString(Schedules_getCandidates, sql_Schedules_getCandidates); ResourceString(Schedules_insert, sql_Schedules_insert); ResourceString(Schedules_insertNewId, sql_Schedules_insertNewId); ResourceString(Schedules_update, sql_Schedules_update); @@ -28,145 +32,9 @@ DECLARE_OPTIONS(Schedules, "P2PVR Scheduler options") "Implementation of episode group scheduler problem solver") END_OPTIONS() -class ScheduleCandidate { - public: - std::string What; - int ServiceId; - int EventId; - int TransportStreamId; - datetime StartTime; - datetime StopTime; - int Priority; - int ScheduleId; -}; -typedef boost::shared_ptr<ScheduleCandidate> ScheduleCandidatePtr; -typedef std::vector<ScheduleCandidatePtr> ScheduleCandidates; - -enum RecordStatuses { - Record_WillRecordThisShowing = 0, - Record_WillRecordOtherShowing = 1, - Record_CannotRecordAnyShowing = 2 -}; - -class Record { - public: - Record() { }; - Record(int s, int e, RecordStatuses rs, int sc) : - ServiceId(s), - EventId(e), - RecordStatus(rs), - ScheduleId(sc) - { - } - - int ServiceId; - int EventId; - RecordStatuses RecordStatus; - int ScheduleId; -}; -typedef boost::shared_ptr<Record> RecordPtr; -typedef std::vector<RecordPtr> Records; - -template<> -void -CreateColumns<P2PVR::ScheduledToRecordPtr>(const ColumnCreator & cc) -{ - cc("serviceid", true); - cc("eventid", true); - cc("scheduleid", true); -} - -template<> -void -UnbindColumns(RowState & rs, P2PVR::ScheduledToRecordPtr const & s) -{ - rs.fields[0] >> s->ServiceId; - rs.fields[1] >> s->EventId; - rs.fields[2] >> s->ScheduleId; -} - -template<> -void -CreateColumns<ScheduleCandidatePtr>(const ColumnCreator & cc) -{ - cc("what", true); - cc("serviceid", false); - cc("eventid", false); - cc("transportstreamid", false); - cc("starttime", false); - cc("stoptime", false); - cc("priority", false); - cc("scheduleid", false); -} - -template<> -void -UnbindColumns(RowState & rs, ScheduleCandidatePtr const & s) -{ - rs.fields[0] >> s->What; - rs.fields[1] >> s->ServiceId; - rs.fields[2] >> s->EventId; - rs.fields[3] >> s->TransportStreamId; - rs.fields[4] >> s->StartTime; - rs.fields[5] >> s->StopTime; - rs.fields[6] >> s->Priority; - rs.fields[7] >> s->ScheduleId; -} - -template<> -void -CreateColumns<P2PVR::SchedulePtr>(const ColumnCreator & cc) -{ - cc("scheduleid", true); - cc("serviceid", false); - cc("eventid", false); - cc("title", false); - cc("search", false); - cc("priority", false); - cc("early", false); - cc("late", false); - cc("repeats", false); -} - -template<> -void -UnbindColumns(RowState & rs, P2PVR::SchedulePtr const & s) -{ - rs.fields[0] >> s->ScheduleId; - rs.fields[1] >> s->ServiceId; - rs.fields[2] >> s->EventId; - rs.fields[3] >> s->Title; - rs.fields[4] >> s->Search; - rs.fields[5] >> s->Priority; - rs.fields[6] >> s->Early; - rs.fields[7] >> s->Late; - rs.fields[8] >> s->Repeats; -} - -template<> -void -CreateColumns<RecordPtr>(const ColumnCreator & cc) -{ - cc("serviceid", true); - cc("eventid", true); - cc("recordstatus", false); - cc("scheduleid", false); -} - -template<> -void -BindColumns(RowState & rs, RecordPtr const & s) -{ - rs.fields[0] << s->ServiceId; - rs.fields[1] << s->EventId; - rs.fields[2] << (int)s->RecordStatus; - rs.fields[3] << s->ScheduleId; -} - -Showing::Showing(unsigned int s, unsigned int e, unsigned int t, unsigned int sc, datetime start, datetime stop, int p, const Episode * ep) : +Showing::Showing(unsigned int e, unsigned int t, unsigned int sc, datetime start, datetime stop, int p, const Episode * ep) : episode(ep), - serviceId(s), - eventId(e), + eventUid(e), priority(p), scheduleId(sc), transportStreamId(t), @@ -202,14 +70,14 @@ EpisodeGroup::IsShowingListValid(const Showings & showings) const Periods periods; Usage usage; - BOOST_FOREACH(const auto & s, showings) { + for (const auto & s : showings) { if (s) { periods.insert(Periods::value_type(s->startTime, {s->transportStreamId, 1})); periods.insert(Periods::value_type(s->stopTime, {s->transportStreamId, -1})); } } bool result = true; - BOOST_FOREACH(const auto & p, periods) { + for (const auto & p : periods) { auto & u = usage[p.second.trans]; u += p.second.offset; if (std::count_if(usage.begin(), usage.end(), [](const Usage::value_type & uv) { return uv.second > 0;}) > tuners) { @@ -301,9 +169,9 @@ Schedules::GetEpisodeIntersects(Episodes & all, Episodes & grouped) { for (Episodes::iterator aei = all.begin(); aei != all.end(); aei++) { const auto & ae = *aei; - BOOST_FOREACH(const auto & ge, grouped) { - BOOST_FOREACH(const auto & gs, ge->showings) { - BOOST_FOREACH(const auto & as, ae->showings) { + for (const auto & ge : grouped) { + for (const auto & gs : ge->showings) { + for (const auto & as : ae->showings) { if (gs->period.intersects(as->period)) { Logger()->messagebf(LOG_DEBUG, " added %s", ae->what); grouped.push_back(ae); @@ -325,36 +193,35 @@ Schedules::DoReschedule(const Ice::Current & ice) unsigned int tunerCount = devs->TunerCount(); // Load list from database - ScheduleCandidates episodes; - SqlContainerCreator<ScheduleCandidates, ScheduleCandidate, ScheduleCandidatePtr> cct(episodes); - cct.populate(Select(Schedules_GetCandidates).second); + auto episodes = Slicer::DeserializeAny<SqlSelectDeserializer, P2PVR::ScheduleCandidates>( + *Select(Schedules_getCandidates).second); Episodes scheduleList; Showings allShowings; EpisodePtr cur; int minPriority = 0; - BOOST_FOREACH(const auto & c, episodes) { + for (const auto & c : episodes) { if (!cur || cur->what != c->What) { cur = new Episode(c->What); scheduleList.push_back(cur); } - ShowingPtr s = new Showing(c->ServiceId, c->EventId, c->TransportStreamId, c->ScheduleId, - c->StartTime, c->StopTime, c->Priority, cur.get()); + ShowingPtr s = new Showing(c->EventUid, c->TransportStreamId, c->ScheduleId, + *c->StartTime, *c->StopTime, c->Priority, cur.get()); minPriority = std::min(minPriority, s->priority); cur->showings.push_back(s); allShowings.push_back(s); } Logger()->messagebf(LOG_DEBUG, "%d episodes created, %s showings", scheduleList.size(), allShowings.size()); - BOOST_FOREACH(const auto & e, scheduleList) { + for (const auto & e : scheduleList) { Logger()->messagebf(LOG_DEBUG, " %s", e->what); - BOOST_FOREACH(const auto & s, e->showings) { + for (const auto & s : e->showings) { s->priority += 1 - minPriority; e->priority += s->priority; } e->priority /= e->showings.size(); } - Records records; + P2PVR::ScheduledToRecordList records; // Solve while (!scheduleList.empty()) { auto work = scheduleList.begin(); @@ -372,7 +239,7 @@ Schedules::DoReschedule(const Ice::Current & ice) Logger()->messagebf(LOG_DEBUG, "group created with %d episodes", group.size()); double total = 1; // Measure and add the optional to not record - BOOST_FOREACH(const auto & e, group) { + for (const auto & e : group) { Logger()->messagebf(LOG_DEBUG, " %d * %d:%s", e->showings.size(), e->priority, e->what); e->showings.push_back(NULL); total *= e->showings.size(); @@ -382,13 +249,13 @@ Schedules::DoReschedule(const Ice::Current & ice) EpisodeGroupPtr sched = EpisodeGroupPtr(EpisodeGroupLoader::createNew(SchedulerAlgorithm, group)); sched->tuners = tunerCount; std::set<ShowingPtr> selected; - BOOST_FOREACH(const auto & s, sched->Solve()) { + for (const auto & s : sched->Solve()) { if (s) selected.insert(s); } - BOOST_FOREACH(const auto & c, group) { + for (const auto & c : group) { Logger()->messagebf(LOG_DEBUG, "Episode %s, %d options", c->what, c->showings.size()); - BOOST_FOREACH(const auto & i, c->showings) { + for (const auto & i : c->showings) { if (selected.find(i) != selected.end()) { Logger()->messagebf(LOG_DEBUG, " %s - %s (%d) <-", i->startTime, i->stopTime, i->transportStreamId); } @@ -398,31 +265,32 @@ Schedules::DoReschedule(const Ice::Current & ice) } } Logger()->message(LOG_DEBUG, "----------"); - BOOST_FOREACH(const auto & c, group) { + for (const auto & c : group) { bool found = false; - BOOST_FOREACH(const auto & i, c->showings) { + for (const auto & i : c->showings) { if (i && selected.find(i) != selected.end()) { found = true; break; } } - BOOST_FOREACH(const auto & i, c->showings) { + for (const auto & i : c->showings) { if (i) { - records.push_back(RecordPtr(new Record(i->serviceId, i->eventId, + records.push_back(new P2PVR::ScheduledToRecord(i->eventUid, found ? - selected.find(i) != selected.end() ? Record_WillRecordThisShowing : Record_WillRecordOtherShowing : - Record_CannotRecordAnyShowing, i->scheduleId))); + selected.find(i) != selected.end() ? P2PVR::WillRecordThisShowing : P2PVR::WillRecordOtherShowing : + P2PVR::CannotRecordAnyShowing, i->scheduleId)); } } } } TxHelper tx(this); + PrivateExecContext ec; SqlMergeTask mergeRecords("postgres", "record"); - CreateColumns<RecordPtr>(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeRecords, _1, _2)); - mergeRecords.sources.insert(new ContainerIterator<Records>(&records)); + auto rcs = CreateColumns<P2PVR::ScheduledToRecordPtr>(boost::bind(&DatabaseClient::SqlMergeColumnsInserter, &mergeRecords, _1, _2)); + mergeRecords.sources.insert(new ContainerIterator<P2PVR::ScheduledToRecordList>(&records, rcs)); mergeRecords.loadComplete(this); - mergeRecords.execute(NULL); + mergeRecords.execute(&ec); tx.Commit(); auto recorder = P2PVR::RecorderPrx::checkedCast(ice.adapter->createProxy(ice.adapter->getCommunicator()->stringToIdentity("Recorder"))); @@ -440,18 +308,17 @@ Schedules::DeleteSchedule(int id, const Ice::Current & ice) P2PVR::ScheduleList Schedules::GetSchedules(const Ice::Current &) { - P2PVR::ScheduleList schedules; - SqlContainerCreator<P2PVR::ScheduleList, P2PVR::Schedule> cct(schedules); - cct.populate(Select(Schedules_selectAll).second); - return schedules; + Logger()->message(LOG_DEBUG, __PRETTY_FUNCTION__); + return Slicer::DeserializeAny<SqlSelectDeserializer, P2PVR::ScheduleList>( + *Select(Schedules_selectAll).second); } P2PVR::SchedulePtr Schedules::GetSchedule(int id, const Ice::Current &) { - P2PVR::ScheduleList schedules; - SqlContainerCreator<P2PVR::ScheduleList, P2PVR::Schedule> cct(schedules); - cct.populate(Select(Schedules_selectById, id).second); + Logger()->messagebf(LOG_DEBUG, "%s(%d)", __PRETTY_FUNCTION__, id); + auto schedules = Slicer::DeserializeAny<SqlSelectDeserializer, P2PVR::ScheduleList>( + *Select(Schedules_selectById, id).second); if (schedules.empty()) throw P2PVR::NotFound(); return schedules.front(); } @@ -459,10 +326,9 @@ Schedules::GetSchedule(int id, const Ice::Current &) P2PVR::ScheduledToRecordList Schedules::GetScheduledToRecord(const Ice::Current &) { - P2PVR::ScheduledToRecordList scheduled; - SqlContainerCreator<P2PVR::ScheduledToRecordList, P2PVR::ScheduledToRecord> cct(scheduled); - cct.populate(Select(Schedules_scheduledToRecord).second); - return scheduled; + Logger()->message(LOG_DEBUG, __PRETTY_FUNCTION__); + return Slicer::DeserializeAny<SqlSelectDeserializer, P2PVR::ScheduledToRecordList>( + *Select(Schedules_scheduledToRecord).second); } int @@ -470,11 +336,11 @@ Schedules::UpdateSchedule(const P2PVR::SchedulePtr & s, const Ice::Current & ice { TxHelper tx(this); if (s->ScheduleId == 0) { - Modify(Schedules_insert, s->ServiceId, s->EventId, s->Title, s->Search, s->Priority, s->Early, s->Late, s->Repeats).second->execute(); + Modify(Schedules_insert, s->ServiceId, s->EventUid, s->Title, s->Search, s->Priority, s->Early, s->Late, s->Repeats).second->execute(); s->ScheduleId = SelectScalar<int>(Schedules_insertNewId); } else { - Modify(Schedules_update, s->ServiceId, s->EventId, s->Title, s->Search, s->Priority, s->Early, s->Late, s->Repeats, s->ScheduleId).second->execute(); + Modify(Schedules_update, s->ServiceId, s->EventUid, s->Title, s->Search, s->Priority, s->Early, s->Late, s->Repeats, s->ScheduleId).second->execute(); } DoReschedule(ice); return s->ScheduleId; |