33 #define LOC QString("ProgramInfo(%1): ").arg(GetBasename())
47 #define DEFINE_FLAGS_NAMES
49 #undef DEFINE_FLAGS_NAMES
52 "SELECT r.title, r.subtitle, r.description, "
53 " r.season, r.episode, r.category, "
54 " r.chanid, c.channum, c.callsign, "
55 " c.name, c.outputfilters,r.recgroup, "
56 " r.playgroup, r.storagegroup, r.basename, "
57 " r.hostname, r.recpriority, r.seriesid, "
58 " r.programid, r.inetref, r.filesize, "
59 " r.progstart, r.progend, r.stars, "
60 " r.starttime, r.endtime, p.airdate+0, "
61 " r.originalairdate, r.lastmodified, r.recordid, "
62 " c.commmethod, r.commflagged, r.previouslyshown, "
63 " r.transcoder, r.transcoded, r.deletepending, "
64 " r.preserve, r.cutlist, r.autoexpire, "
65 " r.editing, r.bookmark, r.watched, "
66 " p.audioprop+0, p.videoprop+0, p.subtitletypes+0, "
67 " r.findid, rec.dupin, rec.dupmethod, "
68 " p.syndicatedepisodenumber, p.partnumber, p.parttotal, "
69 " p.season, p.episode, p.totalepisodes, "
70 " p.category_type, r.recordedid, r.inputname, "
71 " r.bookmarkupdate, r.lastplay "
73 "LEFT JOIN channel AS c "
74 "ON (r.chanid = c.chanid) "
75 "LEFT JOIN recordedprogram AS p "
76 "ON (r.chanid = p.chanid AND "
77 " r.progstart = p.starttime) "
78 "LEFT JOIN record AS rec "
79 "ON (r.recordid = rec.recordid) ";
81 static void set_flag(uint32_t &flags,
int flag_to_set,
bool is_set)
83 flags &= ~flag_to_set;
92 if (!url.startsWith(
"dvd:") && !url.startsWith(
"bd:"))
94 if(url.endsWith(
".img", Qt::CaseInsensitive) ||
95 url.endsWith(
".iso", Qt::CaseInsensitive))
100 result =
"bd:" + url;
104 result =
"dvd:" + url;
114 if (QDir(url +
"/BDMV").exists())
115 result =
"bd:" + url;
116 else if (QDir(url +
"/VIDEO_TS").exists())
117 result =
"dvd:" + url;
124 static const std::array<const QString,ProgramInfo::kNumCatTypes>
kCatName
125 {
"",
"movie",
"series",
"sports",
"tvshow" };
138 for (
size_t i = 1; i <
kCatName.size(); i++)
148 m_title(other.m_title),
149 m_sortTitle(other.m_sortTitle),
150 m_subtitle(other.m_subtitle),
151 m_sortSubtitle(other.m_sortSubtitle),
152 m_description(other.m_description),
153 m_season(other.m_season),
154 m_episode(other.m_episode),
155 m_totalEpisodes(other.m_totalEpisodes),
156 m_syndicatedEpisode(other.m_syndicatedEpisode),
157 m_category(other.m_category),
158 m_director(other.m_director),
160 m_recPriority(other.m_recPriority),
162 m_chanId(other.m_chanId),
163 m_chanStr(other.m_chanStr),
164 m_chanSign(other.m_chanSign),
165 m_chanName(other.m_chanName),
166 m_chanPlaybackFilters(other.m_chanPlaybackFilters),
168 m_recGroup(other.m_recGroup),
169 m_playGroup(other.m_playGroup),
171 m_pathname(other.m_pathname),
173 m_hostname(other.m_hostname),
174 m_storageGroup(other.m_storageGroup),
176 m_seriesId(other.m_seriesId),
177 m_programId(other.m_programId),
178 m_inetRef(other.m_inetRef),
179 m_catType(other.m_catType),
181 m_fileSize(other.m_fileSize),
183 m_startTs(other.m_startTs),
184 m_endTs(other.m_endTs),
185 m_recStartTs(other.m_recStartTs),
186 m_recEndTs(other.m_recEndTs),
188 m_stars(other.m_stars),
190 m_originalAirDate(other.m_originalAirDate),
191 m_lastModified(other.m_lastModified),
194 m_recPriority2(other.m_recPriority2),
195 m_recordId(other.m_recordId),
196 m_parentId(other.m_parentId),
198 m_sourceId(other.m_sourceId),
199 m_inputId(other.m_inputId),
201 m_findId(other.m_findId),
202 m_programFlags(other.m_programFlags),
203 m_videoProperties(other.m_videoProperties),
204 m_audioProperties(other.m_audioProperties),
205 m_subtitleProperties(other.m_subtitleProperties),
206 m_year(other.m_year),
207 m_partNumber(other.m_partNumber),
208 m_partTotal(other.m_partTotal),
210 m_recStatus(other.m_recStatus),
211 m_recType(other.m_recType),
212 m_dupIn(other.m_dupIn),
213 m_dupMethod(other.m_dupMethod),
215 m_recordedId(other.m_recordedId),
216 m_inputName(other.m_inputName),
217 m_bookmarkUpdate(other.m_bookmarkUpdate),
220 m_availableStatus(other.m_availableStatus),
221 m_spread(other.m_spread),
222 m_startCol(other.m_startCol),
225 m_positionMapDBReplacement(other.m_positionMapDBReplacement)
239 "SELECT chanid, starttime "
241 "WHERE recordedid = :RECORDEDID");
242 query.
bindValue(
":RECORDEDID", _recordedid);
252 LOG(VB_GENERAL, LOG_CRIT,
LOC +
253 QString(
"Failed to find recorded entry for %1.")
280 QString _sortSubtitle,
281 QString _description,
285 QString _syndicatedepisode,
292 QString _chanplaybackfilters,
297 const QString &_pathname,
300 QString _storagegroup,
313 QDateTime _recstartts,
321 QDate _originalAirDate,
322 QDateTime _lastmodified,
334 uint _audioproperties,
335 uint _videoproperties,
338 QDateTime _bookmarkupdate) :
339 m_title(
std::move(_title)),
340 m_sortTitle(
std::move(_sortTitle)),
341 m_subtitle(
std::move(_subtitle)),
342 m_sortSubtitle(
std::move(_sortSubtitle)),
343 m_description(
std::move(_description)),
346 m_totalEpisodes(_totalepisodes),
347 m_syndicatedEpisode(
std::move(_syndicatedepisode)),
348 m_category(
std::move(_category)),
350 m_recPriority(_recpriority),
353 m_chanStr(
std::move(_channum)),
354 m_chanSign(
std::move(_chansign)),
355 m_chanName(
std::move(_channame)),
356 m_chanPlaybackFilters(
std::move(_chanplaybackfilters)),
358 m_recGroup(
std::move(_recgroup)),
359 m_playGroup(
std::move(_playgroup)),
361 m_pathname(_pathname),
363 m_hostname(
std::move(_hostname)),
364 m_storageGroup(
std::move(_storagegroup)),
366 m_seriesId(
std::move(_seriesid)),
367 m_programId(
std::move(_programid)),
368 m_inetRef(
std::move(_inetref)),
371 m_fileSize(_filesize),
373 m_startTs(
std::move(_startts)),
374 m_endTs(
std::move(_endts)),
375 m_recStartTs(
std::move(_recstartts)),
376 m_recEndTs(
std::move(_recendts)),
378 m_stars(
std::clamp(_stars, 0.0F, 1.0F)),
380 m_originalAirDate(_originalAirDate),
381 m_lastModified(
std::move(_lastmodified)),
384 m_recordId(_recordid),
387 m_programFlags(_programflags),
388 m_videoProperties(_videoproperties),
389 m_audioProperties(_audioproperties),
390 m_subtitleProperties(_subtitleType),
392 m_partNumber(_partnumber),
393 m_partTotal(_parttotal),
395 m_recStatus(_recstatus),
397 m_dupMethod(_dupmethod),
399 m_recordedId(_recordedid),
400 m_inputName(
std::move(_inputname)),
401 m_bookmarkUpdate(
std::move(_bookmarkupdate))
417 QString _sortSubtitle,
418 QString _description,
434 QDateTime _recstartts,
446 m_title(
std::move(_title)),
447 m_sortTitle(
std::move(_sortTitle)),
448 m_subtitle(
std::move(_subtitle)),
449 m_sortSubtitle(
std::move(_sortSubtitle)),
450 m_description(
std::move(_description)),
453 m_category(
std::move(_category)),
456 m_chanStr(
std::move(_channum)),
457 m_chanSign(
std::move(_chansign)),
458 m_chanName(
std::move(_channame)),
460 m_seriesId(
std::move(_seriesid)),
461 m_programId(
std::move(_programid)),
462 m_inetRef(
std::move(_inetref)),
464 m_startTs(
std::move(_startts)),
465 m_endTs(
std::move(_endts)),
466 m_recStartTs(
std::move(_recstartts)),
467 m_recEndTs(
std::move(_recendts)),
469 m_lastModified(m_startTs),
472 m_recordId(_recordid),
475 m_programFlags((duplicate) ? FL_DUPLICATE : 0),
477 m_recStatus(_recstatus),
492 QString _sortSubtitle,
493 QString _description,
494 QString _syndicatedepisode,
501 QString _chanplaybackfilters,
505 QDateTime _recstartts,
517 QDate _originalAirDate,
526 uint _videoproperties,
527 uint _audioproperties,
535 m_title(
std::move(_title)),
536 m_sortTitle(
std::move(_sortTitle)),
537 m_subtitle(
std::move(_subtitle)),
538 m_sortSubtitle(
std::move(_sortSubtitle)),
539 m_description(
std::move(_description)),
542 m_totalEpisodes(_totalepisodes),
543 m_syndicatedEpisode(
std::move(_syndicatedepisode)),
544 m_category(
std::move(_category)),
547 m_chanStr(
std::move(_channum)),
548 m_chanSign(
std::move(_chansign)),
549 m_chanName(
std::move(_channame)),
550 m_chanPlaybackFilters(
std::move(_chanplaybackfilters)),
552 m_seriesId(
std::move(_seriesid)),
553 m_programId(
std::move(_programid)),
556 m_startTs(
std::move(_startts)),
557 m_endTs(
std::move(_endts)),
558 m_recStartTs(
std::move(_recstartts)),
559 m_recEndTs(
std::move(_recendts)),
561 m_stars(
std::clamp(_stars, 0.0F, 1.0F)),
563 m_originalAirDate(_originalAirDate),
564 m_lastModified(m_startTs),
565 m_lastInUseTime(m_startTs.addSecs(-4 * 60 * 60)),
567 m_recordId(_recordid),
570 m_videoProperties(_videoproperties),
571 m_audioProperties(_audioproperties),
572 m_subtitleProperties(_subtitleType),
574 m_partNumber(_partnumber),
575 m_partTotal(_parttotal),
577 m_recStatus(_recstatus),
586 for (
auto *it : schedList)
636 QString _sortSubtitle,
637 QString _description,
647 QString _chanplaybackfilters,
654 QDateTime _recstartts,
660 QString _inputname) :
661 m_title(
std::move(_title)),
662 m_sortTitle(
std::move(_sortTitle)),
663 m_subtitle(
std::move(_subtitle)),
664 m_sortSubtitle(
std::move(_sortSubtitle)),
665 m_description(
std::move(_description)),
668 m_totalEpisodes(_totalepisodes),
669 m_category(
std::move(_category)),
672 m_chanStr(
std::move(_channum)),
673 m_chanSign(
std::move(_chansign)),
674 m_chanName(
std::move(_channame)),
675 m_chanPlaybackFilters(
std::move(_chanplaybackfilters)),
677 m_recGroup(
std::move(_recgroup)),
678 m_playGroup(
std::move(_playgroup)),
680 m_seriesId(
std::move(_seriesid)),
681 m_programId(
std::move(_programid)),
682 m_inetRef(
std::move(_inetref)),
684 m_startTs(
std::move(_startts)),
685 m_endTs(
std::move(_endts)),
686 m_recStartTs(
std::move(_recstartts)),
687 m_recEndTs(
std::move(_recendts)),
690 m_lastInUseTime(m_lastModified.addSecs(-4 * 60 * 60)),
692 m_inputName(
std::move(_inputname))
703 if (_pathname.isEmpty())
709 QDateTime _recstartts;
723 QString basename = _pathname.section(
'/', -1);
724 if (_pathname == basename)
725 SetPathname(QDir::currentPath() +
'/' + _pathname);
726 else if (_pathname.contains(
"./") && !_pathname.contains(
":"))
727 SetPathname(QFileInfo(_pathname).absoluteFilePath());
737 const QString &_plot,
738 const QString &_title,
739 const QString &_sortTitle,
740 const QString &_subtitle,
741 const QString &_sortSubtitle,
742 const QString &_director,
743 int _season,
int _episode,
744 const QString &_inetref,
745 std::chrono::minutes length_in_minutes,
747 const QString &_programid)
764 int64_t minutes = length_in_minutes.count();
770 QString pn = _pathname;
771 if (!_pathname.startsWith(
"myth://"))
782 const QDateTime &_startts,
783 const QDateTime &_endts)
789 "SELECT chanid, channum, callsign, name, outputfilters, commmethod "
791 "WHERE chanid=:CHANID");
810 QString channelFormat =
818 QString(
"%1 (%2)").arg(
m_title, QObject::tr(
"Manual Record"));
836 bool ignore_non_serialized_data)
864 if (!ignore_non_serialized_data || !is_same ||
920 if (!ignore_non_serialized_data)
1026 if (a.isEmpty() and (b ==
"Default"))
1028 if ((a ==
"Default") and b.isEmpty())
1168 uint chanid,
const QDateTime &recstartts)
1170 return QString(
"%1_%2").arg(chanid).arg(recstartts.toString(
Qt::ISODate));
1177 uint &chanid, QDateTime &recstartts)
1179 QStringList keyParts = uniquekey.split(
'_');
1180 if (keyParts.size() != 2)
1182 chanid = keyParts[0].toUInt();
1184 return (chanid != 0U) && recstartts.isValid();
1188 const QString &pathname,
uint &chanid, QDateTime &recstartts)
1190 QString basename = pathname.section(
'/', -1);
1191 if (basename.isEmpty())
1194 QStringList lr = basename.split(
"_");
1197 chanid = lr[0].toUInt();
1198 QStringList ts = lr[1].split(
".");
1199 if (chanid && !ts.empty())
1202 return recstartts.isValid();
1210 const QString &pathname,
uint &chanid, QDateTime &recstartts)
1212 QString basename = pathname.section(
'/', -1);
1213 if (basename.isEmpty())
1218 "SELECT chanid, starttime "
1220 "WHERE basename = :BASENAME");
1224 chanid = query.
value(0).toUInt();
1235 QString basename = pathname.section(
'/', -1);
1236 if (basename.isEmpty())
1241 "SELECT recordedid "
1243 "WHERE basename = :BASENAME");
1247 recordedid = query.
value(0).toUInt();
1254 #define INT_TO_LIST(x) do { list << QString::number(x); } while (false)
1256 #define DATETIME_TO_LIST(x) do { \
1257 if ((x).isValid()) { \
1258 INT_TO_LIST((x).toSecsSinceEpoch()); \
1260 INT_TO_LIST(kInvalidDateTime); \
1264 #define LONGLONG_TO_LIST(x) do { list << QString::number(x); } while (false)
1266 #define STR_TO_LIST(x) do { list << (x); } while (false)
1267 #define DATE_TO_LIST(x) do { list << (x).toString(Qt::ISODate); } while (false)
1269 #define FLOAT_TO_LIST(x) do { list << QString("%1").arg(x); } while (false)
1341 #define NEXT_STR() do { if (it == listend) \
1343 LOG(VB_GENERAL, LOG_ERR, listerror); \
1347 ts = *it++; } while (false)
1349 #define INT_FROM_LIST(x) do { NEXT_STR(); (x) = ts.toLongLong(); } while (false)
1350 #define ENUM_FROM_LIST(x, y) do { NEXT_STR(); (x) = ((y)ts.toInt()); } while (false)
1352 #define DATETIME_FROM_LIST(x) \
1354 if (ts.isEmpty() or (ts.toUInt() == kInvalidDateTime)) { \
1355 (x) = QDateTime(); \
1357 (x) = MythDate::fromSecsSinceEpoch(ts.toLongLong()); \
1360 #define DATE_FROM_LIST(x) \
1361 do { NEXT_STR(); (x) = ((ts.isEmpty()) || (ts == "0000-00-00")) ? \
1362 QDate() : QDate::fromString(ts, Qt::ISODate); \
1365 #define STR_FROM_LIST(x) do { NEXT_STR(); (x) = ts; } while (false)
1367 #define FLOAT_FROM_LIST(x) do { NEXT_STR(); (x) = ts.toFloat(); } while (false)
1381 const QStringList::const_iterator& listend)
1383 QString listerror =
LOC +
"FromStringList, not enough items in list.";
1447 if (!origChanid || !origRecstartts.isValid() ||
1462 template <
typename T>
1467 return propNames[0];
1470 for (
uint i = 0; i <
sizeof(T)*8 - 1; ++i)
1473 if ((props & bit) == 0)
1475 if (propNames.contains(bit))
1477 result += propNames[bit];
1480 QString
tmp = QString(
"0x%1").arg(bit,
sizeof(T)*2,16,QChar(
'0'));
1481 LOG(VB_GENERAL, LOG_ERR, QString(
"Unknown name for %1 flag 0x%2.")
1485 return result.join(
'|');
1488 template <
typename T>
1490 const QString& props)
1492 if (props.isEmpty())
1497 QStringList names = props.split(
'|');
1498 for (
const auto& n : names )
1500 uint bit = propNames.key(n, 0);
1503 LOG(VB_GENERAL, LOG_ERR, QString(
"Unknown flag for %1 %2")
1559 uint date_format)
const
1564 QString channelFormat =
1566 QString longChannelFormat =
1576 QString tempSubTitle =
m_title;
1580 tempSubTitle = QString(
"%1 - \"%2\"")
1582 tempSortSubtitle = QString(
"%1 - \"%2\"")
1586 progMap[
"titlesubtitle"] = tempSubTitle;
1587 progMap[
"sorttitlesubtitle"] = tempSortSubtitle;
1589 progMap[
"description"] = progMap[
"description0"] =
m_description;
1596 progMap[
"s00e00"] = QString(
"s%1e%2")
1599 progMap[
"00x00"] = QString(
"%1x%2")
1605 progMap[
"season"] = progMap[
"episode"] =
"";
1606 progMap[
"totalepisodes"] =
"";
1607 progMap[
"s00e00"] = progMap[
"00x00"] =
"";
1615 progMap[
"commfree"] = (
m_programFlags & FL_CHANCOMMFREE) ?
"1" :
"0";
1619 progMap[
"starttime"] =
"";
1620 progMap[
"startdate"] =
"";
1621 progMap[
"endtime"] =
"";
1622 progMap[
"enddate"] =
"";
1623 progMap[
"recstarttime"] =
"";
1624 progMap[
"recstartdate"] =
"";
1625 progMap[
"recendtime"] =
"";
1626 progMap[
"recenddate"] =
"";
1630 progMap[
"startdate"] =
"";
1631 progMap[
"recstartdate"] =
"";
1635 progMap[
"startdate"] =
m_startTs.toLocalTime().toString(
"yyyy");
1636 progMap[
"recstartdate"] =
m_startTs.toLocalTime().toString(
"yyyy");
1643 progMap[
"startdate"] =
1653 progMap[
"startts"] = QString::number(
m_startTs.toSecsSinceEpoch());
1654 progMap[
"endts"] = QString::number(
m_endTs.toSecsSinceEpoch());
1655 if (timeNow.toLocalTime().date().year() !=
1657 progMap[
"startyear"] =
m_startTs.toLocalTime().toString(
"yyyy");
1658 if (timeNow.toLocalTime().date().year() !=
1659 m_endTs.toLocalTime().date().year())
1660 progMap[
"endyear"] =
m_endTs.toLocalTime().toString(
"yyyy");
1664 progMap[
"timedate"] =
1668 progMap[
"shorttimedate"] =
1672 progMap[
"starttimedate"] =
1675 progMap[
"shortstarttimedate"] =
1679 progMap[
"lastmodifieddate"] =
1681 progMap[
"lastmodified"] =
1688 progMap[
"chanid"] = QString::number(
m_chanId);
1691 progMap[
"longchannel"] =
ChannelText(longChannelFormat);
1693 QString tmpSize = locale.toString(
m_fileSize * (1.0 / (1024.0 * 1024.0 * 1024.0)),
'f', 2);
1694 progMap[
"filesize_str"] = QObject::tr(
"%1 GB",
"GigaBytes").arg(tmpSize);
1696 progMap[
"filesize"] = locale.toString((quint64)
m_fileSize);
1699 int minutes = seconds / 60;
1701 QString min_str = QObject::tr(
"%n minute(s)",
"",minutes);
1703 progMap[
"lenmins"] = min_str;
1704 int hours = minutes / 60;
1705 minutes = minutes % 60;
1707 progMap[
"lentime"] = min_str;
1708 if (hours > 0 && minutes > 0)
1710 min_str = QObject::tr(
"%n minute(s)",
"",minutes);
1711 progMap[
"lentime"] = QString(
"%1 %2")
1712 .arg(QObject::tr(
"%n hour(s)",
"", hours), min_str);
1716 progMap[
"lentime"] = QObject::tr(
"%n hour(s)",
"", hours);
1719 progMap[
"recordedpercent"] =
1722 progMap[
"watchedpercent"] =
1730 QString tmp_rec = progMap[
"rectype"];
1748 tmp_rec += QObject::tr(
"Re-Record");
1755 progMap[
"rectypestatus"] = tmp_rec;
1765 progMap[
"recordinggroup"] = (
m_recGroup ==
"Default")
1770 progMap[
"storagegroup"] = QObject::tr(
"Default");
1776 progMap[
"storagegroup"] = QObject::tr(
m_storageGroup.toUtf8().constData());
1800 progMap[
"repeat"] = QString(
"(%1) ").arg(QObject::tr(
"Repeat"));
1801 progMap[
"longrepeat"] = progMap[
"repeat"];
1804 progMap[
"longrepeat"] = QString(
"(%1 %2) ")
1805 .arg(QObject::tr(
"Repeat"),
1813 progMap[
"repeat"] =
"";
1814 progMap[
"longrepeat"] =
"";
1822 progMap[
"year"] =
m_year > 1895 ? QString::number(
m_year) :
"";
1827 QString star_str = (
m_stars != 0.0F) ?
1828 QObject::tr(
"%n star(s)",
"",
GetStars(star_range)) :
"";
1829 progMap[
"stars"] = star_str;
1830 progMap[
"numstars"] = QString::number(
GetStars(star_range));
1833 progMap[
"yearstars"] = QString(
"(%1, %2)").arg(
m_year).arg(star_str);
1835 progMap[
"yearstars"] = QString(
"(%1)").arg(star_str);
1837 progMap[
"yearstars"] = QString(
"(%1)").arg(
m_year);
1839 progMap[
"yearstars"] =
"";
1844 progMap[
"originalairdate"] =
"";
1845 progMap[
"shortoriginalairdate"] =
"";
1859 QString mediaTypeString;
1863 mediaType =
"video";
1864 mediaTypeString = QObject::tr(
"Video");
1868 mediaTypeString = QObject::tr(
"DVD");
1871 mediaType =
"httpstream";
1872 mediaTypeString = QObject::tr(
"HTTP Streaming");
1875 mediaType =
"rtspstream";
1876 mediaTypeString = QObject::tr(
"RTSP Streaming");
1879 mediaType =
"bluraydisc";
1880 mediaTypeString = QObject::tr(
"Blu-ray Disc");
1884 mediaType =
"recording";
1885 mediaTypeString = QObject::tr(
"Recording",
1886 "Recorded file, object not action");
1888 progMap[
"mediatype"] = mediaType;
1889 progMap[
"mediatypestring"] = mediaTypeString;
1897 return (recsecs > 0s) ? recsecs : std::max(duration, 0s);
1909 uint64_t last_frame = 0;
1918 if (!posMap.empty())
1920 frm_pos_map_t::const_iterator it = posMap.constEnd();
1922 last_frame = it.key();
1944 str +=
" startts(" +
1947 ") recendts(" +
m_recEndTs.toString() +
")\n";
1948 str +=
" title(" +
m_title +
")";
1956 QString(
"%1%2%3%4").arg(sep, grp,
m_subtitle, grp) :
1961 str = QString(
"%1 at %2")
1965 str = QString(
"%1 @ %2")
1988 const uint _chanid,
const QDateTime &_recstartts)
1990 if (!_chanid || !_recstartts.isValid())
1999 "WHERE r.chanid = :CHANID AND "
2000 " r.starttime = :RECSTARTTS");
2002 query.
bindValue(
":RECSTARTTS", _recstartts);
2055 if (!query.
value(7).toString().isEmpty())
2069 QString new_basename = query.
value(14).toString();
2070 if ((
GetBasename() != new_basename) || !is_reload)
2074 LOG(VB_FILE, LOG_INFO,
LOC +
2075 QString(
"Updated pathname '%1':'%2' -> '%3'")
2098 m_stars = std::clamp((
float)query.
value(23).toDouble(), 0.0F, 1.0F);
2211 if (index == oindex && (index < 0 ||
2270 if (index == oindex && (index < 0 ||
2365 QMap<QString, int> authMap;
2366 std::array<QString,3> tables {
"program",
"recorded",
"oldrecorded" };
2369 for (
const QString& table : tables)
2372 "SELECT DISTINCT LEFT(programid, LOCATE('/', programid)) "
2373 "FROM %1 WHERE programid <> ''").arg(table));
2378 while (query.
next())
2379 authMap[query.
value(0).toString()] = 1;
2383 int numAuths = authMap.count();
2384 LOG(VB_GENERAL, LOG_INFO,
2385 QString(
"Found %1 distinct programid authorities").arg(numAuths));
2398 QString retval = QString(
"%1_%2.%3")
2399 .arg(QString::number(
m_chanId), starts, ext);
2405 uint chanid,
const QString &pathname,
bool use_remote)
2407 QString fn_lower = pathname.toLower();
2411 else if (fn_lower.startsWith(
"http:"))
2413 else if (fn_lower.startsWith(
"rtsp:"))
2419 if (fn_lower.startsWith(
"dvd:"))
2423 else if (fn_lower.startsWith(
"bd:"))
2427 else if (use_remote && fn_lower.startsWith(
"myth://"))
2429 QString tmpFileDVD = pathname +
"/VIDEO_TS";
2430 QString tmpFileBD = pathname +
"/BDMV";
2458 LOG(VB_GUI, LOG_INFO,
2473 query.
prepare(
"UPDATE recorded "
2474 "SET basename = :BASENAME "
2475 "WHERE recordedid = :RECORDEDID;");
2485 query.
prepare(
"UPDATE recordedfile "
2486 "SET basename = :BASENAME "
2487 "WHERE recordedid = :RECORDEDID;");
2519 "FROM recordedfile "
2520 "WHERE recordedid = :RECORDEDID;");
2527 else if (query.
next())
2529 return query.
value(0).toString();
2533 LOG(VB_GENERAL, LOG_INFO,
2534 QString(
"QueryBasename found no entry for recording ID %1")
2549 bool checkMaster,
bool forceCheckLocal)
2556 if (basename.isEmpty())
2565 if (!fullpath.startsWith(
"myth://", Qt::CaseInsensitive) || !checklocal)
2568 QUrl url = QUrl(fullpath);
2569 QString path = url.path();
2570 QString host = url.toString(QUrl::RemovePath).mid(7);
2571 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
2572 QStringList list = host.split(
":", QString::SkipEmptyParts);
2574 QStringList list = host.split(
":", Qt::SkipEmptyParts);
2579 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
2580 list = host.split(
"@", QString::SkipEmptyParts);
2582 list = host.split(
"@", Qt::SkipEmptyParts);
2585 if (!list.empty() && list.size() < 3)
2587 host = list.size() == 1 ? list[0] : list[1];
2588 group = list.size() == 1 ? QString() : list[0];
2591 if (!local.isEmpty() && sg.
FileExists(local))
2604 LOG(VB_FILE, LOG_DEBUG,
LOC +
2605 QString(
"GetPlaybackURL: CHECKING SG : %1 : ").arg(tmpURL));
2607 tmpURL = sgroup.
FindFile(basename);
2609 if (!tmpURL.isEmpty())
2611 LOG(VB_FILE, LOG_INFO,
LOC +
2612 QString(
"GetPlaybackURL: File is local: '%1'") .arg(tmpURL));
2617 LOG(VB_GENERAL, LOG_ERR,
LOC +
2618 QString(
"GetPlaybackURL: '%1' should be local, but it can "
2619 "not be found.").arg(basename));
2622 return QString(
"GetPlaybackURL/UNABLE/TO/FIND/LOCAL/FILE/ON/%1/%2")
2628 if ((checkMaster) &&
2636 LOG(VB_FILE, LOG_INFO,
LOC +
2637 QString(
"GetPlaybackURL: Found @ '%1'").arg(tmpURL));
2646 LOG(VB_FILE, LOG_INFO,
LOC +
2647 QString(
"GetPlaybackURL: Using default of: '%1'") .arg(tmpURL));
2661 query.
prepare(
"SELECT mplexid FROM channel "
2662 "WHERE chanid = :CHANID");
2667 else if (query.
next())
2668 ret = query.
value(0).toUInt();
2671 ret = (32767 == ret) ? 0 : ret;
2683 bool is_valid = (frame > 0);
2704 "SET bookmarkupdate = CURRENT_TIMESTAMP, "
2705 " bookmark = :BOOKMARKFLAG "
2706 "WHERE recordedid = :RECORDEDID");
2708 query.
bindValue(
":BOOKMARKFLAG", bookmarked);
2720 bool isValid = frame > 0;
2745 "SET bookmarkupdate = CURRENT_TIMESTAMP, "
2746 " lastplay = :LASTPLAYFLAG "
2747 "WHERE recordedid = :RECORDEDID");
2749 query.
bindValue(
":LASTPLAYFLAG", hasLastPlay);
2780 "SELECT bookmarkupdate "
2782 "WHERE chanid = :CHANID AND"
2783 " starttime = :STARTTIME");
2791 else if (query.
next())
2811 return (bookmarkmap.isEmpty()) ? 0 : bookmarkmap.begin().key();
2821 return (bookmarkmap.isEmpty()) ? 0 : bookmarkmap.begin().key();
2838 return (bookmarkmap.isEmpty()) ? 0 : bookmarkmap.begin().key();
2855 return (bookmarkmap.isEmpty()) ? 0 : bookmarkmap.begin().key();
2863 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Using last position @ %1").arg(start));
2867 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Using bookmark @ %1").arg(start));
2872 LOG(VB_PLAYBACK, LOG_INFO,
"Ignoring progstart as cutlist exists");
2876 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Using progstart @ %1").arg(start));
2880 LOG(VB_PLAYBACK, LOG_INFO,
"Using file start");
2891 const QString &serialid)
const
2893 QStringList fields = QStringList();
2898 query.
prepare(
" SELECT dvdstate, title, framenum, audionum, subtitlenum "
2899 " FROM dvdbookmark "
2900 " WHERE serialid = :SERIALID ");
2905 QString dvdstate = query.
value(0).toString();
2907 if (!dvdstate.isEmpty())
2909 fields.append(dvdstate);
2914 for(
int i = 1; i < 5; i++)
2915 fields.append(query.
value(i).toString());
2925 QStringList::const_iterator it = fields.begin();
2928 QString serialid = *(it);
2929 QString name = *(++it);
2931 if( fields.count() == 3 )
2934 QString state = *(++it);
2936 query.
prepare(
"INSERT IGNORE INTO dvdbookmark "
2938 " VALUES ( :SERIALID, :NAME );");
2945 query.
prepare(
" UPDATE dvdbookmark "
2946 " SET dvdstate = :STATE , "
2947 " timestamp = NOW() "
2948 " WHERE serialid = :SERIALID");
2955 query.
prepare(
"DELETE FROM dvdbookmark "
2956 "WHERE serialid = :SERIALID");
2969 QStringList fields = QStringList();
2974 query.
prepare(
" SELECT bdstate FROM bdbookmark "
2975 " WHERE serialid = :SERIALID ");
2979 fields.append(query.
value(0).toString());
2987 QStringList::const_iterator it = fields.begin();
2990 QString serialid = *(it);
2991 QString name = *(++it);
2993 if( fields.count() == 3 )
2996 QString state = *(++it);
2998 query.
prepare(
"INSERT IGNORE INTO bdbookmark "
3000 " VALUES ( :SERIALID, :NAME );");
3007 query.
prepare(
" UPDATE bdbookmark "
3008 " SET bdstate = :STATE , "
3009 " timestamp = NOW() "
3010 " WHERE serialid = :SERIALID");
3017 query.
prepare(
"DELETE FROM bdbookmark "
3018 "WHERE serialid = :SERIALID");
3037 query.
prepare(
" SELECT category_type "
3038 " FROM recordedprogram "
3039 " WHERE chanid = :CHANID "
3040 " AND starttime = :STARTTIME;");
3060 query.
prepare(
"UPDATE recorded"
3061 " SET watched = :WATCHEDFLAG"
3062 " WHERE chanid = :CHANID"
3063 " AND starttime = :STARTTIME ;");
3066 query.
bindValue(
":WATCHEDFLAG", watched);
3078 if (url.startsWith(
"myth://"))
3080 url = QUrl(url).path();
3085 query.
prepare(
"UPDATE videometadata"
3086 " SET watched = :WATCHEDFLAG"
3087 " WHERE title = :TITLE"
3088 " AND subtitle = :SUBTITLE"
3089 " AND filename = :FILENAME ;");
3093 query.
bindValue(
":WATCHEDFLAG", watched);
3112 query.
prepare(
"SELECT editing FROM recorded"
3113 " WHERE chanid = :CHANID"
3114 " AND starttime = :STARTTIME ;");
3119 editing = query.
value(0).toBool();
3136 query.
prepare(
"UPDATE recorded"
3137 " SET editing = :EDIT"
3138 " WHERE chanid = :CHANID"
3139 " AND starttime = :STARTTIME ;");
3161 query.
prepare(
"UPDATE recorded"
3162 " SET deletepending = :DELETEFLAG, "
3164 " WHERE chanid = :CHANID"
3165 " AND starttime = :STARTTIME ;");
3168 query.
bindValue(
":DELETEFLAG", deleteFlag);
3193 query.
prepare(
"SELECT hostname, recusage FROM inuseprograms "
3194 " WHERE chanid = :CHANID"
3195 " AND starttime = :STARTTIME "
3196 " AND lastupdatetime > :ONEHOURAGO ;");
3199 query.
bindValue(
":ONEHOURAGO", oneHourAgo);
3202 if (query.
exec() && query.
size() > 0)
3206 while (query.
next())
3208 usageStr = QObject::tr(
"Unknown");
3209 recusage = query.
value(1).toString();
3212 usageStr = QObject::tr(
"Playing");
3214 usageStr = QObject::tr(
"PIP");
3216 usageStr = QObject::tr(
"PBP");
3219 usageStr = QObject::tr(
"Recording");
3221 usageStr = QObject::tr(
"File transfer");
3223 usageStr = QObject::tr(
"Delete");
3225 usageStr = QObject::tr(
"Commercial Detection");
3227 usageStr = QObject::tr(
"Transcoding");
3229 usageStr = QObject::tr(
"Preview Generation");
3231 usageStr = QObject::tr(
"User Job");
3233 byWho.push_back(recusage);
3234 byWho.push_back(query.
value(0).toString());
3235 byWho.push_back(query.
value(0).toString() +
" (" + usageStr +
")");
3253 for (
int i = 0; i+2 < users.size(); i+=3)
3254 byWho += users[i+2] +
"\n";
3281 for (
uint i = 0; (i+2 < (
uint)byWho.size()) && ok; i+=3)
3291 (one_playback_allowed && (play_cnt <= 1)));
3293 ok = ok && (ft_cnt == jq_cnt);
3304 query.
prepare(
"SELECT transcoded FROM recorded"
3305 " WHERE chanid = :CHANID"
3306 " AND starttime = :STARTTIME ;");
3326 "SET transcoded = :VALUE "
3327 "WHERE chanid = :CHANID AND"
3328 " starttime = :STARTTIME");
3347 query.
prepare(
"UPDATE recorded"
3348 " SET commflagged = :FLAG"
3349 " WHERE chanid = :CHANID"
3350 " AND starttime = :STARTTIME ;");
3373 query.
prepare(
"UPDATE recorded"
3374 " SET preserve = :PRESERVE"
3375 " WHERE chanid = :CHANID"
3376 " AND starttime = :STARTTIME ;");
3377 query.
bindValue(
":PRESERVE", preserveEpisode);
3400 query.
prepare(
"UPDATE recorded"
3401 " SET autoexpire = :AUTOEXPIRE"
3402 " WHERE chanid = :CHANID"
3403 " AND starttime = :STARTTIME ;");
3410 else if (updateDelete)
3429 auto delay_secs = std::chrono::seconds(
m_recStartTs.secsTo(timeNow));
3430 auto delay = duration_cast<std::chrono::hours>(delay_secs);
3431 delay = std::clamp(delay, 1h, 200h);
3433 query.
prepare(
"UPDATE record SET last_delete = :TIME, "
3434 "avg_delay = (avg_delay * 3 + :DELAY) / 4 "
3435 "WHERE recordid = :RECORDID");
3437 query.
bindValue(
":DELAY",
static_cast<qint64
>(delay.count()));
3441 query.
prepare(
"UPDATE record SET last_delete = NULL "
3442 "WHERE recordid = :RECORDID");
3455 query.
prepare(
"SELECT autoexpire FROM recorded"
3456 " WHERE chanid = :CHANID"
3457 " AND starttime = :STARTTIME ;");
3478 for (
auto i = autosaveMap.constBegin(); i != autosaveMap.constEnd(); ++i)
3480 uint64_t frame = i.key();
3486 delMap[frame] =
mark;
3496 return !delMap.isEmpty();
3512 for (
auto i = delMap.constBegin(); i != delMap.constEnd(); ++i)
3514 uint64_t frame = i.key();
3523 tmpDelMap[frame] =
mark;
3532 query.
prepare(
"UPDATE recorded"
3533 " SET cutlist = :CUTLIST"
3534 " WHERE chanid = :CHANID"
3535 " AND starttime = :STARTTIME ;");
3537 query.
bindValue(
":CUTLIST", delMap.isEmpty() ? 0 : 1);
3566 comp += QString(
" AND mark >= %1 ").arg(min_frame);
3569 comp += QString(
" AND mark <= %1 ").arg(max_frame);
3572 comp += QString(
" AND type = :TYPE ");
3576 query.
prepare(
"DELETE FROM filemarkup"
3577 " WHERE filename = :PATH "
3583 query.
prepare(
"DELETE FROM recordedmarkup"
3584 " WHERE chanid = :CHANID"
3585 " AND STARTTIME = :STARTTIME"
3602 int64_t min_frame, int64_t max_frame)
const
3614 query.
prepare(
"SELECT starttime FROM recorded"
3615 " WHERE chanid = :CHANID"
3616 " AND starttime = :STARTTIME ;");
3631 frm_dir_map_t::const_iterator it;
3632 for (it =
marks.begin(); it !=
marks.end(); ++it)
3634 uint64_t frame = it.key();
3636 if ((min_frame >= 0) && (frame < (uint64_t)min_frame))
3639 if ((max_frame >= 0) && (frame > (uint64_t)max_frame))
3646 query.
prepare(
"INSERT INTO filemarkup (filename, mark, type)"
3647 " VALUES ( :PATH , :MARK , :TYPE );");
3652 query.
prepare(
"INSERT INTO recordedmarkup"
3653 " (chanid, starttime, mark, type)"
3654 " VALUES ( :CHANID , :STARTTIME , :MARK , :TYPE );");
3658 query.
bindValue(
":MARK", (quint64)frame);
3684 const QString &video_pathname,
3693 query.
prepare(
"SELECT mark, type "
3695 "WHERE filename = :PATH AND "
3698 query.
bindValue(
":PATH", video_pathname);
3707 while (query.
next())
3715 uint chanid,
const QDateTime &recstartts,
3723 query.
prepare(
"SELECT mark, type "
3724 "FROM recordedmarkup "
3725 "WHERE chanid = :CHANID AND "
3726 " starttime = :STARTTIME AND"
3730 query.
bindValue(
":STARTTIME", recstartts);
3739 while (query.
next())
3753 return flagMap.contains(0);
3781 query.
prepare(
"SELECT mark, `offset` FROM filemarkup"
3782 " WHERE filename = :PATH"
3783 " AND type = :TYPE ;");
3788 query.
prepare(
"SELECT mark, `offset` FROM recordedseek"
3789 " WHERE chanid = :CHANID"
3790 " AND starttime = :STARTTIME"
3791 " AND type = :TYPE ;");
3807 while (query.
next())
3808 posMap[query.
value(0).toULongLong()] = query.
value(1).toULongLong();
3824 query.
prepare(
"DELETE FROM filemarkup"
3825 " WHERE filename = :PATH"
3826 " AND type = :TYPE ;");
3831 query.
prepare(
"DELETE FROM recordedseek"
3832 " WHERE chanid = :CHANID"
3833 " AND starttime = :STARTTIME"
3834 " AND type = :TYPE ;");
3851 int64_t min_frame, int64_t max_frame)
const
3857 if ((min_frame >= 0) || (max_frame >= 0))
3865 uint64_t frame = it.key();
3866 if ((min_frame >= 0) && (frame >= (uint64_t)min_frame))
3868 if ((min_frame >= 0) && (frame <= (uint64_t)max_frame))
3870 new_map.insert(it.key(), *it);
3880 for (
auto it = posMap.cbegin(); it != posMap.cend(); ++it)
3882 uint64_t frame = it.key();
3883 if ((min_frame >= 0) && (frame >= (uint64_t)min_frame))
3885 if ((min_frame >= 0) && (frame <= (uint64_t)max_frame))
3889 .insert(frame, *it);
3899 comp +=
" AND mark >= :MIN_FRAME ";
3901 comp +=
" AND mark <= :MAX_FRAME ";
3908 query.
prepare(
"DELETE FROM filemarkup"
3909 " WHERE filename = :PATH"
3916 query.
prepare(
"DELETE FROM recordedseek"
3917 " WHERE chanid = :CHANID"
3918 " AND starttime = :STARTTIME"
3931 query.
bindValue(
":MIN_FRAME", (quint64)min_frame);
3933 query.
bindValue(
":MAX_FRAME", (quint64)max_frame);
3938 if (posMap.isEmpty())
3942 QStringList q(
"INSERT INTO ");
3946 q <<
"filemarkup (filename, type, mark, `offset`)";
3947 qfields = QString(
"('%1',%2,") .
3954 q <<
"recordedseek (chanid, starttime, type, mark, `offset`)";
3955 qfields = QString(
"(%1,'%2',%3,") .
3962 bool add_comma =
false;
3963 frm_pos_map_t::iterator it;
3964 for (it = posMap.begin(); it != posMap.end(); ++it)
3966 uint64_t frame = it.key();
3968 if ((min_frame >= 0) && (frame < (uint64_t)min_frame))
3971 if ((max_frame >= 0) && (frame > (uint64_t)max_frame))
3974 uint64_t offset = *it;
3984 q << qfields << QString(
"%1,%2)").arg(frame).arg(offset);
3996 if (posMap.isEmpty())
4003 for (
auto it = posMap.cbegin(); it != posMap.cend(); ++it)
4010 QStringList q(
"INSERT INTO ");
4014 q <<
"filemarkup (filename, type, mark, `offset`)";
4015 qfields = QString(
"('%1',%2,") .
4022 q <<
"recordedseek (chanid, starttime, type, mark, `offset`)";
4023 qfields = QString(
"(%1,'%2',%3,") .
4034 bool add_comma =
false;
4035 frm_pos_map_t::iterator it;
4036 for (it = posMap.begin(); it != posMap.end(); ++it)
4038 uint64_t frame = it.key();
4039 uint64_t offset = *it;
4049 q << qfields << QString(
"%1,%2)").arg(frame).arg(offset);
4061 "SELECT mark, `offset` FROM filemarkup"
4062 " WHERE filename = :PATH"
4064 " AND mark >= :QUERY_ARG"
4065 " ORDER BY filename ASC, type ASC, mark ASC LIMIT 1;";
4067 "SELECT mark, `offset` FROM filemarkup"
4068 " WHERE filename = :PATH"
4070 " AND mark <= :QUERY_ARG"
4071 " ORDER BY filename DESC, type DESC, mark DESC LIMIT 1;";
4073 "SELECT mark, `offset` FROM recordedseek"
4074 " WHERE chanid = :CHANID"
4075 " AND starttime = :STARTTIME"
4077 " AND mark >= :QUERY_ARG"
4078 " ORDER BY chanid ASC, starttime ASC, type ASC, mark ASC LIMIT 1;";
4080 "SELECT mark, `offset` FROM recordedseek"
4081 " WHERE chanid = :CHANID"
4082 " AND starttime = :STARTTIME"
4084 " AND mark <= :QUERY_ARG"
4085 " ORDER BY chanid DESC, starttime DESC, type DESC, mark DESC LIMIT 1;";
4087 "SELECT `offset`,mark FROM filemarkup"
4088 " WHERE filename = :PATH"
4090 " AND `offset` >= :QUERY_ARG"
4091 " ORDER BY filename ASC, type ASC, mark ASC LIMIT 1;";
4093 "SELECT `offset`,mark FROM filemarkup"
4094 " WHERE filename = :PATH"
4096 " AND `offset` <= :QUERY_ARG"
4097 " ORDER BY filename DESC, type DESC, mark DESC LIMIT 1;";
4099 "SELECT `offset`,mark FROM recordedseek"
4100 " WHERE chanid = :CHANID"
4101 " AND starttime = :STARTTIME"
4103 " AND `offset` >= :QUERY_ARG"
4104 " ORDER BY chanid ASC, starttime ASC, type ASC, mark ASC LIMIT 1;";
4106 "SELECT `offset`,mark FROM recordedseek"
4107 " WHERE chanid = :CHANID"
4108 " AND starttime = :STARTTIME"
4110 " AND `offset` <= :QUERY_ARG"
4111 " ORDER BY chanid DESC, starttime DESC, type DESC, mark DESC LIMIT 1;";
4114 uint64_t position_or_keyframe,
4117 const char *from_filemarkup_asc,
4118 const char *from_filemarkup_desc,
4119 const char *from_recordedseek_asc,
4120 const char *from_recordedseek_desc)
const
4127 query.
prepare(from_filemarkup_desc);
4129 query.
prepare(from_filemarkup_asc);
4135 query.
prepare(from_recordedseek_desc);
4137 query.
prepare(from_recordedseek_asc);
4142 query.
bindValue(
":QUERY_ARG", (
unsigned long long)position_or_keyframe);
4152 *result = query.
value(1).toULongLong();
4159 query.
prepare(from_filemarkup_asc);
4161 query.
prepare(from_filemarkup_desc);
4167 query.
prepare(from_recordedseek_asc);
4169 query.
prepare(from_recordedseek_desc);
4174 query.
bindValue(
":QUERY_ARG", (
unsigned long long)position_or_keyframe);
4184 *result = query.
value(1).toULongLong();
4193 bool backwards)
const
4202 bool backwards)
const
4211 bool backwards)
const
4220 bool backwards)
const
4240 query.
prepare(
"INSERT INTO recordedmarkup"
4241 " (chanid, starttime, mark, type, data)"
4243 " ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
4247 query.
bindValue(
":MARK", (quint64)frame);
4255 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
4256 query.
bindValue(
":DATA", QVariant(QVariant::UInt));
4258 query.
bindValue(
":DATA", QVariant(QMetaType(QMetaType::UInt)));
4276 query.
prepare(
"INSERT INTO recordedmarkup"
4277 " (chanid, starttime, mark, type, data)"
4279 " ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
4282 query.
bindValue(
":MARK", (quint64)frame);
4301 query.
prepare(
"INSERT INTO recordedmarkup"
4302 " (chanid, starttime, mark, type, data)"
4304 " ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
4307 query.
bindValue(
":MARK", (quint64)frame);
4324 query.
prepare(
"DELETE FROM recordedmarkup "
4325 " WHERE chanid=:CHANID "
4326 " AND starttime=:STARTTIME "
4335 query.
prepare(
"INSERT INTO recordedmarkup"
4336 " (chanid, starttime, mark, type, data)"
4338 " ( :CHANID, :STARTTIME, 0, :TYPE, :DATA);");
4356 query.
prepare(
"DELETE FROM recordedmarkup "
4357 " WHERE chanid=:CHANID "
4358 " AND starttime=:STARTTIME "
4367 query.
prepare(
"INSERT INTO recordedmarkup"
4368 " (chanid, starttime, mark, type, data)"
4370 " ( :CHANID, :STARTTIME, 0, :TYPE, :DATA);");
4390 query.
prepare(
"INSERT INTO recordedmarkup"
4391 " (chanid, starttime, mark, type, data)"
4393 " ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
4396 query.
bindValue(
":MARK", (quint64)frame);
4403 query.
prepare(
"INSERT INTO recordedmarkup"
4404 " (chanid, starttime, mark, type, data)"
4406 " ( :CHANID, :STARTTIME, :MARK, :TYPE, :DATA);");
4409 query.
bindValue(
":MARK", (quint64)frame);
4420 QString qstr = QString(
4421 "SELECT recordedmarkup.data "
4422 "FROM recordedmarkup "
4423 "WHERE recordedmarkup.chanid = :CHANID AND "
4424 " recordedmarkup.starttime = :STARTTIME AND "
4425 " recordedmarkup.type = :TYPE "
4426 "GROUP BY recordedmarkup.data "
4427 "ORDER BY SUM( ( SELECT IFNULL(rm.mark, recordedmarkup.mark)"
4428 " FROM recordedmarkup AS rm "
4429 " WHERE rm.chanid = recordedmarkup.chanid AND "
4430 " rm.starttime = recordedmarkup.starttime AND "
4431 " rm.type = recordedmarkup.type AND "
4432 " rm.mark > recordedmarkup.mark "
4433 " ORDER BY rm.mark ASC LIMIT 1 "
4434 " ) - recordedmarkup.mark "
4442 query.
bindValue(
":STARTTIME", recstartts);
4450 return (query.
next()) ? query.
value(0).toUInt() : 0;
4483 query.
prepare(
"SELECT recordedmarkup.type "
4484 "FROM recordedmarkup "
4485 "WHERE recordedmarkup.chanid = :CHANID AND "
4486 " recordedmarkup.starttime = :STARTTIME AND "
4487 " recordedmarkup.type >= :ASPECTSTART AND "
4488 " recordedmarkup.type <= :ASPECTEND "
4489 "GROUP BY recordedmarkup.type "
4490 "ORDER BY SUM( ( SELECT IFNULL(rm.mark, ( "
4491 " SELECT MAX(rmmax.mark) "
4492 " FROM recordedmarkup AS rmmax "
4493 " WHERE rmmax.chanid = recordedmarkup.chanid "
4494 " AND rmmax.starttime = recordedmarkup.starttime "
4496 " FROM recordedmarkup AS rm "
4497 " WHERE rm.chanid = recordedmarkup.chanid AND "
4498 " rm.starttime = recordedmarkup.starttime AND "
4499 " rm.type >= :ASPECTSTART2 AND "
4500 " rm.type <= :ASPECTEND2 AND "
4501 " rm.mark > recordedmarkup.mark "
4502 " ORDER BY rm.mark ASC LIMIT 1 "
4503 " ) - recordedmarkup.mark "
4565 QVector<MarkupEntry> &mapSeek)
const
4571 query.
prepare(
"SELECT type, mark, `offset` FROM filemarkup"
4572 " WHERE filename = :PATH"
4573 " AND type NOT IN (:KEYFRAME,:DURATION)"
4574 " ORDER BY mark, type;");
4581 query.
prepare(
"SELECT type, mark, data FROM recordedmarkup"
4582 " WHERE chanid = :CHANID"
4583 " AND STARTTIME = :STARTTIME"
4584 " ORDER BY mark, type");
4597 while (query.
next())
4600 uint64_t frame = query.
value(1).toLongLong();
4602 bool isDataNull = query.
value(2).isNull();
4604 data = query.
value(2).toLongLong();
4611 query.
prepare(
"SELECT type, mark, `offset` FROM filemarkup"
4612 " WHERE filename = :PATH"
4613 " AND type IN (:KEYFRAME,:DURATION)"
4614 " ORDER BY mark, type;");
4621 query.
prepare(
"SELECT type, mark, `offset` FROM recordedseek"
4622 " WHERE chanid = :CHANID"
4623 " AND STARTTIME = :STARTTIME"
4624 " ORDER BY mark, type");
4633 while (query.
next())
4636 uint64_t frame = query.
value(1).toLongLong();
4638 bool isDataNull = query.
value(2).isNull();
4640 data = query.
value(2).toLongLong();
4646 const QVector<MarkupEntry> &mapSeek)
const
4652 if (mapMark.isEmpty())
4654 LOG(VB_GENERAL, LOG_INFO,
4655 QString(
"No mark entries in input, "
4656 "not removing marks from DB"));
4660 query.
prepare(
"DELETE FROM filemarkup"
4661 " WHERE filename = :PATH"
4662 " AND type NOT IN (:KEYFRAME,:DURATION)");
4671 for (
const auto& entry : qAsConst(mapMark))
4675 if (entry.isDataNull)
4677 query.
prepare(
"INSERT INTO filemarkup"
4678 " (filename,type,mark)"
4679 " VALUES (:PATH,:TYPE,:MARK)");
4683 query.
prepare(
"INSERT INTO filemarkup"
4684 " (filename,type,mark,`offset`)"
4685 " VALUES (:PATH,:TYPE,:MARK,:OFFSET)");
4686 query.
bindValue(
":OFFSET", (quint64)entry.data);
4690 query.
bindValue(
":MARK", (quint64)entry.frame);
4698 if (mapSeek.isEmpty())
4700 LOG(VB_GENERAL, LOG_INFO,
4701 QString(
"No seek entries in input, "
4702 "not removing marks from DB"));
4706 query.
prepare(
"DELETE FROM filemarkup"
4707 " WHERE filename = :PATH"
4708 " AND type IN (:KEYFRAME,:DURATION)");
4717 for (
int i = 0; i < mapSeek.size(); ++i)
4719 if (i > 0 && (i % 1000 == 0))
4721 LOG(VB_GENERAL, LOG_INFO,
4722 QString(
"Inserted %1 of %2 records")
4723 .arg(i).arg(mapSeek.size()));
4726 query.
prepare(
"INSERT INTO filemarkup"
4727 " (filename,type,mark,`offset`)"
4728 " VALUES (:PATH,:TYPE,:MARK,:OFFSET)");
4743 if (mapMark.isEmpty())
4745 LOG(VB_GENERAL, LOG_INFO,
4746 QString(
"No mark entries in input, "
4747 "not removing marks from DB"));
4751 query.
prepare(
"DELETE FROM recordedmarkup"
4752 " WHERE chanid = :CHANID"
4753 " AND starttime = :STARTTIME");
4761 for (
const auto& entry : qAsConst(mapMark))
4763 if (entry.isDataNull)
4765 query.
prepare(
"INSERT INTO recordedmarkup"
4766 " (chanid,starttime,type,mark)"
4767 " VALUES (:CHANID,:STARTTIME,:TYPE,:MARK)");
4771 query.
prepare(
"INSERT INTO recordedmarkup"
4772 " (chanid,starttime,type,mark,data)"
4773 " VALUES (:CHANID,:STARTTIME,"
4774 " :TYPE,:MARK,:OFFSET)");
4775 query.
bindValue(
":OFFSET", (quint64)entry.data);
4780 query.
bindValue(
":MARK", (quint64)entry.frame);
4788 if (mapSeek.isEmpty())
4790 LOG(VB_GENERAL, LOG_INFO,
4791 QString(
"No seek entries in input, "
4792 "not removing marks from DB"));
4796 query.
prepare(
"DELETE FROM recordedseek"
4797 " WHERE chanid = :CHANID"
4798 " AND starttime = :STARTTIME");
4806 for (
int i = 0; i < mapSeek.size(); ++i)
4808 if (i > 0 && (i % 1000 == 0))
4810 LOG(VB_GENERAL, LOG_INFO,
4811 QString(
"Inserted %1 of %2 records")
4812 .arg(i).arg(mapSeek.size()));
4815 query.
prepare(
"INSERT INTO recordedseek"
4816 " (chanid,starttime,type,mark,`offset`)"
4817 " VALUES (:CHANID,:STARTTIME,"
4818 " :TYPE,:MARK,:OFFSET)");
4838 LOG(VB_RECORD, LOG_INFO,
4839 QString(
"SaveVideoProperties(0x%1, 0x%2)")
4840 .arg(mask,2,16,QChar(
'0')).arg(video_property_flags,2,16,QChar(
'0')));
4843 "UPDATE recordedprogram "
4844 "SET videoprop = ((videoprop+0) & :OTHERFLAGS) | :FLAGS "
4845 "WHERE chanid = :CHANID AND starttime = :STARTTIME");
4848 query.
bindValue(
":FLAGS", video_property_flags);
4858 videoproperties &= ~mask;
4859 videoproperties |= video_property_flags;
4877 QString chan(format);
4887 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"UpdateInUseMark(%1) '%2'")
4907 "SET season = :SEASON, episode = :EPISODE "
4908 "WHERE chanid = :CHANID AND starttime = :STARTTIME "
4909 "AND recordid = :RECORDID");
4931 "SET inetref = :INETREF "
4932 "WHERE chanid = :CHANID AND starttime = :STARTTIME "
4933 "AND recordid = :RECORDID");
4972 query.
prepare(
"SELECT password FROM recgroups "
4973 "WHERE recgroup = :GROUP");
4977 result = query.
value(0).toString();
4987 query.
prepare(
"SELECT recgroup FROM recorded "
4988 "WHERE chanid = :CHANID AND "
4989 " starttime = :START");
4995 grp = query.
value(0).toString();
5003 query.
prepare(
"SELECT transcoder FROM recorded "
5004 "WHERE chanid = :CHANID AND "
5005 " starttime = :START");
5010 return query.
value(0).toUInt();
5028 if (path.startsWith(
"/"))
5030 QFileInfo testFile(path);
5031 return testFile.path();
5042 if (testFile.exists())
5044 if (testFile.isSymLink())
5047 if (testFile.isFile())
5048 return testFile.path();
5049 if (testFile.isDir())
5050 return testFile.filePath();
5054 testFile.setFile(testFile.absolutePath());
5055 if (testFile.exists())
5057 if (testFile.isSymLink())
5060 if (testFile.isDir())
5061 return testFile.filePath();
5080 bool notifyOfChange =
false;
5086 if (!usedFor.isEmpty())
5092 LOG(VB_GENERAL, LOG_INFO,
LOC +
5093 QString(
"MarkAsInUse(true, '%1'->'%2')")
5095 " -- use has changed");
5099 LOG(VB_GENERAL, LOG_INFO,
LOC +
5100 QString(
"MarkAsInUse(true, ''->'%1')").arg(usedFor));
5102 #endif // DEBUG_IN_USE
5109 .arg(QObject::tr(
"Unknown")).arg(getpid());
5110 LOG(VB_GENERAL, LOG_WARNING,
LOC +
5112 " -- use was not explicitly set");
5115 notifyOfChange =
true;
5120 LOG(VB_GENERAL, LOG_WARNING,
LOC +
5121 QString(
"MarkAsInUse(false, '%1'->'%2')")
5123 " -- use has changed since first setting as in use.");
5128 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"MarkAsInUse(false, '%1')")
5131 #endif // DEBUG_IN_USE
5138 LOG(VB_GENERAL, LOG_WARNING,
LOC +
5139 "MarkAsInUse requires a key to delete in use mark");
5147 "DELETE FROM inuseprograms "
5148 "WHERE chanid = :CHANID AND starttime = :STARTTIME AND "
5149 " hostname = :HOSTNAME AND recusage = :RECUSAGE");
5174 "FROM inuseprograms "
5175 "WHERE chanid = :CHANID AND starttime = :STARTTIME AND "
5176 " hostname = :HOSTNAME AND recusage = :RECUSAGE");
5186 else if (!query.
next())
5188 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MarkAsInUse -- select query failed");
5190 else if (query.
value(0).toBool())
5193 "UPDATE inuseprograms "
5194 "SET lastupdatetime = :UPDATETIME "
5195 "WHERE chanid = :CHANID AND starttime = :STARTTIME AND "
5196 " hostname = :HOSTNAME AND recusage = :RECUSAGE");
5201 query.
bindValue(
":UPDATETIME", inUseTime);
5211 "INSERT INTO inuseprograms "
5212 " (chanid, starttime, recusage, hostname, "
5213 " lastupdatetime, rechost, recdir) "
5215 " (:CHANID, :STARTTIME, :RECUSAGE, :HOSTNAME, "
5216 " :UPDATETIME, :RECHOST, :RECDIR)");
5221 query.
bindValue(
":UPDATETIME", inUseTime);
5233 if (!notifyOfChange)
5238 query.
prepare(
"SELECT DISTINCT recusage "
5239 "FROM inuseprograms "
5240 "WHERE lastupdatetime >= :ONEHOURAGO AND "
5241 " chanid = :CHANID AND "
5242 " starttime = :STARTTIME");
5245 query.
bindValue(
":ONEHOURAGO", oneHourAgo);
5249 m_programFlags &= ~(FL_INUSEPLAYING | FL_INUSERECORDING | FL_INUSEOTHER);
5250 while (query.
next())
5252 QString inUseForWhat = query.
value(0).toString();
5274 query.
prepare(
"SELECT channel.channum, capturecard.inputname "
5275 "FROM channel, capturecard "
5276 "WHERE channel.chanid = :CHANID AND "
5277 " capturecard.sourceid = :SOURCEID AND "
5278 " capturecard.cardid = :INPUTID");
5285 channum = query.
value(0).toString();
5286 input = query.
value(1).toString();
5295 static bool s_done =
false;
5296 static QMutex s_initTrLock;
5297 QMutexLocker locker(&s_initTrLock);
5301 QString rec_profile_names =
5302 QObject::tr(
"Default",
"Recording Profile Default") +
5303 QObject::tr(
"High Quality",
"Recording Profile High Quality") +
5304 QObject::tr(
"Live TV",
"Recording Profile Live TV") +
5305 QObject::tr(
"Low Quality",
"Recording Profile Low Quality") +
5306 QObject::tr(
"Medium Quality",
"Recording Profile Medium Quality") +
5307 QObject::tr(
"MPEG-2",
"Recording Profile MPEG-2") +
5308 QObject::tr(
"RTjpeg/MPEG-4",
"Recording Profile RTjpeg/MPEG-4");
5311 QString rec_profile_groups =
5312 QObject::tr(
"CRC IP Recorders",
5313 "Recording Profile Group Name") +
5314 QObject::tr(
"FireWire Input",
5315 "Recording Profile Group Name") +
5316 QObject::tr(
"Freebox Input",
5317 "Recording Profile Group Name") +
5318 QObject::tr(
"Hardware DVB Encoders",
5319 "Recording Profile Group Name") +
5320 QObject::tr(
"Hardware HDTV",
5321 "Recording Profile Group Name") +
5322 QObject::tr(
"Hardware MJPEG Encoders (Matrox G200-TV, Miro DC10, etc)",
5323 "Recording Profile Group Name") +
5324 QObject::tr(
"HD-PVR Recorders",
5325 "Recording Profile Group Name") +
5326 QObject::tr(
"HDHomeRun Recorders",
5327 "Recording Profile Group Name") +
5328 QObject::tr(
"MPEG-2 Encoders (PVR-x50, PVR-500)",
5329 "Recording Profile Group Name") +
5330 QObject::tr(
"Software Encoders (V4L based)",
5331 "Recording Profile Group Name") +
5332 QObject::tr(
"Transcoders",
5333 "Recording Profile Group Name") +
5334 QObject::tr(
"USB MPEG-4 Encoder (Plextor ConvertX, etc)",
5335 "Recording Profile Group Name") +
5336 QObject::tr(
"V4L2 Encoders",
5337 "Recording Profile Group Name");
5339 QString display_rec_groups =
5340 QObject::tr(
"All Programs",
"Recording Group All Programs") +
5341 QObject::tr(
"All",
"Recording Group All Programs -- short form") +
5342 QObject::tr(
"Live TV",
"Recording Group Live TV") +
5343 QObject::tr(
"Default",
"Recording Group Default") +
5344 QObject::tr(
"Deleted",
"Recording Group Deleted");
5346 QString special_program_groups =
5347 QObject::tr(
"All Programs - %1",
5348 "Show all programs from a specific recording group");
5350 QString storage_groups =
5351 QObject::tr(
"Default",
"Storage Group Name") +
5352 QObject::tr(
"Live TV",
"Storage Group Name") +
5353 QObject::tr(
"Thumbnails",
"Storage Group Name") +
5354 QObject::tr(
"DB Backups",
"Storage Group Name");
5356 QString play_groups =
5357 QObject::tr(
"Default",
"Playback Group Name");
5360 return (rec_profile_names.length() +
5361 rec_profile_groups.length() +
5362 display_rec_groups.length() +
5363 special_program_groups.length() +
5364 storage_groups.length() +
5365 play_groups.length());
5380 QByteArray msg_arr = msg.toLatin1();
5381 QString msg_i18n = QObject::tr(msg_arr.constData());
5382 QByteArray msg_i18n_arr = msg_i18n.toLatin1();
5383 return (msg_arr == msg_i18n_arr) ? msg : msg_i18n;
5395 if (pburl.startsWith(
"myth://"))
5397 str.replace(QString(
"%DIR%"), pburl);
5401 QFileInfo dirInfo(pburl);
5402 str.replace(QString(
"%DIR%"), dirInfo.path());
5406 str.replace(QString(
"%TITLE%"),
m_title);
5407 str.replace(QString(
"%SUBTITLE%"),
m_subtitle);
5408 str.replace(QString(
"%SEASON%"), QString::number(
m_season));
5409 str.replace(QString(
"%EPISODE%"), QString::number(
m_episode));
5410 str.replace(QString(
"%TOTALEPISODES%"), QString::number(
m_totalEpisodes));
5413 str.replace(QString(
"%HOSTNAME%"),
m_hostname);
5414 str.replace(QString(
"%CATEGORY%"),
m_category);
5415 str.replace(QString(
"%RECGROUP%"),
m_recGroup);
5417 str.replace(QString(
"%CHANID%"), QString::number(
m_chanId));
5418 str.replace(QString(
"%INETREF%"),
m_inetRef);
5419 str.replace(QString(
"%PARTNUMBER%"), QString::number(
m_partNumber));
5420 str.replace(QString(
"%PARTTOTAL%"), QString::number(
m_partTotal));
5421 str.replace(QString(
"%ORIGINALAIRDATE%"),
5423 static const std::array<const QString,4> s_timeStr
5424 {
"STARTTIME",
"ENDTIME",
"PROGSTART",
"PROGEND", };
5425 const std::array<const QDateTime *,4> time_dtr
5427 for (
size_t i = 0; i < s_timeStr.size(); i++)
5429 str.replace(QString(
"%%1%").arg(s_timeStr[i]),
5430 (time_dtr[i]->toLocalTime()).
toString(
"yyyyMMddhhmmss"));
5431 str.replace(QString(
"%%1ISO%").arg(s_timeStr[i]),
5433 str.replace(QString(
"%%1UTC%").arg(s_timeStr[i]),
5434 time_dtr[i]->
toString(
"yyyyMMddhhmmss"));
5435 str.replace(QString(
"%%1ISOUTC%").arg(s_timeStr[i]),
5438 str.replace(QString(
"%RECORDEDID%"), QString::number(
m_recordedId));
5443 QMap<QString, uint32_t> inUseMap;
5448 query.
prepare(
"SELECT DISTINCT chanid, starttime, recusage "
5449 "FROM inuseprograms WHERE lastupdatetime >= :ONEHOURAGO");
5450 query.
bindValue(
":ONEHOURAGO", oneHourAgo);
5455 while (query.
next())
5458 query.
value(0).toUInt(),
5461 QString inUseForWhat = query.
value(2).toString();
5463 if (!inUseMap.contains(inUseKey))
5464 inUseMap[inUseKey] = 0;
5467 inUseMap[inUseKey] |= FL_INUSEPLAYING;
5469 inUseMap[inUseKey] |= FL_INUSERECORDING;
5471 inUseMap[inUseKey] |= FL_INUSEOTHER;
5479 QMap<QString,bool> is_job_running;
5482 query.
prepare(
"SELECT chanid, starttime, status FROM jobqueue "
5483 "WHERE type = :TYPE");
5486 return is_job_running;
5488 while (query.
next())
5492 int tmpStatus = query.
value(2).toInt();
5493 if ((tmpStatus != 0x0000) &&
5494 (tmpStatus != 0x0001) &&
5495 (!(tmpStatus & 0x0100)))
5502 return is_job_running;
5506 const QString &tmptable,
int recordid)
5511 if (
sched && tmptable.isEmpty())
5519 LOG(VB_GENERAL, LOG_ERR,
5520 "Called from master backend\n\t\t\t"
5521 "with recordid or tmptable, this is not currently supported");
5526 (tmptable.isEmpty()) ?
5527 QString(
"QUERY_GETALLPENDING") :
5528 QString(
"QUERY_GETALLPENDING %1 %2").arg(tmptable).arg(recordid));
5532 LOG(VB_GENERAL, LOG_ALERT,
5533 "LoadFromScheduler(): Error querying master.");
5551 QString columns = QString(
5552 "program.chanid, program.starttime, program.endtime, "
5553 "program.title, program.subtitle, program.description, "
5554 "program.category, channel.channum, channel.callsign, "
5555 "channel.name, program.previouslyshown, channel.commmethod, "
5556 "channel.outputfilters, program.seriesid, program.programid, "
5557 "program.airdate, program.stars, program.originalairdate, "
5558 "program.category_type, oldrecstatus.recordid, "
5559 "oldrecstatus.rectype, oldrecstatus.recstatus, "
5560 "oldrecstatus.findid, program.videoprop+0, program.audioprop+0, "
5561 "program.subtitletypes+0, program.syndicatedepisodenumber, "
5562 "program.partnumber, program.parttotal, "
5563 "program.season, program.episode, program.totalepisodes ");
5565 QString querystr = QString(
5568 "LEFT JOIN channel ON program.chanid = channel.chanid "
5569 "LEFT JOIN oldrecorded AS oldrecstatus ON "
5570 " oldrecstatus.future = 0 AND "
5571 " program.title = oldrecstatus.title AND "
5572 " channel.callsign = oldrecstatus.station AND "
5573 " program.starttime = oldrecstatus.starttime "
5579 querystr += QString(
"LIMIT %1 ").arg(limit);
5580 else if (!querystr.contains(
" LIMIT "))
5581 querystr +=
" LIMIT 20000 ";
5583 MSqlBindings::const_iterator it;
5600 if (start > 0 || limit > 0)
5602 QString countStr = querystr.arg(
"SQL_CALC_FOUND_ROWS program.chanid");
5604 for (it = bindings.begin(); it != bindings.end(); ++it)
5606 if (countStr.contains(it.key()))
5616 if (query.
exec(
"SELECT FOUND_ROWS()") && query.
next())
5617 count = query.
value(0).toUInt();
5621 querystr += QString(
"OFFSET %1 ").arg(start);
5623 querystr = querystr.arg(columns);
5625 for (it = bindings.begin(); it != bindings.end(); ++it)
5627 if (querystr.contains(it.key()))
5641 const QString &groupBy,
const QString &orderBy,
5646 QString queryStr =
"";
5648 if (!where.isEmpty())
5649 queryStr.append(QString(
"WHERE %1 ").arg(where));
5651 if (!groupBy.isEmpty())
5652 queryStr.append(QString(
"GROUP BY %1 ").arg(groupBy));
5654 if (!orderBy.isEmpty())
5655 queryStr.append(QString(
"ORDER BY %1 ").arg(orderBy));
5659 return LoadFromProgram(destination, queryStr, bindings, schedList, 0, 0, count);
5668 QString queryStr = sql;
5682 if (!queryStr.contains(
"WHERE"))
5683 queryStr +=
" WHERE deleted IS NULL AND visible > 0 ";
5691 if (!queryStr.contains(
"GROUP BY"))
5692 queryStr +=
" GROUP BY program.starttime, channel.channum, "
5693 " channel.callsign, program.title ";
5695 if (!queryStr.contains(
"ORDER BY"))
5697 queryStr +=
" ORDER BY program.starttime, ";
5700 if (chanorder !=
"channum")
5701 queryStr += chanorder +
" ";
5703 queryStr +=
"atsc_major_chan,atsc_minor_chan,channum,callsign ";
5708 return LoadFromProgram(destination, queryStr, bindings, schedList, 0, 0, count);
5716 destination.
clear();
5718 if (sql.contains(
" OFFSET", Qt::CaseInsensitive))
5720 LOG(VB_GENERAL, LOG_WARNING,
"LoadFromProgram(): SQL contains OFFSET "
5721 "clause, caller should be updated to use "
5722 "start parameter instead");
5725 if (sql.contains(
" LIMIT", Qt::CaseInsensitive))
5727 LOG(VB_GENERAL, LOG_WARNING,
"LoadFromProgram(): SQL contains LIMIT "
5728 "clause, caller should be updated to use "
5729 "limit parameter instead");
5738 count = query.
size();
5740 while (query.
next())
5744 query.
value(3).toString(),
5746 query.
value(4).toString(),
5748 query.
value(5).toString(),
5749 query.
value(26).toString(),
5750 query.
value(6).toString(),
5752 query.
value(0).toUInt(),
5753 query.
value(7).toString(),
5754 query.
value(8).toString(),
5755 query.
value(9).toString(),
5756 query.
value(12).toString(),
5763 query.
value(13).toString(),
5764 query.
value(14).toString(),
5767 query.
value(16).toFloat(),
5768 query.
value(15).toUInt(),
5769 query.
value(27).toUInt(),
5770 query.
value(28).toUInt(),
5771 query.
value(17).toDate(),
5773 query.
value(19).toUInt(),
5775 query.
value(22).toUInt(),
5778 query.
value(10).toBool(),