182 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "resetfil.h"
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TResetfile
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| TResetfile::TResetfile(int logicnum, bool remove)
 | |
|              : _file_num(logicnum), _removerec(remove),
 | |
|              	 _validate_record_function(NULL),
 | |
|              	 _validate_field_function(NULL),
 | |
|              	 _before_reset_function(NULL), 
 | |
|              	 _after_reset_function(NULL),
 | |
|              	 _is_reseted(FALSE)	
 | |
| {
 | |
| 	// oggetto file da azzerare
 | |
| 	_file = new TSystemisamfile(_file_num);
 | |
| }
 | |
| 
 | |
| TResetfile::~TResetfile()
 | |
| {                        
 | |
| 	// pack file se richiesto rimozione record 
 | |
| 	// e file azzerato
 | |
| 	if(_removerec && _is_reseted)
 | |
| 		_file->pack();
 | |
| 		
 | |
| 	delete _file;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| // @mfunc ritorna se il campo <p fd> è un campo chiave
 | |
| bool TResetfile::iskeyfield(const RecDes& recd, const int fd) const
 | |
| {
 | |
| 	// inizializzo risultato da restituire
 | |
| 	bool found = FALSE;
 | |
| 	
 | |
| 	// loop di scansione delle chiavi del file
 | |
| 	for (int i = 0; i < recd.NKeys && !found; i++)
 | |
|   {
 | |
|   	
 | |
|   	// Elenco dei campi della chiave
 | |
|   	const KeyDes& keyd = recd.Ky[i]; 
 | |
|     
 | |
|     // loop di scansione dei campi della chiave
 | |
|     for (int j = 0; j < keyd.NkFields && !found; j++) 
 | |
|     	if (fd == keyd.FieldSeq[j] % MaxFields)
 | |
|     		found = TRUE;
 | |
|   } 		                  
 | |
|   
 | |
|   return found;
 | |
| }                                                            
 | |
| 
 | |
| // @doc INTERNAL
 | |
| // @mfunc carica l'array <p resetable_fields> con i campi da azzerare
 | |
| // @rfunc ritorna il numero di campi caricati
 | |
| int TResetfile::load_resetable_fields(const RecDes& recd,
 | |
| 																			TString_array& resetable_fields)
 | |
| {
 | |
| 	// inizializzo numero campi da restituire
 | |
| 	int numfld = 0;
 | |
| 	
 | |
|   for (int i = 0; i < recd.NFields; i++) 
 | |
|   {                        
 | |
|       // non azzero i campi chiave
 | |
|       if (iskeyfield(recd, i))
 | |
|       	continue;                      
 | |
|       	
 | |
|       // Descrittore campo
 | |
|       RecFieldDes& fieldd	= recd.Fd[i];
 | |
|       
 | |
|       // non azzero i campi indefiniti
 | |
|       if (fieldd.TypeF == _nullfld)		
 | |
|       	continue;
 | |
|        
 | |
|       // aggiungo campo da azzerare all'array
 | |
|       resetable_fields.add(fieldd.Name,numfld++);
 | |
| 	}
 | |
|   
 | |
|   return numfld;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| // @mfunc esegue l'azzeramento del file
 | |
| // @rfunc ritorna il codice errore relativo ad operazioni sul file
 | |
| int TResetfile::run()
 | |
| {	
 | |
| 	// codice errore
 | |
| 	int err;               
 | |
| 	
 | |
| 	// numero campi da azzerare 
 | |
| 	int num_resetable_fields;
 | |
| 	
 | |
| 	// Apertura file con bloccaggio
 | |
| 	err = _file->open(_excllock); 
 | |
| 	if (err != NOERR)
 | |
| 		return err;
 | |
| 	
 | |
| 	// riferimento a record corrente
 | |
| 	TRectype& rec = _file->curr();            
 | |
| 	
 | |
| 	// Descrittore record 
 | |
| 	const RecDes* recd = rec.rec_des();
 | |
| 	
 | |
| 	// array dei campi da azzerare
 | |
| 	TString_array resetable_fields(recd->NFields);
 | |
| 	
 | |
| 	// riempimento array dei campi da azzerare
 | |
| 	if (!_removerec)
 | |
| 		num_resetable_fields = load_resetable_fields(*recd, resetable_fields);
 | |
| 
 | |
| 	// reperimento nome file file
 | |
| 	const char* desfile = _file->description();
 | |
| 	
 | |
| 	// composizione testo per indicatore progressivo
 | |
| 	TString testo;
 | |
| 	testo.format("Azzeramento %s", desfile);
 | |
| 	
 | |
| 	// inizializzazione indice massimo e parziale per indicatore progressivo
 | |
| 	const long pmax = _file->items();
 | |
| 	long pi = 0L;
 | |
| 		
 | |
| 	// istanza indicatore progressivo per avanzamento azzeramento
 | |
| 	TProgind p(pmax, testo, FALSE, TRUE);
 | |
| 	
 | |
| 	// loop di scansione file da azzerare
 | |
| 	for (err = _file->first(); err == NOERR; err = _file->next()) 
 | |
| 	{                                  
 | |
| 	  // incremento indicatore progressivo
 | |
| 	  p.addstatus(1);
 | |
| 	  pi++;
 | |
| 	  
 | |
| 	  // richiamo handler VALIDATE_RECORD 
 | |
| 		if (_validate_record_function)
 | |
|   		if (!_validate_record_function(rec))
 | |
|   			continue;
 | |
|   		
 | |
| 		// richiamo handler BEFORE_RESET 
 | |
| 		if (_before_reset_function)
 | |
|   		_before_reset_function(rec);
 | |
| 		
 | |
| 		// rimozione del record 
 | |
| 		if(_removerec)
 | |
| 			_file->remove();
 | |
| 		
 | |
| 		// azzeramento del record 
 | |
| 		else	
 | |
| 		{
 | |
| 			// loop di scansione campi da azzerare
 | |
| 			for (int i = 0; i < num_resetable_fields; i++) 
 | |
| 			{
 | |
| 				// richiamo handler VALIDATE_FIELD 
 | |
| 				if (_validate_field_function)
 | |
|   				if (!_validate_field_function(rec, resetable_fields.row(i)))
 | |
|   					continue;                      
 | |
|   				
 | |
| 				// azzeramento campi
 | |
| 				rec.zero(resetable_fields.row(i));
 | |
|     	}
 | |
|     }
 | |
|     
 | |
|     // richiamo handler AFTER_RESET 
 | |
| 		if (_after_reset_function)
 | |
|   		_after_reset_function(rec);
 | |
|   		
 | |
|   	// registrazione record
 | |
|   	if(!_removerec)
 | |
|   		_file->rewrite();
 | |
|   }
 | |
| 	
 | |
| 	// rabbocco indicatore progressivo
 | |
| 	p.addstatus(pmax-pi);
 | |
| 	
 | |
| 	// chiusura file
 | |
| 	_file->close();
 | |
| 	
 | |
| 	// file azzerato
 | |
| 	_is_reseted = TRUE;
 | |
| 	
 | |
| 	return err;
 | |
| }
 | |
| 
 |