2021-11-24 Fred Gleason <fredg@paravelsystems.com>

* Added a '--check-strings' switch to rddbmgr(8).

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason
2021-11-24 08:35:36 -05:00
parent 9231829495
commit eb2ec404a1
5 changed files with 143 additions and 0 deletions

View File

@@ -22571,3 +22571,5 @@
2021-10-28 Fred Gleason <fredg@paravelsystems.com> 2021-10-28 Fred Gleason <fredg@paravelsystems.com>
* Moved the 'Daylight Saving Time Considerations' section in the * Moved the 'Daylight Saving Time Considerations' section in the
Operations Guide to after the 'The RDCatch Main Window' section. Operations Guide to after the 'The RDCatch Main Window' section.
2021-11-24 Fred Gleason <fredg@paravelsystems.com>
* Added a '--check-strings' switch to rddbmgr(8).

View File

@@ -166,6 +166,18 @@
<option>--check</option>: <option>--check</option>:
</para> </para>
<variablelist remap='TP'> <variablelist remap='TP'>
<varlistentry>
<term>
<option>--check-strings</option>
</term>
<listitem>
<para>
Check all database fields of type VARCHAR for null characters and
then exit.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>--dump-cuts-dir=</option><replaceable>dir-name</replaceable> <option>--dump-cuts-dir=</option><replaceable>dir-name</replaceable>

View File

@@ -135,6 +135,15 @@ bool MainObject::Check(QString *err_msg)
printf("done.\n\n"); printf("done.\n\n");
} }
//
// Validate Strings
//
if(db_check_all||db_check_strings) {
printf("Validating character strings (this may take some time)...\n");
ValidateDbStrings();
printf("done.\n\n");
}
// //
// Rehash // Rehash
// //
@@ -1161,3 +1170,110 @@ void MainObject::CheckSchedCodeRules(bool prompt_user) const
} }
delete clock_q; delete clock_q;
} }
void MainObject::ValidateDbStrings() const
{
QString sql;
RDSqlQuery *q;
sql="show tables";
q=new RDSqlQuery(sql);
while(q->next()) {
ValidateTableStrings(q->value(0).toString());
}
delete q;
}
void MainObject::ValidateTableStrings(const QString &tbl_name) const
{
QString sql;
RDSqlQuery *q;
QString pri_col;
QString pri_type;
sql=QString("describe ")+"`"+tbl_name+"`";
q=new RDSqlQuery(sql);
while(q->next()) {
if(q->value(3).toString()=="PRI") {
pri_col=q->value(0).toString();
pri_type=q->value(1).toString();
}
if(q->value(1).toString().left(8)=="varchar(") {
ValidateFieldString(pri_col,pri_type,tbl_name,q->value(0).toString());
}
}
delete q;
}
void MainObject::ValidateFieldString(const QString &pri_col,
const QString &pri_type,
const QString &tbl_name,
const QString &col_name) const
{
QString sql;
RDSqlQuery *q;
sql=QString("select `")+col_name+"` from `"+tbl_name+"` where "+
"`"+col_name+"` like '%\\0'";
q=new RDSqlQuery(sql);
while(q->next()) {
FixFieldString(pri_col,pri_type,tbl_name,col_name);
}
delete q;
}
void MainObject::FixFieldString(const QString &pri_col,const QString &pri_type,
const QString &tbl_name,
const QString &col_name) const
{
QString sql;
RDSqlQuery *q;
if(pri_col==col_name) {
printf(" Field `%s`.`%s` contains invalid characters but is also primary key, unable to fix!\n",
tbl_name.toUtf8().constData(),
col_name.toUtf8().constData());
return;
}
if(pri_col.isEmpty()||pri_type.isEmpty()) {
printf(" Field `%s`.`%s` contains invalid characters but no primary key found, unable to fix!\n",
tbl_name.toUtf8().constData(),
col_name.toUtf8().constData());
return;
}
printf(" Field `%s`.`%s` contains invalid characters. Fix? (y/N) ",
tbl_name.toUtf8().constData(),
col_name.toUtf8().constData());
fflush(NULL);
if(UserResponse()) {
sql=QString("select ")+
"`"+pri_col+"`,"+ // 00
"`"+col_name+"` "+ // 01
"from `"+tbl_name+"` where "+
"`"+col_name+"` like '%\\0'";
q=new RDSqlQuery(sql);
while(q->next()) {
sql=QString("update `")+tbl_name+"` set "+
"`"+col_name+"`='"+RDEscapeString(q->value(1).toByteArray())+"' ";
if(pri_type.left(3)=="int") {
sql+="where `"+pri_col+QString::asprintf("`=%d",q->value(0).toInt());
}
else {
if(pri_type.left(7)=="varchar") {
sql+="where `"+pri_col+"`='"+
RDEscapeString(q->value(0).toString())+"'";
}
else {
printf(" Unknown primary key type \"%s\", skipping...\n",
pri_type.toUtf8().constData());
return;
}
}
RDSqlQuery::apply(sql);
}
}
}

View File

@@ -58,6 +58,7 @@ MainObject::MainObject(QObject *parent)
db_check_orphaned_carts=false; db_check_orphaned_carts=false;
db_check_orphaned_cuts=false; db_check_orphaned_cuts=false;
db_check_orphaned_tracks=false; db_check_orphaned_tracks=false;
db_check_strings=false;
// //
// Check that we're 'root' // Check that we're 'root'
@@ -230,6 +231,11 @@ MainObject::MainObject(QObject *parent)
db_check_orphaned_tracks=true; db_check_orphaned_tracks=true;
cmd->setProcessed(i,true); cmd->setProcessed(i,true);
} }
if(cmd->key(i)=="--check-strings") {
db_check_all=false;
db_check_strings=true;
cmd->setProcessed(i,true);
}
if(!cmd->processed(i)) { if(!cmd->processed(i)) {
fprintf(stderr,"rddbmgr: unrecognized option \"%s\"\n", fprintf(stderr,"rddbmgr: unrecognized option \"%s\"\n",

View File

@@ -71,6 +71,12 @@ class MainObject : public QObject
void RemoveCart(unsigned cartnum); void RemoveCart(unsigned cartnum);
bool CopyToAudioStore(const QString &destfile,const QString &srcfile) const; bool CopyToAudioStore(const QString &destfile,const QString &srcfile) const;
void CheckSchedCodeRules(bool prompt_user) const; void CheckSchedCodeRules(bool prompt_user) const;
void ValidateDbStrings() const;
void ValidateTableStrings(const QString &tbl_name) const;
void ValidateFieldString(const QString &pri_col,const QString &pri_type,
const QString &tbl_name,const QString &col_name) const;
void FixFieldString(const QString &pri_col,const QString &pri_type,
const QString &tbl_name,const QString &col_name) const;
bool UserResponse() const; bool UserResponse() const;
// //
@@ -148,6 +154,7 @@ class MainObject : public QObject
bool db_check_orphaned_tracks; bool db_check_orphaned_tracks;
bool db_check_orphaned_carts; bool db_check_orphaned_carts;
bool db_check_orphaned_cuts; bool db_check_orphaned_cuts;
bool db_check_strings;
QString db_orphan_group_name; QString db_orphan_group_name;
QString db_dump_cuts_dir; QString db_dump_cuts_dir;
QString db_rehash; QString db_rehash;