2025-03-07 Fred Gleason <fredg@paravelsystems.com>

* Added a check for orphaned database tables in rddbmgr(8).

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2025-03-07 19:07:14 -05:00
parent ea2e9dec40
commit 80a960e84a
7 changed files with 579 additions and 13 deletions

View File

@ -24962,3 +24962,5 @@
2025-03-07 Fred Gleason <fredg@paravelsystems.com>
* Fixed a bug in 'RDCart::updateLength()' that could cause SQL
errors.
2025-03-07 Fred Gleason <fredg@paravelsystems.com>
* Added a check for orphaned database tables in rddbmgr(8).

View File

@ -184,7 +184,7 @@
</term>
<listitem>
<para>
Disable all checks. Add check for log line IDs. Specifically,
Disable all checks, then add check for log line IDs. Specifically,
verify that all IDs are valid (>0) and unique within the context
of the given log.
</para>
@ -245,7 +245,7 @@
</term>
<listitem>
<para>
Disable all checks. Add check for orphaned audio files.
Disable all checks, then add check for orphaned audio files.
</para>
</listitem>
</varlistentry>
@ -256,7 +256,7 @@
</term>
<listitem>
<para>
Disable all checks. Add check for orphaned carts.
Disable all checks, then add check for orphaned carts.
</para>
</listitem>
</varlistentry>
@ -267,7 +267,7 @@
</term>
<listitem>
<para>
Disable all checks. Add check for orphaned cuts.
Disable all checks, then add check for orphaned cuts.
</para>
</listitem>
</varlistentry>
@ -278,7 +278,18 @@
</term>
<listitem>
<para>
Disable all checks. Add check for orphaned voice tracks.
Disable all checks, then add check for orphaned voice tracks.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--orphaned-tables</option>
</term>
<listitem>
<para>
Disable all checks, then add check for orphaned database tables.
</para>
</listitem>
</varlistentry>

View File

@ -1,6 +1,6 @@
## Makefile.am
##
## (C) Copyright 2018-2022 Fred Gleason <fredg@paravelsystems.com>
## (C) Copyright 2018-2025 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
@ -27,7 +27,8 @@ moc_%.cpp: %.h
sbin_PROGRAMS = rddbmgr
dist_rddbmgr_SOURCES = check.cpp\
dist_rddbmgr_SOURCES = analyze.cpp\
check.cpp\
create.cpp\
modify.cpp\
printstatus.cpp\

View File

@ -0,0 +1,43 @@
// analyze.cpp
//
// Routines for --analyze for rddbmgr(8)
//
// (C) Copyright 2025 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 <netdb.h>
#include <unistd.h>
#include <sys/stat.h>
#include <QRegExp>
#include <rd.h>
#include <rdconf.h>
#include <rddb.h>
#include <rdescape_string.h>
#include <rdpaths.h>
#include "rddbmgr.h"
bool MainObject::Analyze(int schema,QString *err_msg) const
{
printf(" This command runs the 'MainObject::Analyze()' method,\n");
printf(" located in 'utils/rddbmgr/analyze.cpp'.\n");
return true;
}

View File

@ -63,6 +63,15 @@ bool MainObject::Check(QString *err_msg)
printf("done.\n\n");
}
//
// Check for Orphaned Tables
//
if(db_check_all||db_check_orphaned_tables) {
printf("Checking DB tables...\n");
CheckOrphanedTables();
printf("done.\n\n");
}
//
// Check for Orphaned Voice Tracks
//
@ -870,6 +879,465 @@ void MainObject::CheckOrphanedAudio() const
}
void MainObject::CheckOrphanedTables() const
{
QStringList missing;
QStringList extra;
QStringList canonical=GetCanonicalTables(db_current_schema);
if(canonical.size()==0) {
printf(" Unsupported schema for analysis, skipping\n");
return;
}
if(!CheckTableNames(canonical,missing,extra)) {
for(int i=0;i<missing.size();i++) {
printf(" WARNING: missing table \"%s\"\n",
missing.at(i).toUtf8().constData());
}
for(int i=0;i<extra.size();i++) {
printf(" Found orphaned table \"%s\". Remove (y/N)?",
extra.at(i).toUtf8().constData());
if(UserResponse()) {
DropTable(extra.at(i));
}
}
}
}
bool MainObject::CheckTableNames(const QStringList &canonical,
QStringList &missing,QStringList &extra) const
{
//
// Get Existing Tables
//
QStringList existing;
QString sql=QString("show tables");
RDSqlQuery *q=new RDSqlQuery(sql);
while(q->next()) {
existing.push_back(q->value(0).toString());
}
delete q;
//
// Find Missing Tables
//
for(int i=0;i<canonical.size();i++) {
if(canonical.at(i).left(1)!="*") { // Don't look for ephemeral tables
if(!existing.contains(canonical.at(i))) {
missing.push_back(canonical.at(i));
}
}
}
//
// Find Extra Tables
//
bool found;
for(int i=0;i<existing.size();i++) {
found=false;
for(int j=0;j<canonical.size();j++) {
QRegExp exp(canonical.at(j));
exp.setPatternSyntax(QRegExp::Wildcard);
if(exp.indexIn(existing.at(i),0)>=0) {
found=true;
}
}
if(!found) {
extra.push_back(existing.at(i));
}
}
return (missing.size()==0)&&(extra.size()==0);
}
QStringList MainObject::GetCanonicalTables(int schema) const
{
QStringList tables;
switch(schema) {
case 275: // v2.19.x
tables.push_back("AUDIO_PERMS");
tables.push_back("AUDIO_PORTS");
tables.push_back("AUTOFILLS");
tables.push_back("AUX_METADATA");
tables.push_back("CART");
tables.push_back("CARTSLOTS");
tables.push_back("CLIPBOARD");
tables.push_back("CLOCKS");
tables.push_back("CLOCK_PERMS");
tables.push_back("CUTS");
tables.push_back("CUT_EVENTS");
tables.push_back("DECKS");
tables.push_back("DECK_EVENTS");
tables.push_back("DROPBOXES");
tables.push_back("DROPBOX_PATHS");
tables.push_back("DROPBOX_SCHED_CODES");
tables.push_back("ENCODER_CHANNELS");
tables.push_back("ENCODER_BITRATES");
tables.push_back("ENCODER_SAMPLERATES");
tables.push_back("ENCODERS");
tables.push_back("EVENTS");
tables.push_back("EVENT_PERMS");
tables.push_back("EXTENDED_PANELS");
tables.push_back("EXTENDED_PANEL_NAMES");
tables.push_back("FEEDS");
tables.push_back("FEED_PERMS");
tables.push_back("GPIO_EVENTS");
tables.push_back("GPIS");
tables.push_back("GPOS");
tables.push_back("GROUPS");
tables.push_back("HOSTVARS");
tables.push_back("IMPORT_TEMPLATES");
tables.push_back("INPUTS");
tables.push_back("ISCI_XREFERENCE");
tables.push_back("JACK_CLIENTS");
tables.push_back("LIVEWIRE_GPIO_SLOTS");
tables.push_back("LOGS");
tables.push_back("LOGS");
tables.push_back("LOG_MODES");
tables.push_back("MATRICES");
tables.push_back("OUTPUTS");
tables.push_back("NOWNEXT_PLUGINS");
tables.push_back("PANELS");
tables.push_back("PANEL_NAMES");
tables.push_back("PODCASTS");
tables.push_back("RDAIRPLAY");
tables.push_back("RDAIRPLAY_CHANNELS");
tables.push_back("RDCATCH");
tables.push_back("RDHOTKEYS");
tables.push_back("RDLIBRARY");
tables.push_back("RDLOGEDIT");
tables.push_back("RDPANEL");
tables.push_back("RDPANEL_CHANNELS");
tables.push_back("RECORDINGS");
tables.push_back("REPLICATORS");
tables.push_back("REPLICATOR_MAP");
tables.push_back("REPL_CART_STATE");
tables.push_back("REPL_CUT_STATE");
tables.push_back("REPORTS");
tables.push_back("REPORT_GROUPS");
tables.push_back("REPORT_SERVICES");
tables.push_back("REPORT_STATIONS");
tables.push_back("SCHED_CODES");
tables.push_back("SERVICES");
tables.push_back("SERVICE_CLOCKS");
tables.push_back("SERVICE_PERMS");
tables.push_back("STATIONS");
tables.push_back("SWITCHER_NODES");
tables.push_back("SYSTEM");
tables.push_back("TRIGGERS");
tables.push_back("TTYS");
tables.push_back("USERS");
tables.push_back("USER_PERMS");
tables.push_back("USER_SERVICE_PERMS");
tables.push_back("VERSION");
tables.push_back("VGUEST_RESOURCES");
tables.push_back("WEBAPI_AUTHS");
tables.push_back("WEB_CONNECTIONS");
tables.push_back("*_CLK");
tables.push_back("*_FLG");
tables.push_back("*_LOG");
tables.push_back("*_PRE");
tables.push_back("*_POST");
tables.push_back("*_RULES");
tables.push_back("*_SRT");
tables.push_back("*_STACK");
break;
case 308: // v3.0.x
tables.push_back("AUDIO_CARDS");
tables.push_back("AUDIO_INPUTS");
tables.push_back("AUDIO_OUTPUTS");
tables.push_back("AUDIO_PERMS");
tables.push_back("AUTOFILLS");
tables.push_back("AUX_METADATA");
tables.push_back("CART");
tables.push_back("CARTSLOTS");
tables.push_back("CART_SCHED_CODES");
tables.push_back("CAST_DOWNLOADS");
tables.push_back("CLIPBOARD");
tables.push_back("CLOCKS");
tables.push_back("CLOCK_LINES");
tables.push_back("CLOCK_PERMS");
tables.push_back("CUTS");
tables.push_back("CUT_EVENTS");
tables.push_back("DECKS");
tables.push_back("DECK_EVENTS");
tables.push_back("DROPBOXES");
tables.push_back("DROPBOX_PATHS");
tables.push_back("DROPBOX_SCHED_CODES");
tables.push_back("ELR_LINES");
tables.push_back("ENCODER_CHANNELS");
tables.push_back("ENCODER_BITRATES");
tables.push_back("ENCODER_SAMPLERATES");
tables.push_back("ENCODERS");
tables.push_back("EVENTS");
tables.push_back("EVENT_LINES");
tables.push_back("EVENT_PERMS");
tables.push_back("EXTENDED_PANELS");
tables.push_back("EXTENDED_PANEL_NAMES");
tables.push_back("FEEDS");
tables.push_back("FEED_PERMS");
tables.push_back("GPIO_EVENTS");
tables.push_back("GPIS");
tables.push_back("GPOS");
tables.push_back("GROUPS");
tables.push_back("HOSTVARS");
tables.push_back("IMPORTER_LINES");
tables.push_back("IMPORT_TEMPLATES");
tables.push_back("INPUTS");
tables.push_back("ISCI_XREFERENCE");
tables.push_back("JACK_CLIENTS");
tables.push_back("LIVEWIRE_GPIO_SLOTS");
tables.push_back("LOGS");
tables.push_back("LOGS");
tables.push_back("LOG_LINES");
tables.push_back("LOG_MACHINES");
tables.push_back("LOG_MODES");
tables.push_back("MATRICES");
tables.push_back("OUTPUTS");
tables.push_back("PANELS");
tables.push_back("PANEL_NAMES");
tables.push_back("PODCASTS");
tables.push_back("PYPAD_INSTANCES");
tables.push_back("RDAIRPLAY");
tables.push_back("RDAIRPLAY_CHANNELS");
tables.push_back("RDCATCH");
tables.push_back("RDHOTKEYS");
tables.push_back("RDLIBRARY");
tables.push_back("RDLOGEDIT");
tables.push_back("RDPANEL");
tables.push_back("RDPANEL_CHANNELS");
tables.push_back("RECORDINGS");
tables.push_back("REPLICATORS");
tables.push_back("REPLICATOR_MAP");
tables.push_back("REPL_CART_STATE");
tables.push_back("REPL_CUT_STATE");
tables.push_back("REPORTS");
tables.push_back("REPORT_GROUPS");
tables.push_back("REPORT_SERVICES");
tables.push_back("REPORT_STATIONS");
tables.push_back("RULE_LINES");
tables.push_back("SCHED_CODES");
tables.push_back("SERVICES");
tables.push_back("SERVICE_CLOCKS");
tables.push_back("SERVICE_PERMS");
tables.push_back("STACK_LINES");
tables.push_back("STACK_SCHED_CODES");
tables.push_back("STATIONS");
tables.push_back("SWITCHER_NODES");
tables.push_back("SYSTEM");
tables.push_back("TRIGGERS");
tables.push_back("TTYS");
tables.push_back("USERS");
tables.push_back("USER_PERMS");
tables.push_back("USER_SERVICE_PERMS");
tables.push_back("VERSION");
tables.push_back("VGUEST_RESOURCES");
tables.push_back("WEBAPI_AUTHS");
tables.push_back("WEB_CONNECTIONS");
break;
case 310: // v3.1.x
tables.push_back("AUDIO_CARDS");
tables.push_back("AUDIO_INPUTS");
tables.push_back("AUDIO_OUTPUTS");
tables.push_back("AUDIO_PERMS");
tables.push_back("AUTOFILLS");
tables.push_back("AUX_METADATA");
tables.push_back("CART");
tables.push_back("CARTSLOTS");
tables.push_back("CART_SCHED_CODES");
tables.push_back("CAST_DOWNLOADS");
tables.push_back("CLIPBOARD");
tables.push_back("CLOCKS");
tables.push_back("CLOCK_LINES");
tables.push_back("CLOCK_PERMS");
tables.push_back("CUTS");
tables.push_back("CUT_EVENTS");
tables.push_back("DECKS");
tables.push_back("DECK_EVENTS");
tables.push_back("DROPBOXES");
tables.push_back("DROPBOX_PATHS");
tables.push_back("DROPBOX_SCHED_CODES");
tables.push_back("ELR_LINES");
tables.push_back("ENCODER_CHANNELS");
tables.push_back("ENCODER_BITRATES");
tables.push_back("ENCODER_SAMPLERATES");
tables.push_back("ENCODERS");
tables.push_back("EVENTS");
tables.push_back("EVENT_LINES");
tables.push_back("EVENT_PERMS");
tables.push_back("EXTENDED_PANELS");
tables.push_back("EXTENDED_PANEL_NAMES");
tables.push_back("FEEDS");
tables.push_back("FEED_PERMS");
tables.push_back("GPIO_EVENTS");
tables.push_back("GPIS");
tables.push_back("GPOS");
tables.push_back("GROUPS");
tables.push_back("HOSTVARS");
tables.push_back("IMPORTER_LINES");
tables.push_back("IMPORT_TEMPLATES");
tables.push_back("INPUTS");
tables.push_back("ISCI_XREFERENCE");
tables.push_back("JACK_CLIENTS");
tables.push_back("LIVEWIRE_GPIO_SLOTS");
tables.push_back("LOGS");
tables.push_back("LOGS");
tables.push_back("LOG_LINES");
tables.push_back("LOG_MACHINES");
tables.push_back("LOG_MODES");
tables.push_back("MATRICES");
tables.push_back("NEXUS_FIELDS");
tables.push_back("NEXUS_QUEUE");
tables.push_back("NEXUS_SERVER");
tables.push_back("NEXUS_STATIONS");
tables.push_back("OUTPUTS");
tables.push_back("PANELS");
tables.push_back("PANEL_NAMES");
tables.push_back("PODCASTS");
tables.push_back("PYPAD_INSTANCES");
tables.push_back("RDAIRPLAY");
tables.push_back("RDAIRPLAY_CHANNELS");
tables.push_back("RDCATCH");
tables.push_back("RDHOTKEYS");
tables.push_back("RDLIBRARY");
tables.push_back("RDLOGEDIT");
tables.push_back("RDPANEL");
tables.push_back("RDPANEL_CHANNELS");
tables.push_back("RECORDINGS");
tables.push_back("REPLICATORS");
tables.push_back("REPLICATOR_MAP");
tables.push_back("REPL_CART_STATE");
tables.push_back("REPL_CUT_STATE");
tables.push_back("REPORTS");
tables.push_back("REPORT_GROUPS");
tables.push_back("REPORT_SERVICES");
tables.push_back("REPORT_STATIONS");
tables.push_back("RULE_LINES");
tables.push_back("SCHED_CODES");
tables.push_back("SERVICES");
tables.push_back("SERVICE_CLOCKS");
tables.push_back("SERVICE_PERMS");
tables.push_back("STACK_LINES");
tables.push_back("STACK_SCHED_CODES");
tables.push_back("STATIONS");
tables.push_back("SWITCHER_NODES");
tables.push_back("SYSTEM");
tables.push_back("TRIGGERS");
tables.push_back("TTYS");
tables.push_back("USERS");
tables.push_back("USER_PERMS");
tables.push_back("USER_SERVICE_PERMS");
tables.push_back("VERSION");
tables.push_back("VGUEST_RESOURCES");
tables.push_back("WEBAPI_AUTHS");
tables.push_back("WEB_CONNECTIONS");
break;
case 375: // v3.2.x
tables.push_back("AUDIO_CARDS");
tables.push_back("AUDIO_INPUTS");
tables.push_back("AUDIO_OUTPUTS");
tables.push_back("AUDIO_PERMS");
tables.push_back("AUTOFILLS");
tables.push_back("AUX_METADATA");
tables.push_back("CART");
tables.push_back("CARTSLOTS");
tables.push_back("CART_SCHED_CODES");
tables.push_back("CLIPBOARD");
tables.push_back("CLOCKS");
tables.push_back("CLOCK_LINES");
tables.push_back("CLOCK_PERMS");
tables.push_back("CUTS");
tables.push_back("CUT_EVENTS");
tables.push_back("DECKS");
tables.push_back("DECK_EVENTS");
tables.push_back("DROPBOXES");
tables.push_back("DROPBOX_PATHS");
tables.push_back("DROPBOX_SCHED_CODES");
tables.push_back("ELR_LINES");
tables.push_back("ENCODER_PRESETS");
tables.push_back("EVENTS");
tables.push_back("EVENT_LINES");
tables.push_back("EVENT_PERMS");
tables.push_back("EXTENDED_PANELS");
tables.push_back("EXTENDED_PANEL_NAMES");
tables.push_back("FEEDS");
tables.push_back("FEED_IMAGES");
tables.push_back("FEED_PERMS");
tables.push_back("GPIO_EVENTS");
tables.push_back("GPIS");
tables.push_back("GPOS");
tables.push_back("GROUPS");
tables.push_back("HOSTVARS");
tables.push_back("IMPORTER_LINES");
tables.push_back("IMPORT_TEMPLATES");
tables.push_back("INPUTS");
tables.push_back("ISCI_XREFERENCE");
tables.push_back("JACK_CLIENTS");
tables.push_back("LIVEWIRE_GPIO_SLOTS");
tables.push_back("LOGS");
tables.push_back("LOGS");
tables.push_back("LOG_LINES");
tables.push_back("LOG_MACHINES");
tables.push_back("LOG_MODES");
tables.push_back("MATRICES");
tables.push_back("NEXUS_FIELDS");
tables.push_back("NEXUS_QUEUE");
tables.push_back("NEXUS_SERVER");
tables.push_back("NEXUS_STATIONS");
tables.push_back("OUTPUTS");
tables.push_back("PANELS");
tables.push_back("PANEL_NAMES");
tables.push_back("PODCASTS");
tables.push_back("PYPAD_INSTANCES");
tables.push_back("RDAIRPLAY");
tables.push_back("RDAIRPLAY_CHANNELS");
tables.push_back("RDCATCH");
tables.push_back("RDHOTKEYS");
tables.push_back("RDLIBRARY");
tables.push_back("RDLOGEDIT");
tables.push_back("RDPANEL");
tables.push_back("RDPANEL_CHANNELS");
tables.push_back("RECORDINGS");
tables.push_back("REPLICATORS");
tables.push_back("REPLICATOR_MAP");
tables.push_back("REPL_CART_STATE");
tables.push_back("REPL_CUT_STATE");
tables.push_back("REPORTS");
tables.push_back("REPORT_GROUPS");
tables.push_back("REPORT_SERVICES");
tables.push_back("REPORT_STATIONS");
tables.push_back("RULE_LINES");
tables.push_back("SCHED_CODES");
tables.push_back("SERVICES");
tables.push_back("SERVICE_CLOCKS");
tables.push_back("SERVICE_PERMS");
tables.push_back("STACK_LINES");
tables.push_back("STACK_SCHED_CODES");
tables.push_back("STATIONS");
tables.push_back("SUPERFEED_MAPS");
tables.push_back("SWITCHER_NODES");
tables.push_back("SYSTEM");
tables.push_back("TRIGGERS");
tables.push_back("TTYS");
tables.push_back("USERS");
tables.push_back("USER_PERMS");
tables.push_back("USER_SERVICE_PERMS");
tables.push_back("VERSION");
tables.push_back("VGUEST_RESOURCES");
tables.push_back("WEBAPI_AUTHS");
tables.push_back("WEB_CONNECTIONS");
break;
}
return tables;
}
void MainObject::CheckLogLineIds(const QString &logname) const
{
QString sql;

View File

@ -58,6 +58,7 @@ MainObject::MainObject(QObject *parent)
db_check_orphaned_carts=false;
db_check_orphaned_cuts=false;
db_check_orphaned_tracks=false;
db_check_orphaned_tables=false;
db_check_strings=false;
db_check_log_line_ids=false;
@ -89,6 +90,18 @@ MainObject::MainObject(QObject *parent)
//
RDCmdSwitch *cmd=new RDCmdSwitch("rddbmgr",RDDBMGR_USAGE);
for(unsigned i=0;i<cmd->keys();i++) {
#ifdef RDDBMGR_ENABLE_ANALYZE
if(cmd->key(i)=="--analyze") {
MainObject::Command command=MainObject::AnalyzeCommand;
if((db_command!=MainObject::NoCommand)&&
(db_command!=MainObject::CheckCommand)) {
fprintf(stderr,"rddbmgr: exactly one command must be specified\n");
exit(1);
}
db_command=command;
cmd->setProcessed(i,true);
}
#endif // RDDBMGR_ENABLE_ANALYZE
if(cmd->key(i)=="--check") {
MainObject::Command command=MainObject::CheckCommand;
if((db_command!=MainObject::NoCommand)&&
@ -236,6 +249,11 @@ MainObject::MainObject(QObject *parent)
db_check_orphaned_tracks=true;
cmd->setProcessed(i,true);
}
if(cmd->key(i)=="--orphaned-tables") {
db_check_all=false;
db_check_orphaned_tables=true;
cmd->setProcessed(i,true);
}
if(cmd->key(i)=="--check-strings") {
db_check_all=false;
db_check_strings=true;
@ -334,9 +352,9 @@ MainObject::MainObject(QObject *parent)
//
// Resolve Target Schema
//
int schema=GetCurrentSchema();
if(schema>RD_VERSION_DATABASE) {
fprintf(stderr,"rddbmgr: unknown current schema [%d]\n",schema);
db_current_schema=GetCurrentSchema();
if(db_current_schema>RD_VERSION_DATABASE) {
fprintf(stderr,"rddbmgr: unknown current schema [%d]\n",db_current_schema);
exit(1);
}
if(set_schema>0) {
@ -348,7 +366,7 @@ MainObject::MainObject(QObject *parent)
else {
if(set_version.isEmpty()) {
set_schema=RD_VERSION_DATABASE;
if(set_schema<schema) {
if(set_schema<db_current_schema) {
fprintf(stderr,"rddbmgr: reversion implied, you must explicitly specify the target schema\n");
exit(1);
}
@ -367,6 +385,10 @@ MainObject::MainObject(QObject *parent)
//
QString err_msg;
switch(db_command) {
case MainObject::AnalyzeCommand:
ok=Analyze(db_current_schema,&err_msg);
break;
case MainObject::CheckCommand:
ok=Check(&err_msg);
break;

View File

@ -2,7 +2,7 @@
//
// Rivendell database management utility
//
// (C) Copyright 2018-2022 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2018-2025 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
@ -27,15 +27,28 @@
#include <rdfeed.h>
#include <rdstation.h>
//
// Defining this enables an '--analyze' switch, which will execute the usual
// startup, then call the 'MainObject::Analyze()' method, located in
// 'analyze.cpp'.
//
//#define RDDBMGR_ENABLE_ANALYZE
#define RDDBMGR_USAGE "[options]\n"
class MainObject : public QObject
{
public:
enum Command {NoCommand=0,ModifyCommand=1,CreateCommand=2,CheckCommand=3};
enum Command {NoCommand=0,ModifyCommand=1,CreateCommand=2,CheckCommand=3,
AnalyzeCommand=4};
MainObject(QObject *parent=0);
private:
//
// analyze.cpp
//
bool Analyze(int schema,QString *err_msg) const;
//
// check.cpp
//
@ -63,6 +76,10 @@ class MainObject : public QObject
void CheckOrphanedCarts() const;
void CheckOrphanedCuts() const;
void CheckOrphanedAudio() const;
void CheckOrphanedTables() const;
bool CheckTableNames(const QStringList &table_names,
QStringList &missing,QStringList &extra) const;
QStringList GetCanonicalTables(int schema) const;
void CheckLogLineIds(const QString &logname) const;
void ValidateAudioLengths() const;
void Rehash(const QString &arg) const;
@ -156,6 +173,7 @@ class MainObject : public QObject
bool db_check_orphaned_tracks;
bool db_check_orphaned_carts;
bool db_check_orphaned_cuts;
bool db_check_orphaned_tables;
bool db_check_strings;
bool db_check_log_line_ids;
QString db_orphan_group_name;
@ -165,6 +183,7 @@ class MainObject : public QObject
bool db_relink_audio_move;
QDateTime db_start_datetime;
QString db_table_create_postfix;
int db_current_schema;
RDConfig *db_config;
};