2017-12-21 Fred Gleason <fredg@paravelsystems.com>

* Added log locking logic to rdlogmanager(1).
This commit is contained in:
Fred Gleason 2017-12-21 14:27:07 -05:00
parent 97a6045992
commit 54a807fe3d
21 changed files with 413 additions and 51 deletions

View File

@ -16535,3 +16535,5 @@
rdclilogedit(1).
2017-12-21 Fred Gleason <fredg@paravelsystems.com>
* Added log locking logic to the 'SaveLog' Web API call.
2017-12-21 Fred Gleason <fredg@paravelsystems.com>
* Added log locking logic to rdlogmanager(1).

View File

@ -2438,5 +2438,13 @@ Zkuste to, prosím, znovu!</translation>
</source>
<translation>Chyba plnění události</translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2433,5 +2433,13 @@ bitte erneut versuchen!</translation>
</source>
<translation>Event-Füllfehler</translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2425,5 +2425,13 @@ please try again!</source>
<translation>Errores al llenar eventos
</translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2019,5 +2019,13 @@ please try again!</source>
</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2370,5 +2370,13 @@ prøv ein gong til!</translation>
</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2370,5 +2370,13 @@ prøv ein gong til!</translation>
</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -2384,5 +2384,13 @@ por favor, tente novamente!</translation>
<translation>Erros de Auto Preenchimento
</translation>
</message>
<message>
<source>Log in use by</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import failed</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -20,16 +20,15 @@
#include <qmessagebox.h>
#include <rdconf.h>
#include <rd.h>
#include <rdsvc.h>
#include <rddatedecode.h>
#include <rdcreate_log.h>
#include <rdclock.h>
#include <rdlog.h>
#include <rdconf.h>
#include <rdcreate_log.h>
#include <rddatedecode.h>
#include <rddb.h>
#include <rd.h>
#include <rdescape_string.h>
#include <rdlog.h>
#include <rdsvc.h>
#include <rdweb.h>
//
@ -710,13 +709,15 @@ bool RDSvc::import(ImportSource src,const QDate &date,const QString &break_str,
bool RDSvc::generateLog(const QDate &date,const QString &logname,
const QString &nextname,QString *report,RDUser *user)
const QString &nextname,QString *report,RDUser *user,
QString *err_msg)
{
QString sql;
RDSqlQuery *q;
RDClock clock;
QString err_msg;
// QString err_msg;
RDLog *log=NULL;
RDLogLock *log_lock=NULL;
if((!date.isValid()||logname.isEmpty())) {
return false;
@ -728,9 +729,20 @@ bool RDSvc::generateLog(const QDate &date,const QString &logname,
// Generate Log Structure
//
if(RDLog::exists(logname)) {
RDLog::remove(logname,svc_station,user,svc_config);
log_lock=new RDLogLock(logname,user,svc_station,this);
if(!TryLock(log_lock,err_msg)) {
delete log_lock;
return false;
}
RDLog::remove(logname,svc_station,user,svc_config);
delete log_lock;
}
RDLog::create(logname,svc_name,"RDLogManager",err_msg,svc_config);
log_lock=new RDLogLock(logname,user,svc_station,this);
if(!TryLock(log_lock,err_msg)) {
delete log_lock;
return false;
}
RDLog::create(logname,svc_name,"RDLogManager",&err_msg,svc_config);
log=new RDLog(logname);
log->setDescription(RDDateDecode(descriptionTemplate(),date,svc_station,
svc_config,svc_name));
@ -792,18 +804,26 @@ bool RDSvc::generateLog(const QDate &date,const QString &logname,
log->setNextId(count);
log->setAutoRefresh(autoRefresh());
delete log;
delete log_lock;
return true;
}
bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date,
const QString &logname,QString *report)
const QString &logname,QString *report,RDUser *user,
QString *err_msg)
{
QString sql;
RDSqlQuery *q;
QString autofill_errors;
RDLogLock *log_lock=new RDLogLock(logname,user,svc_station,this);
if(!TryLock(log_lock,err_msg)) {
delete log_lock;
return false;
}
emit generationProgress(0);
//
@ -822,6 +842,8 @@ bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date,
import_name.replace(" ","_");
if(!import(src,date,breakString(),trackString(src),import_name)) {
*err_msg=tr("Import failed");
delete log_lock;
return false;
}
@ -943,13 +965,20 @@ bool RDSvc::linkLog(RDSvc::ImportSource src,const QDate &date,
sql=QString().sprintf("drop table `%s`",(const char *)import_name);
q=new RDSqlQuery(sql);
delete q;
delete log_lock;
return true;
}
void RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname)
bool RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname,
RDUser *user,QString *err_msg)
{
RDLogLock *log_lock=new RDLogLock(logname,user,svc_station,this);
if(!TryLock(log_lock,err_msg)) {
delete log_lock;
return false;
}
std::vector<int> cleared_ids;
RDLogLine::Type event_type=RDLogLine::UnknownType;
RDLogLine::Source event_source=RDLogLine::Manual;
@ -1012,7 +1041,9 @@ void RDSvc::clearLogLinks(RDSvc::ImportSource src,const QString &logname)
log->setLinkState(RDLog::SourceMusic,false);
}
delete log;
delete log_lock;
*err_msg="OK";
return true;
}
@ -1447,6 +1478,23 @@ QString RDSvc::timeString(int hour,int secs)
}
bool RDSvc::TryLock(RDLogLock *lock,QString *err_msg)
{
QString username;
QString stationname;
QHostAddress addr;
if(!lock->tryLock(&username,&stationname,&addr)) {
*err_msg=tr("Log in use by")+" "+username+"@"+stationname;
if(stationname!=addr.toString()) {
*err_msg+=" ["+addr.toString()+"]";
}
return false;
}
return true;
}
QString RDSvc::SourceString(ImportSource src) const
{
QString fieldname;

View File

@ -27,6 +27,7 @@
#include <qsqldatabase.h>
#include "rdconfig.h"
#include "rdloglock.h"
#include "rdstation.h"
#include "rduser.h"
@ -86,10 +87,13 @@ class RDSvc : public QObject
const QString &track_str,const QString &dest_table)
const;
bool generateLog(const QDate &date,const QString &logname,
const QString &nextname,QString *report,RDUser *user);
const QString &nextname,QString *report,RDUser *user,
QString *err_msg);
bool linkLog(RDSvc::ImportSource src,const QDate &date,
const QString &logname,QString *report);
void clearLogLinks(RDSvc::ImportSource src,const QString &logname);
const QString &logname,QString *report,RDUser *user,
QString *err_msg);
bool clearLogLinks(RDSvc::ImportSource src,const QString &logname,
RDUser *user,QString *err_msg);
void create(const QString exemplar) const;
void remove() const;
QString xml() const;
@ -104,6 +108,7 @@ class RDSvc : public QObject
void generationProgress(int step);
private:
bool TryLock(RDLogLock *lock,QString *err_msg);
QString SourceString(ImportSource src) const;
QString OsString(ImportOs os) const;
QString FieldString(ImportField field) const;

View File

@ -45,6 +45,7 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname,
QString svcname_table=svcname;
svcname_table.replace(" ","_");
unsigned schema=0;
QString err_msg;
QApplication a(argc,argv,false);
@ -112,8 +113,8 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname,
rdstation_conf,config,svc->name()),
RDDateDecode(svc->nameTemplate(),start_date.addDays(1),
rdstation_conf,config,svc->name()),
&unused_report,rduser)) {
fprintf(stderr,"rdlogmanager: unable to generate log\n");
&unused_report,rduser,&err_msg)) {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
return 256;
}
log->updateTracks();
@ -147,15 +148,24 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname,
}
report="";
log->removeTracks(rdstation_conf,rduser,config);
svc->clearLogLinks(RDSvc::Traffic,logname);
svc->clearLogLinks(RDSvc::Music,logname);
if(svc->linkLog(RDSvc::Music,start_date,logname,&report)) {
if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
return 256;
}
if(!svc->clearLogLinks(RDSvc::Music,logname,rduser,&err_msg)) {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
return 256;
}
if(svc->linkLog(RDSvc::Music,start_date,logname,&report,rduser,&err_msg)) {
printf("%s\n",(const char*)report);
}
else {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
/*
fprintf(stderr,
"rdlogmanager: unable to open music schedule file at \"%s\"\n",
(const char *)svc->importFilename(RDSvc::Music,start_date));
*/
exit(256);
}
}
@ -176,14 +186,21 @@ int RunLogOperation(int argc,char *argv[],const QString &svcname,
return 256;
}
report="";
svc->clearLogLinks(RDSvc::Traffic,logname);
if(svc->linkLog(RDSvc::Traffic,start_date,logname,&report)) {
if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
return 256;
}
if(svc->linkLog(RDSvc::Traffic,start_date,logname,&report,rduser,
&err_msg)) {
printf("%s\n",(const char*)report);
}
else {
fprintf(stderr,"rdlogmanager: %s\n",(const char *)err_msg);
/*
fprintf(stderr,
"rdlogmanager: unable to open traffic schedule file at \"%s\"\n",
(const char *)svc->importFilename(RDSvc::Traffic,start_date));
*/
}
}

View File

@ -298,6 +298,7 @@ void GenerateLog::createData()
QString str1;
QString str2;
unsigned tracks=0;
QString err_msg;
//
// Generate Log
@ -359,13 +360,20 @@ void GenerateLog::createData()
connect(svc,SIGNAL(generationProgress(int)),
gen_progress_dialog,SLOT(setProgress(int)));
svc->generateLog(gen_date_edit->date(),
if(!svc->generateLog(gen_date_edit->date(),
RDDateDecode(svc->nameTemplate(),gen_date_edit->date(),
rdstation_conf,log_config,svc->name()),
RDDateDecode(svc->nameTemplate(),gen_date_edit->date().
addDays(1),rdstation_conf,log_config,
svc->name()),
&unused_report,rduser);
&unused_report,rduser,&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to generate log")+": "+err_msg);
gen_progress_dialog->setProgress(gen_progress_dialog->totalSteps());
delete svc;
delete log;
return;
}
log->updateTracks();
delete log;
delete svc;
@ -392,6 +400,7 @@ void GenerateLog::createData()
void GenerateLog::musicData()
{
unsigned tracks=0;
QString err_msg;
RDSvc *svc=
new RDSvc(gen_service_box->currentText(),rdstation_conf,log_config,this);
@ -428,13 +437,33 @@ void GenerateLog::musicData()
}
}
log->removeTracks(rdstation_conf,rduser,log_config);
svc->clearLogLinks(RDSvc::Traffic,logname);
svc->clearLogLinks(RDSvc::Music,logname);
if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to clear traffic links")+": "+err_msg);
delete log;
delete svc;
return;
}
if(!svc->clearLogLinks(RDSvc::Music,logname,rduser,&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to clear music links")+": "+err_msg);
delete log;
delete svc;
return;
}
}
connect(svc,SIGNAL(generationProgress(int)),
gen_progress_dialog,SLOT(setProgress(int)));
QString report;
svc->linkLog(RDSvc::Music,gen_date_edit->date(),logname,&report);
if(!svc->linkLog(RDSvc::Music,gen_date_edit->date(),logname,&report,rduser,
&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to link music log")+": "+err_msg);
delete log;
delete svc;
return;
}
delete log;
delete svc;
if(!report.isEmpty()) {
@ -446,6 +475,7 @@ void GenerateLog::musicData()
void GenerateLog::trafficData()
{
QString err_msg;
RDSvc *svc=
new RDSvc(gen_service_box->currentText(),rdstation_conf,log_config,this);
QString logname=RDDateDecode(svc->nameTemplate(),gen_date_edit->date(),
@ -464,13 +494,26 @@ void GenerateLog::trafficData()
delete svc;
return;
}
svc->clearLogLinks(RDSvc::Traffic,logname);
if(!svc->clearLogLinks(RDSvc::Traffic,logname,rduser,&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to clear traffic links")+": "+err_msg);
delete log;
delete svc;
return;
}
}
connect(svc,SIGNAL(generationProgress(int)),
gen_progress_dialog,SLOT(setProgress(int)));
QString report;
svc->linkLog(RDSvc::Traffic,gen_date_edit->date(),logname,&report);
if(!svc->linkLog(RDSvc::Traffic,gen_date_edit->date(),logname,&report,rduser,
&err_msg)) {
QMessageBox::warning(this,"RDLogManager - "+tr("Error"),
tr("Unable to link traffic log")+": "+err_msg);
delete log;
delete svc;
return;
}
delete log;
delete svc;
if(!report.isEmpty()) {

View File

@ -855,6 +855,30 @@ Opětovné sloučení tato data smaže. Sloučit znovu?</translation>
<source>Generate Log - User: </source>
<translation>Vytvořit zápis - Uživatel: </translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -855,6 +855,30 @@ Einbinden wird diese entfernen. Fortfahren?</translation>
<source>Generate Log - User: </source>
<translation>Generiere Log - User: </translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -857,6 +857,30 @@ removerá estos datos. ¿Remezclar?</translation>
<source>Generate Log - User: </source>
<translation>Generar lista - Usuario: </translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -837,6 +837,30 @@ will remove this data. Remerge?</source>
<source>Generate Log - User: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -868,6 +868,30 @@ Flettar du på nytt, vil du fjerna desse dataa. Flett på nytt?</translation>
<source>Generate Log - User: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -868,6 +868,30 @@ Flettar du på nytt, vil du fjerna desse dataa. Flett på nytt?</translation>
<source>Generate Log - User: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -857,6 +857,30 @@ Re-agregar removerá estes dados. Re-agregar? </translation>
<source>Traffic Exists</source>
<translation>Tráfego Existente</translation>
</message>
<message>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to generate log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear traffic links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to clear music links</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link music log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to link traffic log</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImportListView</name>

View File

@ -37,10 +37,7 @@
MainObject::MainObject(QObject *parent)
:QObject(parent)
{
QString log_name="";
RDSvc::ImportSource import_source=RDSvc::Traffic;
RDConfig *config=NULL;
RDStation *station=NULL;
test_import_source=RDSvc::Traffic;
unsigned schema=0;
//
@ -51,16 +48,16 @@ MainObject::MainObject(QObject *parent)
LOG_UNLINK_TEST_USAGE);
for(unsigned i=0;i<cmd->keys();i++) {
if(cmd->key(i)=="--log") {
log_name=cmd->value(i);
test_log_name=cmd->value(i);
cmd->setProcessed(i,true);
}
if(cmd->key(i)=="--source") {
if(cmd->value(i).lower()=="traffic") {
import_source=RDSvc::Traffic;
test_import_source=RDSvc::Traffic;
}
else {
if(cmd->value(i).lower()=="music") {
import_source=RDSvc::Music;
test_import_source=RDSvc::Music;
}
else {
fprintf(stderr,
@ -76,7 +73,7 @@ MainObject::MainObject(QObject *parent)
exit(256);
}
}
if(log_name.isEmpty()) {
if(test_log_name.isEmpty()) {
fprintf(stderr,"log_unlink_test: you must specify a log name with \"--log=\"\n");
exit(1);
}
@ -84,9 +81,9 @@ MainObject::MainObject(QObject *parent)
//
// Load Configuration
//
config=new RDConfig();
config->load();
config->setModuleName("reserve_carts_test");
test_config=new RDConfig();
test_config->load();
test_config->setModuleName("reserve_carts_test");
//
// Open Database
@ -98,18 +95,31 @@ MainObject::MainObject(QObject *parent)
delete cmd;
exit(256);
}
station=new RDStation(config->stationName());
test_station=new RDStation(test_config->stationName());
test_ripc=new RDRipc(test_station,test_config,this);
connect(test_ripc,SIGNAL(userChanged()),this,SLOT(userData()));
test_ripc->connectHost("localhost",RIPCD_TCP_PORT,test_config->password());
}
void MainObject::userData()
{
QString err_msg;
//
// Run the Test
//
if(!RDLog::exists(log_name)) {
if(!RDLog::exists(test_log_name)) {
fprintf(stderr,"log_unlink_test: no such log\n");
exit(1);
}
RDLog *log=new RDLog(log_name);
RDSvc *svc=new RDSvc(log->service(),station,config,this);
svc->clearLogLinks(import_source,log_name);
RDLog *log=new RDLog(test_log_name);
RDSvc *svc=new RDSvc(log->service(),test_station,test_config,this);
if(!svc->clearLogLinks(test_import_source,test_log_name,
new RDUser(test_ripc->user()),&err_msg)) {
fprintf(stderr,"log_unlink_test: %s\n",(const char *)err_msg);
exit(1);
}
exit(0);
}

View File

@ -23,12 +23,25 @@
#include <qobject.h>
#include <rdripc.h>
#include <rdstation.h>
#define LOG_UNLINK_TEST_USAGE "[options]\n\nTest the Rivendell log unlinker methods\n\nOptions are:\n--log=<log-name>\n Name of log to unlink.\n\n--source=music|traffic\n Data source to unlink\n\n"
class MainObject : public QObject
{
public:
MainObject(QObject *parent=0);
private slots:
void userData();
private:
RDSvc::ImportSource test_import_source;
QString test_log_name;
RDStation *test_station;
RDRipc *test_ripc;
RDConfig *test_config;
};