/* SDB - import/export commands */

#include "bdscio.h"
#include "dbqdefs.h"

int *db_import()
{
	struct scan *sptr;
	struct attribute *aptr;
	char fname[STRINGMAX+1],avalue[STRINGMAX+1];
	int tcnt,astart,i,eofile;
	FILE *fp;

	if (db_ntoken() == ID)
		strcat(dbv_tstring,".dat");
	else if (dbv_token != STRING)
		{ RETERR(SYNTAX) }
	strcpy(fname,dbv_tstring);
	if (db_ntoken() != INTO)
		{ RETERR(SYNTAX) }
	if (db_ntoken() != ID)
		{ RETERR(SYNTAX) }

	if ((sptr = db_ropen(dbv_tstring)) == NULL)
		return(FALSE);

	if ((fp = CALLOC(BUFSIZ)) == NULL) {
		RETERR(INSMEM) }

	if ((fopen(fname,fp)) == ERROR) {
		CFREE(fp);
		RETERR(INPFNF)
		}
/*
	if ((fp = fopen(fname,"r")) == NULL) /* OH NO NOT AGAIN */
		{ RETERR(INPFNF) }
*/
	eofile = FALSE;
	for (tcnt = 0; ; tcnt++) {

		astart = 1;
		for (i = 0; i < NATTRS; i++) {
			aptr = &sptr->sc_relation->rl_header.hd_attrs[i];

			if (aptr->at_name[0] == 0)
				break;

			if (fgets(avalue,fp) == 0) {
				eofile = TRUE;
				break;
			}
			avalue[strlen(avalue)-1] = EOS;

			db_aput(aptr,&sptr->sc_tuple[astart],avalue);

			astart += aptr->at_size;
		}

		if (!eofile) {
			if (!db_rstore(sptr)) {
				db_rclose(sptr);
				return (FALSE);
			}
		}
		else
			break;
	}

	db_rclose(sptr);

	fclose(fp);
	CFREE(fp);

	pcount(tcnt,"imported");

	return (TRUE);
}

int *db_export()	/* remember to forget about fmt etc */
{
	struct scan *sptr;
	struct attribute *aptr;
	char rname[STRINGMAX+1],avalue[STRINGMAX+1];
	int tcnt,astart,i,delflg;
	FILE *fp;

	if (db_ntoken() != ID)
		{ RETERR(SYNTAX) }

	if (db_scmp(dbv_tstring,"deleted") == 0) {
		delflg = TRUE;
		if (db_ntoken() != ID)
			{ RETERR(SYNTAX) }
		}
	else
		delflg = FALSE;

	strcpy(rname,dbv_tstring);

	if (!db_to(&fp,".dat"))
		return(FALSE);

	if ((sptr = db_ropen(rname)) == NULL)
		return(FALSE);

	for (tcnt = 0; dexport(sptr,delflg); tcnt++) {
		astart = 1;
		for (i = 0; i < NATTRS; i++) {

			aptr = &sptr->sc_relation->rl_header.hd_attrs[i];

			if (aptr->at_name[0] == 0)
				break;

			db_aget(aptr,&sptr->sc_tuple[astart],avalue);

			fprintf(fp,"%s\n",avalue);

			astart += aptr->at_size;
		}
	}

	db_rclose(sptr);

	if (fp != STDOUT)
		fclose(fp);

	pcount(tcnt,"exported");

	return (TRUE);
}

int dexport(sptr,delflg)
struct scan *sptr; int delflg;
{
	if (delflg)
		return (db_dfetch(sptr));
	else
		return (db_rfetch(sptr));
}

int *db_squeeze()
{
	struct scan *sptr;

	if (db_ntoken() != ID)
		{ RETERR(SYNTAX) }

	if ((sptr = db_ropen(dbv_tstring)) == NULL)
		return (FALSE);

	if (!db_rcompress(sptr)) {
		db_rclose(sptr);
		return (FALSE);
	}

	db_rclose(sptr);

	return (TRUE);
}

int *db_extract()
{
	struct scan *sptr;
	struct attribute *aptr;
	char rname[STRINGMAX+1],aname[ANSIZE+1],*atype;
	int i;
	FILE *fp;

	if (db_ntoken() != ID)
		{ RETERR(SYNTAX) }
	strcpy(rname,dbv_tstring);
	if (!db_to(&fp,".def"))
		return (FALSE);

	if ((sptr = db_ropen(rname)) == NULL)
		return (FALSE);

	fprintf(fp,"create %s\n",rname);

	for (i = 0; i < NATTRS; i++) {

		aptr = &sptr->sc_relation->rl_header.hd_attrs[i];

		if (aptr->at_name[0] == 0)
			break;

		strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0;

		switch (aptr->at_type) {
		case TCHAR:
			atype = "char";
			break;
		case TNUM:
			atype = "num";
			break;
		default:
			atype = "<error>";
			break;
		}

		if (strlen(aname) < 8)
			fprintf(fp,"\t%s\t\t%s\t%d\t%d\n",aname,atype,
				aptr->at_size,aptr->at_scale);
		else
			fprintf(fp,"\t%s\t%s\t%d\t%d\n",aname,atype,
				aptr->at_size,aptr->at_scale);
	}

/*	fprintf(fp,") %d\n",sptr->sc_relation->rl_tmax);	*/
	fprintf(fp,";\n");

	db_rclose(sptr);

	if (fp != STDOUT)
		fclose(fp);

	return (TRUE);
}


int db_rcompress(sptr)
	struct scan *sptr;
{

	unsigned next,nextfree,tcnt;

	tcnt = sptr->sc_relation->rl_tcnt;

	for (next = nextfree = 1; next <= tcnt; next++) {

		tseek(sptr,next);
		if (cread(sptr->sc_relation->rl_fd,
			sptr->sc_tuple,sptr->sc_relation->rl_size)
				!= sptr->sc_relation->rl_size)
			{ RETERR(TUPINP) }

		if (sptr->sc_tuple[0] == ACTIVE) {

			if (next != nextfree) {
			tseek(sptr,nextfree);
			    if (cwrite(sptr->sc_relation->rl_fd,
				sptr->sc_tuple,sptr->sc_relation->rl_size)
					!= sptr->sc_relation->rl_size)
				{ RETERR(TUPOUT) }
			}

		nextfree += 1;
		}
	}

	nextfree--;

	tcnt = sptr->sc_relation->rl_tcnt - nextfree;
	pcount(tcnt,"freed");

	sptr->sc_relation->rl_tcnt = nextfree;

	sptr->sc_atnum = sptr->sc_relation->rl_tcnt;

	sptr->sc_dtnum = 0;

	sptr->sc_store = TRUE;

	return (TRUE);
}

;

	sptr->sc_atnum = sptr->sc_relation->rl_tcnt;

	sptr->sc_dtnum = 0;

	sptr->sc_store = TRUE;
