/*
@(SH) Utility per la gestione dei file ISAM
-------------------------------------------------------------------------------
*/

#include				<ccommon.h>
#include				<genconst.h>
#include				<ccustio.h>
#include				<cfiles.h>
#include				<cbpltree.h>
#include				<cbplcre.h>
#include				<cisam.h>
#include				<memory.h>
#include				<progind.h>

/*
@(#) creorgfile  ISAM

@(ID)
Compatta il file dati eliminando fisicamente i record cancellati logicamente.
Ritorna il codice di errore.
@(FD)

@(ISV)
wisfd    = puntatore al descrittore del file.

rec      = buffer per contenere un record.

i        = contatore.

k        = contatore.

oldeod   = variabile che contiene il vecchio valore di End of Data.


junk     = variabile spazzatura per la chiamata di varie funzioni.

w        = finestra di visualizzazione.

s    = stringa messaggio.

- Versione DOS e XENIX
@(FSV)
*/

int	creorgfile(logicname,vis,err)
int						logicname; /* numero logico del file                           */
BOOLEAN				vis;       /* se true visualizza le operazioni che sta facendo */
int						*err;      /* codice errore                                    */

	{
		isfdptr		wisfd;
		RecType		rec;
		RecNoType	i = 0L,k = 0L,oldeod;
		int				junk;
		char			s[80];

		*err = NoErr;
		if (cisopen(&wisfd, logicname, &rec, ExclLock, err)) return(*err);
		oldeod = wisfd->d->EOD;
		if (vis && (oldeod > 0))
		{
			sprintf(s,"Compatta - %s", wisfd->d->Des);
			progind_create(wisfd->d->EOD, s, FALSE, TRUE, 10);
		}
		while (i < wisfd->d->EOD)
		{
			i++;
			CRead(&wisfd->f, rec, i, NoLock);
			if ((*err = wisfd->f.IOR)) break ;
			if (!IRecIsDeleted(rec))
			{
				k++;
				if (k < i) CWrite(&wisfd->f, rec, k, NoLock);
			}
			if (vis && (oldeod > 0) && (!(i % 10)))
				progind_set_status(i);
		}
		if (vis && (oldeod > 0))
			progind_set_status(i);
		if (!*err)
		{
			wisfd->d->EOD = k;
#ifndef DOS
			writelog(FNREORG, NULL, (RecType) &oldeod);
#endif
			junk  = cisupdflags(wisfd, &junk, TRUE);
		}
		junk = cisclose(&wisfd, &rec, &junk);
		if (vis && oldeod > 0)
			progind_destroy();
		return(*err);
	}

/*
@(#) creorgindex  ISAM

@(ID)
Ricostruisce l'indice di un file.
Ritorna il codice di errore.
@(FD)

@(ISV)
wisfd    = puntatore al descrittore del file.

rec      = buffer per contenere un record.

j        = contatore.

junk     = variabile spazzatura per la chiamata di varie funzioni.

w        = finestra di visualizzazione.

s    = stringa messaggio.
@(FSV)

@(IN)
Deve essere usata in coppia con la "creorgfile".
@(FN)
*/

int	creorgindex(logicname,vis,err)
int						logicname; /* numero logico del file                   */
BOOLEAN				vis;       /* se  true visualizza cio' che sta facendo */
int						*err;      /* codice errore                            */

	{
		isfdptr		wisfd;
		RecType		rec;
		int				junk, j;
		char			s[80];

		*err = NoErr;
		getisfd(&wisfd, logicname);
		CBInitFile(&wisfd->i);
		for (j = 1; j <= wisfd->r->NKeys;j++)
		{
			CBInitPath(j,CCalcLenKey(wisfd->r,j),wisfd->d->EOX,
								 wisfd->r->Ky[j-1].DupKeys,&(wisfd->i),err);
			if (*err)
			{
				relisfd(&wisfd);
				return (*err);
			}
		}
		junk = unlink(CGetIdxName(wisfd->d->SysName));
		CBCreate(&wisfd->i, CGetIdxName(wisfd->d->SysName),err);
		relisfd(&wisfd);
		if (*err) return (*err);
		if (cisopen(&wisfd, logicname, &rec, ExclLock, err)) return(*err);
		wisfd->RecNo = 0L;
		if (vis && (wisfd->d->EOD > 0))
		{
			sprintf(s,"Crea indice - %s", wisfd->d->Des);
			progind_create(wisfd->d->EOD, s, FALSE, TRUE, 10);
		}
		while (wisfd->RecNo < wisfd->d->EOD)
		{
			wisfd->RecNo++;
			CRead(&wisfd->f, rec, wisfd->RecNo, NoLock);
			if ((*err = wisfd->f.IOR)) break ;
			if (!IRecIsDeleted(rec))
				if (addkeys(wisfd,rec,1,err)) break ;
			if (vis && (wisfd->d->EOD > 0) && (!(wisfd->RecNo % 10)))
				progind_set_status(wisfd->RecNo);
		}
		if (vis && (wisfd->d->EOD > 0))
			progind_set_status(wisfd->RecNo);
		junk = cisclose(&wisfd, &rec, &junk);
		if (vis)
			progind_destroy();
		return(*err);
	}