summaryrefslogtreecommitdiff
path: root/p2pvr/daemon/schedules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'p2pvr/daemon/schedules.cpp')
-rw-r--r--p2pvr/daemon/schedules.cpp228
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;