#.TH SqlMinerva Onyx
#.SH NAME
#	SqlMinerva.ppg \- Grammar for Minerva as a Server

include "/usr/local/Minerva/include/msql.h"
include "memory.h"

class SqlMinerva : SqlParser {
	int sql_sock;

	SqlMinerva();
	virtual ~SqlMinerva();

	virtual int statement();
	virtual int select();
	virtual int other();
	virtual int query();

	virtual int sql_open();
	virtual int sql_close();
	virtual int sql_up();
	virtual void sql_purge();
	}

#.SH DESCRIPTION
#	SqlMinerva is the implementation of the Minerva as an Sql server
#	for Onyx.

statement :
	database | other
	;

select :
	"select" matchexp
	;

other :
	matchexp { query(); }
	.

{ /* ----------------------------------------------------------------------- */

SqlMinerva::SqlMinerva()
	: SqlParser()
{	sql_sock=-1;
	sql_row_type = 2;
	}

SqlMinerva::~SqlMinerva()
{	if (sql_sock !=-1) sql_close();
	}

int SqlMinerva::sql_open()
{	char *p,*q;

	if (!sql_database) return(0);

	if ((sql_sock = msqlConnect(NULL)) < 0) {
		message("ERROR : %s",msqlErrMsg);
		sql_sock = -1;
		return(0);
		}

	p=strchr(sql_database,'%'); if (p) *p=0;
	q=strchr(sql_database,'@'); if (q) *q=0;

	if (msqlSelectDB(sql_sock, sql_database) < 0) {
		if (p) *p = '%';
		if (q) *q = '@';
		message("ERROR : %s",msqlErrMsg);
		sql_sock = -1;
		return(0);
		}

	if (p) *p = '%';
	if (q) *q = '@';

	message("Connected to %s",sql_database);

	return(1);
	}

int SqlMinerva::sql_close()
{	if (sql_up()) {
		msqlClose(sql_sock);
		sql_sock = -1;
		message("Disconnect from %s",sql_database);
		SqlParser::sql_close();
		return(1);
		}
	else	return(0);
	}

int SqlMinerva::sql_up()
{	return(sql_sock != -1);
	}

void SqlMinerva::sql_purge()
{	SqlParser::sql_purge();
	}

#define bzero(s,l) memset(s,0,l)

int SqlMinerva::query()
{
	char	**p;
	char	*nq,
		sepBuf[2048];
	int	off,
		length;
	m_result *result;
	m_row	cur;
	m_field	*curField;

	if (!p_matched->nlines) return(1);
	(void)bzero(sepBuf,sizeof(sepBuf));
	p=p_matched->lines;

	while (p && *p) {
		strcpy(sepBuf+strlen(sepBuf),*p);
		strcpy(sepBuf+strlen(sepBuf)," ");
		p++;
		}

	if (msqlQuery(sql_sock,sepBuf) < 0)
	{
		message("ERROR : %s",msqlErrMsg);
		return(0);
	}
	message("Query OK.");

	result = msqlStoreResult();
	if (!result) {
		return(1);
		}

	message("%d rows matched.",(char*)msqlNumRows(result));

	/*
	** Print the returned data
	*/
	while ((cur = msqlFetchRow(result))) {
		(void)bzero(sepBuf,sizeof(sepBuf));
		off = 0;
		while(off < msqlNumFields(result)) {
			strcat(sepBuf,cur[off]);
			off++;
			if (off < msqlNumFields(result))
				strcat(sepBuf,"\t");
			}
		sql_row_text->add_line(sepBuf);
		}
	msqlFreeResult(result);
	return(1);
	}
/* ----------------------------------------------------------------------- */ }

