mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-10-31 22:24:02 +01:00 
			
		
		
		
	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:
		| @@ -22571,3 +22571,5 @@ | ||||
| 2021-10-28 Fred Gleason <fredg@paravelsystems.com> | ||||
| 	* Moved the 'Daylight Saving Time Considerations' section in the | ||||
| 	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). | ||||
|   | ||||
| @@ -166,6 +166,18 @@ | ||||
|     <option>--check</option>: | ||||
|   </para> | ||||
|   <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> | ||||
|       <term> | ||||
| 	<option>--dump-cuts-dir=</option><replaceable>dir-name</replaceable> | ||||
|   | ||||
| @@ -135,6 +135,15 @@ bool MainObject::Check(QString *err_msg) | ||||
|     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 | ||||
|   // | ||||
| @@ -1161,3 +1170,110 @@ void MainObject::CheckSchedCodeRules(bool prompt_user) const | ||||
|   } | ||||
|   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); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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_strings=false; | ||||
|  | ||||
|   // | ||||
|   // Check that we're 'root' | ||||
| @@ -230,6 +231,11 @@ MainObject::MainObject(QObject *parent) | ||||
|       db_check_orphaned_tracks=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)) { | ||||
|       fprintf(stderr,"rddbmgr: unrecognized option \"%s\"\n", | ||||
|   | ||||
| @@ -71,6 +71,12 @@ class MainObject : public QObject | ||||
|   void RemoveCart(unsigned cartnum); | ||||
|   bool CopyToAudioStore(const QString &destfile,const QString &srcfile) 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; | ||||
|  | ||||
|   // | ||||
| @@ -148,6 +154,7 @@ class MainObject : public QObject | ||||
|   bool db_check_orphaned_tracks; | ||||
|   bool db_check_orphaned_carts; | ||||
|   bool db_check_orphaned_cuts; | ||||
|   bool db_check_strings; | ||||
|   QString db_orphan_group_name; | ||||
|   QString db_dump_cuts_dir; | ||||
|   QString db_rehash; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user