Rivendellaudio/lib/rdlog.cpp
Fred Gleason c170dc3d0a 2019-04-29 Fred Gleason <fredg@paravelsystems.com>
* Added code to normalize the case of log names in
	'RDLog::RDLog()'.
2019-04-29 16:29:50 -04:00

773 lines
16 KiB
C++

// rdlog.cpp
//
// Abstract a Rivendell Log.
//
// (C) Copyright 2002-2003,2016-2018 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <qobject.h>
#include "rdapplication.h"
#include "rddb.h"
#include "rdconf.h"
#include "rdescape_string.h"
#include "rdlog.h"
#include "rdlog_line.h"
#include "rdsvc.h"
#include "rdweb.h"
RDLog::RDLog(const QString &name)
{
log_name=name;
//
// Normalize case
//
QString sql=QString("select NAME from LOGS where ")+
"NAME=\""+RDEscapeString(name)+"\"";
RDSqlQuery *q=new RDSqlQuery(sql);
if(q->first()) {
log_name=q->value(0).toString();
}
delete q;
}
QString RDLog::name() const
{
return log_name;
}
bool RDLog::exists() const
{
QString sql=QString("select NAME from LOGS where ")+
"NAME=\""+RDEscapeString(log_name)+"\"";
RDSqlQuery *q=new RDSqlQuery(sql);
if(q->first()) {
delete q;
return true;
}
delete q;
return false;
}
bool RDLog::logExists() const
{
return RDBool(GetStringValue("LOG_EXISTS"));
}
void RDLog::setLogExists(bool state) const
{
SetRow("LOG_EXISTS",RDYesNo(state));
}
RDLog::Type RDLog::type() const
{
return(RDLog::Type)GetIntValue("TYPE");
}
void RDLog::setType(RDLog::Type type) const
{
SetRow("TYPE",(int)type);
}
QString RDLog::description() const
{
return GetStringValue("DESCRIPTION");
}
void RDLog::setDescription(const QString &desc) const
{
SetRow("DESCRIPTION",desc);
}
QString RDLog::service() const
{
return GetStringValue("SERVICE");
}
void RDLog::setService(const QString &svc) const
{
SetRow("SERVICE",svc);
}
QDate RDLog::startDate() const
{
return GetDateValue("START_DATE");
}
void RDLog::setStartDate(const QDate &date) const
{
SetRow("START_DATE",date);
}
QDate RDLog::endDate() const
{
return GetDateValue("END_DATE");
}
void RDLog::setEndDate(const QDate &date) const
{
SetRow("END_DATE",date);
}
QDate RDLog::purgeDate() const
{
return GetDateValue("PURGE_DATE");
}
void RDLog::setPurgeDate(const QDate &date) const
{
SetRow("PURGE_DATE",date);
}
QString RDLog::originUser() const
{
return GetStringValue("ORIGIN_USER");
}
void RDLog::setOriginUser(const QString &user) const
{
SetRow("ORIGIN_USER",user);
}
QDateTime RDLog::originDatetime() const
{
return GetDatetimeValue("ORIGIN_DATETIME");
}
void RDLog::setOriginDatetime(const QDateTime &datetime) const
{
SetRow("ORIGIN_DATETIME",datetime);
}
QDateTime RDLog::linkDatetime() const
{
return GetDatetimeValue("LINK_DATETIME");
}
void RDLog::setLinkDatetime(const QDateTime &datetime) const
{
SetRow("LINK_DATETIME",datetime);
}
QDateTime RDLog::modifiedDatetime() const
{
return GetDatetimeValue("MODIFIED_DATETIME");
}
void RDLog::setModifiedDatetime(const QDateTime &datetime) const
{
SetRow("MODIFIED_DATETIME",datetime);
}
bool RDLog::autoRefresh() const
{
return RDBool(GetStringValue("AUTO_REFRESH"));
}
void RDLog::setAutoRefresh(bool state) const
{
SetRow("AUTO_REFRESH",RDYesNo(state));
}
unsigned RDLog::scheduledTracks() const
{
return GetUnsignedValue("SCHEDULED_TRACKS");
}
void RDLog::setScheduledTracks(unsigned tracks) const
{
SetRow("SCHEDULED_TRACKS",tracks);
}
unsigned RDLog::completedTracks() const
{
return GetUnsignedValue("COMPLETED_TRACKS");
}
void RDLog::setCompletedTracks(unsigned tracks) const
{
SetRow("COMPLETED_TRACKS",tracks);
}
bool RDLog::includeImportMarkers() const
{
return RDBool(GetStringValue("INCLUDE_IMPORT_MARKERS"));
}
void RDLog::setIncludeImportMarkers(bool state)
{
SetRow("INCLUDE_IMPORT_MARKERS",RDYesNo(state));
}
int RDLog::linkQuantity(RDLog::Source src) const
{
switch(src) {
case RDLog::SourceMusic:
return GetIntValue("MUSIC_LINKS");
case RDLog::SourceTraffic:
return GetIntValue("TRAFFIC_LINKS");
}
return 0;
}
void RDLog::setLinkQuantity(RDLog::Source src,int quan) const
{
switch(src) {
case RDLog::SourceMusic:
SetRow("MUSIC_LINKS",quan);
break;
case RDLog::SourceTraffic:
SetRow("TRAFFIC_LINKS",quan);
break;
}
}
void RDLog::updateLinkQuantity(RDLog::Source src) const
{
QString sql;
RDSqlQuery *q;
switch(src) {
case RDLog::SourceMusic:
sql=QString("select LINE_ID from LOG_LINES where ")+
"LOG_NAME=\""+RDEscapeString(log_name)+"\" && "+
QString().sprintf("TYPE=%d",RDLogLine::MusicLink);
q=new RDSqlQuery(sql);
sql=QString("update LOGS set ")+
QString().sprintf("MUSIC_LINKS=%d ",q->size())+
"where NAME=\""+RDEscapeString(log_name)+"\"";
break;
case RDLog::SourceTraffic:
sql=QString("select LINE_ID from LOG_LINES where ")+
"LOG_NAME=\""+RDEscapeString(log_name)+"\" && "+
QString().sprintf("TYPE=%d",RDLogLine::TrafficLink);
q=new RDSqlQuery(sql);
sql=QString("update LOGS set ")+
QString().sprintf("TRAFFIC_LINKS=%d ",q->size())+
"where NAME=\""+RDEscapeString(log_name)+"\"";
break;
default:
return;
}
delete q;
q=new RDSqlQuery(sql);
delete q;
}
RDLog::LinkState RDLog::linkState(RDLog::Source src) const
{
if(linkQuantity(src)==0) {
return RDLog::LinkNotPresent;
}
switch(src) {
case RDLog::SourceMusic:
return (RDLog::LinkState)RDBool(GetStringValue("MUSIC_LINKED"));
case RDLog::SourceTraffic:
return (RDLog::LinkState)RDBool(GetStringValue("TRAFFIC_LINKED"));
}
return RDLog::LinkNotPresent;
}
void RDLog::setLinkState(RDLog::Source src,bool state) const
{
switch(src) {
case RDLog::SourceMusic:
SetRow("MUSIC_LINKED",RDYesNo(state));
break;
case RDLog::SourceTraffic:
SetRow("TRAFFIC_LINKED",RDYesNo(state));
break;
}
}
int RDLog::nextId() const
{
return GetIntValue("NEXT_ID");
}
void RDLog::setNextId(int id) const
{
SetRow("NEXT_ID",id);
}
bool RDLog::isReady() const
{
QString sql;
RDSqlQuery *q;
bool ret=false;
sql=QString("select ")+
"MUSIC_LINKS,"+ // 00
"MUSIC_LINKED,"+ // 01
"TRAFFIC_LINKS,"+ // 02
"TRAFFIC_LINKED,"+ // 03
"SCHEDULED_TRACKS,"+ // 04
"COMPLETED_TRACKS "+ // 05
"from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
ret=((q->value(0).toInt()==0)||(q->value(1).toString()=="Y"))&&
((q->value(2).toInt()==0)||(q->value(3).toString()=="Y"))&&
((q->value(4).toInt()==0)||(q->value(4).toInt()==q->value(5).toInt()));
}
delete q;
return ret;
}
bool RDLog::remove(RDStation *station,RDUser *user,RDConfig *config) const
{
QString sql;
RDSqlQuery *q;
if(removeTracks(station,user,config)<0) {
return false;
}
sql=QString("delete from LOG_LINES where ")+
"LOG_NAME=\""+RDEscapeString(log_name)+"\"";
RDSqlQuery::apply(sql);
sql=QString("delete from LOGS where ")+
"NAME=\""+RDEscapeString(log_name)+"\" && "+
"TYPE=0";
q=new RDSqlQuery(sql);
delete q;
return true;
}
void RDLog::updateTracks()
{
QString sql;
RDSqlQuery *q;
unsigned scheduled=0;
unsigned completed=0;
sql=QString("select LOG_LINES.LINE_ID from ")+
"LOG_LINES left join CART "+
"on LOG_LINES.CART_NUMBER=CART.NUMBER where "+
"LOG_NAME=\""+RDEscapeString(log_name)+"\" && "+
"CART.OWNER is not null";
q=new RDSqlQuery(sql);
completed=q->size();
delete q;
sql=QString("select LINE_ID from LOG_LINES where ")+
"LOG_NAME=\""+RDEscapeString(log_name)+"\" && "+
QString().sprintf("TYPE=%d",RDLogLine::Track);
q=new RDSqlQuery(sql);
scheduled=q->size()+completed;
delete q;
sql=QString("update LOGS set ")+
QString().sprintf("SCHEDULED_TRACKS=%d,",scheduled)+
QString().sprintf("COMPLETED_TRACKS=%u where ",completed)+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}
int RDLog::removeTracks(RDStation *station,RDUser *user,RDConfig *config) const
{
QString sql;
RDSqlQuery *q;
int count=0;
RDCart *cart;
QString owner=log_name;
owner.replace(" ","_");
sql=QString("select NUMBER from CART where ")+
"OWNER=\""+RDEscapeString(owner)+"\"";
q=new RDSqlQuery(sql);
while(q->next()) {
cart=new RDCart(q->value(0).toUInt());
if(!cart->remove(station,user,config)) {
delete cart;
return -1;
}
delete cart;
count++;
}
delete q;
return count;
}
RDLogEvent *RDLog::createLogEvent() const
{
return new RDLogEvent(name());
}
QString RDLog::xml() const
{
QString sql;
RDSqlQuery *q;
QString ret;
sql=QString("select ")+
"NAME,"+ // 00
"SERVICE,"+ // 01
"DESCRIPTION,"+ // 02
"ORIGIN_USER,"+ // 03
"ORIGIN_DATETIME,"+ // 04
"LINK_DATETIME,"+ // 05
"MODIFIED_DATETIME,"+ // 06
"PURGE_DATE,"+ // 07
"AUTO_REFRESH,"+ // 08
"START_DATE,"+ // 09
"END_DATE,"+ // 10
"SCHEDULED_TRACKS,"+ // 11
"COMPLETED_TRACKS,"+ // 12
"MUSIC_LINKS,"+ // 13
"MUSIC_LINKED,"+ // 14
"TRAFFIC_LINKS,"+ // 15
"TRAFFIC_LINKED,"+ // 16
"NEXT_ID "+ // 17
"from LOGS where NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
ret+=" <log>\n";
ret+=" "+RDXmlField("name",log_name);
ret+=" "+RDXmlField("serviceName",q->value(1).toString());
ret+=" "+RDXmlField("description",q->value(2).toString());
ret+=" "+RDXmlField("originUserName",q->value(3).toString());
ret+=" "+RDXmlField("originDatetime",q->value(4).toDateTime());
ret+=" "+RDXmlField("linkDatetime",q->value(5).toDateTime());
ret+=" "+RDXmlField("modifiedDatetime",q->value(6).toDateTime());
ret+=" "+RDXmlField("purgeDate",q->value(7).toDate());
ret+=" "+RDXmlField("autoRefresh",RDBool(q->value(8).toString()));
ret+=" "+RDXmlField("startDate",q->value(9).toDate());
ret+=" "+RDXmlField("endDate",q->value(10).toDate());
ret+=" "+RDXmlField("scheduledTracks",q->value(11).toInt());
ret+=" "+RDXmlField("completedTracks",q->value(12).toInt());
ret+=" "+RDXmlField("musicLinks",q->value(13).toInt());
ret+=" "+RDXmlField("musicLinked",RDBool(q->value(14).toString()));
ret+=" "+RDXmlField("trafficLinks",q->value(15).toInt());
ret+=" "+RDXmlField("trafficLinked",RDBool(q->value(16).toString()));
ret+=" </log>\n";
}
delete q;
return ret;
}
bool RDLog::create(const QString &name,const QString &svc_name,
const QDate &air_date,const QString &user_name,
QString *err_msg,RDConfig *config)
{
QString sql;
RDSqlQuery *q;
int shelflife=-1;
RDSvc::ShelflifeOrigin shelforigin;
QString desc_tmpl;
sql=QString("select ")+
"DEFAULT_LOG_SHELFLIFE,"+ // 00
"LOG_SHELFLIFE_ORIGIN,"+ // 01
"DESCRIPTION_TEMPLATE "+ // 02
"from SERVICES where "+
"NAME=\""+RDEscapeString(svc_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
shelflife=q->value(0).toInt();
shelforigin=(RDSvc::ShelflifeOrigin)q->value(1).toInt();
desc_tmpl=q->value(2).toString();
}
else {
*err_msg=QObject::tr("No such service!");
delete q;
return false;
}
delete q;
sql=QString("insert into LOGS set ")+
"NAME=\""+RDEscapeString(name)+"\","+
"TYPE=0,"+
"DESCRIPTION=\""+RDEscapeString(name)+" log \","+
"ORIGIN_USER=\""+RDEscapeString(user_name)+"\","+
"ORIGIN_DATETIME=now(),"+
"MODIFIED_DATETIME=now(),"+
"LINK_DATETIME=now(),"+
"SERVICE=\""+RDEscapeString(svc_name)+"\"";
if(shelflife>=0) {
switch(shelforigin) {
case RDSvc::OriginCreationDate:
sql+=",PURGE_DATE=\""+
QDate::currentDate().addDays(shelflife).toString("yyyy-MM-dd")+"\"";
break;
case RDSvc::OriginAirDate:
if(air_date.isValid()) {
sql+=",PURGE_DATE=\""+
air_date.addDays(shelflife).toString("yyyy-MM-dd")+"\"";
}
break;
}
}
q=new RDSqlQuery(sql);
if(!q->isActive()) {
*err_msg=QObject::tr("Log already exists!");
delete q;
return false;
}
delete q;
*err_msg=QObject::tr("OK");
return true;
}
bool RDLog::exists(const QString &name)
{
QString sql;
RDSqlQuery *q;
bool ret=false;
sql=QString("select NAME from LOGS where NAME=\"")+
RDEscapeString(name)+"\"";
q=new RDSqlQuery(sql);
ret=q->first();
delete q;
return ret;
}
bool RDLog::remove(const QString &name,RDStation *station,RDUser *user,
RDConfig *config)
{
RDLog *log=new RDLog(name);
bool ret=false;
ret=log->remove(station,user,config);
delete log;
return ret;
}
int RDLog::GetIntValue(const QString &field) const
{
QString sql;
RDSqlQuery *q;
int accum;
sql=QString("select ")+field+" from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
accum=q->value(0).toInt();
delete q;
return accum;
}
delete q;
return 0;
}
unsigned RDLog::GetUnsignedValue(const QString &field) const
{
QString sql;
RDSqlQuery *q;
unsigned accum;
sql=QString("select ")+
field+" from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
accum=q->value(0).toUInt();
delete q;
return accum;
}
delete q;
return 0;
}
QString RDLog::GetStringValue(const QString &field) const
{
QString sql;
RDSqlQuery *q;
QString accum;
sql=QString("select ")+
field+" from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
accum=q->value(0).toString();
}
delete q;
return accum;
}
QDate RDLog::GetDateValue(const QString &field) const
{
QString sql;
RDSqlQuery *q;
QDate accum;
sql=QString("select ")+
field+" from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
accum=q->value(0).toDate();
delete q;
return accum;
}
delete q;
return QDate();
}
QDateTime RDLog::GetDatetimeValue(const QString &field) const
{
QString sql;
RDSqlQuery *q;
QDateTime accum;
sql=QString("select ")+
field+" from LOGS where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
if(q->first()) {
accum=q->value(0).toDateTime();
delete q;
return accum;
}
delete q;
return QDateTime();
}
void RDLog::SetRow(const QString &param,int value) const
{
RDSqlQuery *q;
QString sql;
sql=QString("update LOGS set ")+
param+QString().sprintf("=%d where ",value)+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}
void RDLog::SetRow(const QString &param,unsigned value) const
{
RDSqlQuery *q;
QString sql;
sql=QString("update LOGS set ")+
param+QString().sprintf("=%u where ",value)+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}
void RDLog::SetRow(const QString &param,const QString &value) const
{
RDSqlQuery *q;
QString sql;
sql=QString("update LOGS set ")+
param+"=\""+RDEscapeString(value)+"\" where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}
void RDLog::SetRow(const QString &param,const QDate &value) const
{
RDSqlQuery *q;
QString sql;
sql=QString("update LOGS set ")+
param+"="+RDCheckDateTime(value,"yyyy/MM/dd")+" where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}
void RDLog::SetRow(const QString &param,const QDateTime &value) const
{
RDSqlQuery *q;
QString sql;
sql=QString("update LOGS set ")+
param+"="+RDCheckDateTime(value,"yyyy-MM-dd hh:mm:ss")+" where "+
"NAME=\""+RDEscapeString(log_name)+"\"";
q=new RDSqlQuery(sql);
delete q;
}