Modificata la gestione degli "status" dei nodi: prima metteva sempre nodo modificato
anche quando in realtà non modificava nulla. Modificata di conseguenza anche la funzione per la rimozione dei nodi che si basava sugli "status". git-svn-id: svn://10.65.10.50/trunk@5979 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
c497f91f9f
commit
f1c8e53279
@ -12,8 +12,8 @@ void test_analisi()
|
|||||||
anas.put(ABAN_CODAN,"A1");
|
anas.put(ABAN_CODAN,"A1");
|
||||||
anas.read();
|
anas.read();
|
||||||
// readat -> vedi dopo
|
// readat -> vedi dopo
|
||||||
anas.remove(); //Solo per il test della delete_node o la rimozione di una intera tabella
|
//anas.remove(); //Solo per il test della delete_node o la rimozione di una intera tabella
|
||||||
//anas.write();
|
anas.write();
|
||||||
|
|
||||||
|
|
||||||
/*Questa parte della funzione serve solo per testare la readat
|
/*Questa parte della funzione serve solo per testare la readat
|
||||||
|
152
ab/ablib01.cpp
152
ab/ablib01.cpp
@ -1,10 +1,4 @@
|
|||||||
#include "ablib01.h"
|
#include "ablib01.h"
|
||||||
|
|
||||||
#define MAX_ID_REL 999999999
|
|
||||||
#define NODO_AGGIUNTO "A"
|
|
||||||
#define NODO_MODIFICATO "M"
|
|
||||||
#define NODO_RIMOSSO "R"
|
|
||||||
|
|
||||||
/**************************************************************************************************/
|
/**************************************************************************************************/
|
||||||
// TAlbero_AB
|
// TAlbero_AB
|
||||||
/**************************************************************************************************/
|
/**************************************************************************************************/
|
||||||
@ -63,11 +57,11 @@ int TAlbero_AB::readat(TBaseisamfile& analisi, TRecnotype nrec, word lockop)
|
|||||||
|
|
||||||
int TAlbero_AB::remove(TBaseisamfile& f) const
|
int TAlbero_AB::remove(TBaseisamfile& f) const
|
||||||
{
|
{
|
||||||
//*Abilitare questa parte solo per effettuare un debug della delete_node
|
/*Abilitare questa parte solo per effettuare un debug della delete_node
|
||||||
// anche se messa in questa posizione, la chiamata non ha senso
|
// anche se messa in questa posizione, la chiamata non ha senso
|
||||||
// TLocalisamfile lf(LF_RELANA);
|
// TLocalisamfile lf(LF_RELANA);
|
||||||
TNumeric_id id;
|
TNumeric_id id;
|
||||||
id = 17;
|
id = 4;
|
||||||
_inter_tree->delete_node(id);
|
_inter_tree->delete_node(id);
|
||||||
int errc = commit_body();
|
int errc = commit_body();
|
||||||
if (errc != NOERR)
|
if (errc != NOERR)
|
||||||
@ -76,10 +70,10 @@ int TAlbero_AB::remove(TBaseisamfile& f) const
|
|||||||
//return errc;
|
//return errc;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*Abilitare solo questa parte per il test della remove_tree
|
//*Abilitare solo questa parte per il test della remove_tree
|
||||||
_inter_tree->delete_tree();
|
_inter_tree->delete_tree();
|
||||||
int errc = commit_body();
|
int errc = commit_body();
|
||||||
if (errc != NOERR)
|
if (errc != NOERR)
|
||||||
@ -88,7 +82,7 @@ int TAlbero_AB::remove(TBaseisamfile& f) const
|
|||||||
//return errc;
|
//return errc;
|
||||||
}
|
}
|
||||||
int err = TRectype::remove(f);
|
int err = TRectype::remove(f);
|
||||||
return err; */
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAlbero_AB::zero()
|
void TAlbero_AB::zero()
|
||||||
@ -129,65 +123,9 @@ void TABsaldo::put_headkey(TRectype &rec) const
|
|||||||
rec.put(ABMD_CODCBL, get(ABS_CODCBL));
|
rec.put(ABMD_CODCBL, get(ABS_CODCBL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int TABsaldo::commit_body() const
|
|
||||||
{
|
|
||||||
_inter_tree->write_cache();
|
|
||||||
TRectype rec(_inter_tree->current().num());
|
|
||||||
TLocalisamfile filebody(rec.num());
|
|
||||||
TString status;
|
|
||||||
//Estraggo un nodo per volta basandomi sull'assoc_array degli status
|
|
||||||
while (_inter_tree->dirty_nodes() > 0)
|
|
||||||
{
|
|
||||||
TNumeric_id id;
|
|
||||||
//int prova = _inter_tree->dirty_nodes(); //solo debug
|
|
||||||
|
|
||||||
id=ID_NULLO;
|
|
||||||
rec= _inter_tree->extract_dirtynode(id, status);
|
|
||||||
put_headkey(rec);
|
|
||||||
|
|
||||||
//Ho un rectype e uno status node
|
|
||||||
if (status == NODO_AGGIUNTO)
|
|
||||||
{
|
|
||||||
if (filebody.curr().empty())
|
|
||||||
{ //Se il cursor di relana è posizionato in modo errato:
|
|
||||||
//lo sistemo sull'ultimo record del file
|
|
||||||
//DOMANDA: - Perchè ???
|
|
||||||
//TENATATIVO DI RISPOSTA: - Quando l'ultima azione effettuata (prima di questa "aggiunta") è la rimozione
|
|
||||||
// dell'ultimo record probabilmente (ma non sono sicuro) il cursore non è posizionato (o forse
|
|
||||||
// è posizionato in modo errato come ad es. dopo l'EOF, visto che l'EOF era sull'ultimo record rimosso)
|
|
||||||
// e quando eseguo un tentativo di scrittura da un errore di chiave duplicata (anche se questa non esiste);
|
|
||||||
// In tutti gli altri casi (quando l'ultima azione è stata una write o una rewrite o una remove di un record
|
|
||||||
// che non sia l'ultimo) questo problema non esiste.
|
|
||||||
//RISPOSTA ESATTA: - Bho !!!
|
|
||||||
filebody.last();
|
|
||||||
}
|
|
||||||
int err = filebody.write(rec);
|
|
||||||
if (err != NOERR)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
if (status == NODO_MODIFICATO)
|
|
||||||
{
|
|
||||||
int err = filebody.rewrite(rec);
|
|
||||||
if (err != NOERR)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
if (status == NODO_RIMOSSO)
|
|
||||||
{
|
|
||||||
filebody.read(rec); //Devo leggere sul file per posizionare il cursore: stesso motivo di prima
|
|
||||||
int err = filebody.remove(rec);
|
|
||||||
if (err != NOERR)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
// In tutti gli altri casi il nodo non viene modificato
|
|
||||||
}
|
|
||||||
return NOERR;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//Leggo il "corpo" del record
|
//Leggo il "corpo" del record
|
||||||
int TABsaldo::read_body(bool lockstruct)
|
int TABsaldo::read_body(bool lockstruct)
|
||||||
{
|
{
|
||||||
//_ana = new TAlbero_relana(get(ABAN_CODAN));
|
|
||||||
TString codditta = get(ABS_CODDITTA);
|
TString codditta = get(ABS_CODDITTA);
|
||||||
TToken_string key = codditta.right_just(5,'0');
|
TToken_string key = codditta.right_just(5,'0');
|
||||||
key.add(get(ABS_ANNO));
|
key.add(get(ABS_ANNO));
|
||||||
@ -198,11 +136,9 @@ int TABsaldo::read_body(bool lockstruct)
|
|||||||
|
|
||||||
if (_mov->goto_root())
|
if (_mov->goto_root())
|
||||||
{
|
{
|
||||||
//TNumeric_id id_movdett;
|
|
||||||
//id_movdett = _mov->curr().get_real(ABMD_ID);
|
|
||||||
naviga_movdett();
|
naviga_movdett();
|
||||||
}
|
}
|
||||||
//_inter_tree->write_cache(); //solo per debug
|
// _inter_tree->write_cache(); //solo per debug
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +153,7 @@ void TABsaldo::naviga_movdett()
|
|||||||
pather_id = _mov->curr().get_real(ABMD_IDPADRE);
|
pather_id = _mov->curr().get_real(ABMD_IDPADRE);
|
||||||
lbrother_id = _mov->curr().get_real(ABMD_IDPREC);
|
lbrother_id = _mov->curr().get_real(ABMD_IDPREC);
|
||||||
*_newrec = _mov->curr();
|
*_newrec = _mov->curr();
|
||||||
_inter_tree->insert_node(*_newrec,lbrother_id,pather_id,my_id);
|
_inter_tree->insert_node(*_newrec,lbrother_id,pather_id,my_id,TRASFERITO);
|
||||||
|
|
||||||
if (_mov->has_rbrother())
|
if (_mov->has_rbrother())
|
||||||
{
|
{
|
||||||
@ -282,7 +218,7 @@ int TAlbero_AB::commit_body() const
|
|||||||
while (_inter_tree->dirty_nodes() > 0)
|
while (_inter_tree->dirty_nodes() > 0)
|
||||||
{
|
{
|
||||||
TNumeric_id id;
|
TNumeric_id id;
|
||||||
// int prova = _inter_tree->dirty_nodes(); solo debug
|
// int prova = _inter_tree->dirty_nodes(); //solo debug
|
||||||
|
|
||||||
id=ID_NULLO;
|
id=ID_NULLO;
|
||||||
rec= _inter_tree->extract_dirtynode(id, status);
|
rec= _inter_tree->extract_dirtynode(id, status);
|
||||||
@ -366,7 +302,7 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
|
|||||||
_relaz->curr_id(key_rel);
|
_relaz->curr_id(key_rel);
|
||||||
_newrec = sincronizza_relana(begin_relana, id_relana);
|
_newrec = sincronizza_relana(begin_relana, id_relana);
|
||||||
currid=_newrec->get_real(ABRA_ID);
|
currid=_newrec->get_real(ABRA_ID);
|
||||||
_inter_tree->insert_node(*_newrec,id_prec,id_padre,currid);
|
_inter_tree->insert_node(*_newrec,id_prec,id_padre,currid,TRASFERITO);
|
||||||
|
|
||||||
//Controllo se c'è un fratello di rel_voci
|
//Controllo se c'è un fratello di rel_voci
|
||||||
if (_relaz->has_rbrother())
|
if (_relaz->has_rbrother())
|
||||||
@ -377,7 +313,6 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
|
|||||||
//fra relvoci e relana
|
//fra relvoci e relana
|
||||||
TNumeric_id frat_relana;
|
TNumeric_id frat_relana;
|
||||||
naviga_relazioni(frat_relana,currid , id_padre);
|
naviga_relazioni(frat_relana,currid , id_padre);
|
||||||
//_ana->goto_node(key_ana); //Per risalire al nodo che mi ha chiamato in relana
|
|
||||||
_relaz->goto_node(key_rel);
|
_relaz->goto_node(key_rel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -396,7 +331,6 @@ void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNum
|
|||||||
id_relana=_ana->curr().get_real(ABRA_ID);
|
id_relana=_ana->curr().get_real(ABRA_ID);
|
||||||
}
|
}
|
||||||
naviga_relazioni(id_relana, ID_NULLO , currid);
|
naviga_relazioni(id_relana, ID_NULLO , currid);
|
||||||
//_ana->goto_node(key_ana); //Per risalire al nodo che mi ha chiamato in relana
|
|
||||||
}//Se non trovo il figlio di una relazione, potrebbe essere una foglia di un ramo dell'albero
|
}//Se non trovo il figlio di una relazione, potrebbe essere una foglia di un ramo dell'albero
|
||||||
_relaz->goto_node(key_rel); //Per risalire al nodo che mi ha chiamato in relvoci
|
_relaz->goto_node(key_rel); //Per risalire al nodo che mi ha chiamato in relvoci
|
||||||
}
|
}
|
||||||
@ -649,9 +583,9 @@ TNumeric_id &TAlbero_locale::new_id(TNumeric_id id)
|
|||||||
|
|
||||||
//Inserisce il nodo (che ho in ingresso) nella struttura ad albero doppiamente linkata
|
//Inserisce il nodo (che ho in ingresso) nella struttura ad albero doppiamente linkata
|
||||||
//di relana aggiornando tutti i link
|
//di relana aggiornando tutti i link
|
||||||
bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id)
|
bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char flag_it)
|
||||||
{
|
{
|
||||||
const int dirty_value=NODO_MODIFICATO;
|
const char* dirty_value=NODO_MODIFICATO;
|
||||||
TNumeric_id id_succ;
|
TNumeric_id id_succ;
|
||||||
TToken_string key;
|
TToken_string key;
|
||||||
key=get_headkey();
|
key=get_headkey();
|
||||||
@ -665,9 +599,12 @@ bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, cons
|
|||||||
{ //Aggiorno il successivo del mio precedente dicendogli che il suo successivo sono io
|
{ //Aggiorno il successivo del mio precedente dicendogli che il suo successivo sono io
|
||||||
key.add(id_prec.string());
|
key.add(id_prec.string());
|
||||||
parente = _local_cache->get(key);
|
parente = _local_cache->get(key);
|
||||||
parente.put(idsucc_fieldname(),id.string());
|
if (parente.get_real(idsucc_fieldname()) != id)
|
||||||
_local_cache->put(parente);
|
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
|
||||||
set_status_node(id_prec,dirty_value); //Setto l'eventuale flag di array modificato per il fratello
|
parente.put(idsucc_fieldname(),id.string());
|
||||||
|
_local_cache->put(parente);
|
||||||
|
set_status_node(id_prec,dirty_value); //Setto l'eventuale flag di array modificato per il fratello
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //Se non ho il mio precedente, allora o sono una radice principale o divento il primo figlio:
|
{ //Se non ho il mio precedente, allora o sono una radice principale o divento il primo figlio:
|
||||||
@ -675,23 +612,33 @@ bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, cons
|
|||||||
{ //Sono un primo figlio: rintraccio mio padre e gli dico che il suo primo figlio ora, sono io
|
{ //Sono un primo figlio: rintraccio mio padre e gli dico che il suo primo figlio ora, sono io
|
||||||
key.add(id_padre.string());
|
key.add(id_padre.string());
|
||||||
parente = _local_cache->get(key);
|
parente = _local_cache->get(key);
|
||||||
parente.put(idson_fieldname(),id.string());
|
if(parente.get_real(idson_fieldname()) != id)
|
||||||
_local_cache->put(parente);
|
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
|
||||||
set_status_node(id_padre,dirty_value); //Setto l'eventuale flag di array modificato per il padre
|
parente.put(idson_fieldname(),id.string());
|
||||||
|
_local_cache->put(parente);
|
||||||
|
set_status_node(id_padre,dirty_value); //Setto l'eventuale flag di array modificato per il padre
|
||||||
|
}
|
||||||
} // Sono una radice principale e quindi sono orfana di padre
|
} // Sono una radice principale e quindi sono orfana di padre
|
||||||
}
|
}
|
||||||
|
|
||||||
//Ora aggiorno me stesso
|
//Ora aggiorno me stesso
|
||||||
put_headkey(node);
|
put_headkey(node);
|
||||||
// node.put(ABRA_CODAN,get_headkey()); //Eseguo un combio della chiave: non serve avere il codice della tabella nella cache
|
if ((node.get_real(idprec_fieldname()) != id_prec) ||
|
||||||
node.put(idprec_fieldname(),id_prec.string());
|
(node.get_real(idfather_fieldname()) != id_padre))
|
||||||
node.put(idfather_fieldname(),id_padre.string());
|
{// Il nodo è effettivamente modificato: apporto le modifiche e setto lo status
|
||||||
node.put(idsucc_fieldname(),id_succ.string());
|
node.put(idprec_fieldname(),id_prec.string());
|
||||||
node.put(idson_fieldname(),ID_NULLO);
|
node.put(idfather_fieldname(),id_padre.string());
|
||||||
|
set_status_node(id,dirty_value);
|
||||||
|
}
|
||||||
|
if (flag_it == IMMESSO)
|
||||||
|
{
|
||||||
|
node.put(idsucc_fieldname(),id_succ.string());
|
||||||
|
node.put(idson_fieldname(),ID_NULLO);
|
||||||
|
//set_current(node);
|
||||||
|
}
|
||||||
|
|
||||||
_local_cache->put(node);
|
_local_cache->put(node);
|
||||||
//set_current(node);
|
|
||||||
goto_node(node);
|
goto_node(node);
|
||||||
set_status_node(id,dirty_value);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +668,8 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
|
|||||||
parente=_local_cache->get(key); //padre
|
parente=_local_cache->get(key); //padre
|
||||||
if (parente.get(idson_fieldname()) == id.string())
|
if (parente.get(idson_fieldname()) == id.string())
|
||||||
{ //Il nodo che sta per essere rimosso è il primo figlio di un padre
|
{ //Il nodo che sta per essere rimosso è il primo figlio di un padre
|
||||||
parente.put(idson_fieldname(),id_succ.string()); //Aggiorno il padre
|
parente.put(idson_fieldname(),id_succ.string()); //Aggiorno il padre
|
||||||
|
set_status_node(id_padre, NODO_MODIFICATO); //Aggiorno lo status
|
||||||
_local_cache->put(parente);
|
_local_cache->put(parente);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,6 +683,7 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
|
|||||||
key.add(id_prec.string());
|
key.add(id_prec.string());
|
||||||
parente=_local_cache->get(key); //fratello sinistro
|
parente=_local_cache->get(key); //fratello sinistro
|
||||||
parente.put(idsucc_fieldname(),id_succ.string()); //Assegno al mio fratello sinistro il mio fratello destro
|
parente.put(idsucc_fieldname(),id_succ.string()); //Assegno al mio fratello sinistro il mio fratello destro
|
||||||
|
set_status_node(id_prec,NODO_MODIFICATO); //Aggiorno lo status
|
||||||
_local_cache->put(parente);
|
_local_cache->put(parente);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,6 +696,7 @@ bool TAlbero_locale::delete_node(const TNumeric_id &id)
|
|||||||
key.add(id_succ.string());
|
key.add(id_succ.string());
|
||||||
parente=_local_cache->get(key); //fratello destro
|
parente=_local_cache->get(key); //fratello destro
|
||||||
parente.put(idprec_fieldname(),id_prec.string()); //Assegno al mio fratello destro il mio fratello sinistro
|
parente.put(idprec_fieldname(),id_prec.string()); //Assegno al mio fratello destro il mio fratello sinistro
|
||||||
|
set_status_node(id_succ,NODO_MODIFICATO); //Aggiorno lo status
|
||||||
_local_cache->put(parente);
|
_local_cache->put(parente);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,23 +781,15 @@ bool TAlbero_locale::remove_subtree(const TNumeric_id return_id)
|
|||||||
//in modo tale da mantenerlo allineato con il contenuto della cache
|
//in modo tale da mantenerlo allineato con il contenuto della cache
|
||||||
TString *status;
|
TString *status;
|
||||||
status = (TString*)_status_node.objptr(id.string());
|
status = (TString*)_status_node.objptr(id.string());
|
||||||
if (status != ID_NULLO)
|
if ((status == NULL) || (*status != NODO_AGGIUNTO))
|
||||||
{//Se esiste uno stato per questo nodo
|
{//In questi due casi il nodo esisteva già nel file originario
|
||||||
if ((*status == NODO_MODIFICATO) || (*status == NODO_RIMOSSO))
|
_status_node.add(id.string(),(TString)NODO_RIMOSSO,TRUE); //Forzo la sovrascrittura in ogni caso
|
||||||
{//In questi due casi il nodo esisteva già nel file originario
|
|
||||||
_status_node.add(id.string(),(TString)NODO_RIMOSSO,TRUE); //Forzo la sovrascrittura in ogni caso
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//Nel caso di NODO_AGGIUNTO
|
|
||||||
_status_node.remove(id.string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{//Nel caso di NODO_AGGIUNTO
|
||||||
//Questo caso non dovrebbe verificarsi poichè un nodo per cui
|
_status_node.remove(id.string());
|
||||||
//non è previsto uno status, non dovrebbe esistere nella cache
|
|
||||||
CHECK (FALSE,"Errore nella consistenza della cache");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (return_id != ID_NULLO)
|
if (return_id != ID_NULLO)
|
||||||
goto_node(return_id);
|
goto_node(return_id);
|
||||||
else
|
else
|
||||||
|
11
ab/ablib01.h
11
ab/ablib01.h
@ -31,6 +31,13 @@
|
|||||||
|
|
||||||
#include "saldi.h"
|
#include "saldi.h"
|
||||||
#include "movdett.h"
|
#include "movdett.h"
|
||||||
|
#define MAX_ID_REL 999999999
|
||||||
|
#define NODO_AGGIUNTO "A"
|
||||||
|
#define NODO_MODIFICATO "M"
|
||||||
|
#define NODO_RIMOSSO "R"
|
||||||
|
#define IMMESSO 'I'
|
||||||
|
#define TRASFERITO 'T'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -294,8 +301,8 @@ class TAlbero_locale : public TAlbero_bidir
|
|||||||
// debug
|
// debug
|
||||||
void write_cache() { _local_cache->flush(); }
|
void write_cache() { _local_cache->flush(); }
|
||||||
|
|
||||||
// @cmember Inserisce un nodo in una struttura di tipo lista doppiamente lincata
|
// @cmember Inserisce un nodo in una struttura di tipo lista doppiamente lincata: trasf_immes è un flag che dice se il nodo è trasferito o immesso
|
||||||
bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id);
|
bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id, const char trasf_immes);
|
||||||
// @cmember Elimina un nodo da una struttura di tipo lista doppiamente lincata
|
// @cmember Elimina un nodo da una struttura di tipo lista doppiamente lincata
|
||||||
bool delete_node(const TNumeric_id &id);
|
bool delete_node(const TNumeric_id &id);
|
||||||
// @cmember Lancia la rimozione di tutto l'albero
|
// @cmember Lancia la rimozione di tutto l'albero
|
||||||
|
Loading…
x
Reference in New Issue
Block a user