/*
** Utility functions for sqlite which iterate through the results of a query.
** This version just adds a wrapper around sqlite_get_table() results.
**
** 2002-12-01 James P. Lyon
*/

#include <assert.h>

#include "sqlite.h"

#ifndef NULL
#define NULL ((void*)0)
#endif


/* Structure used to access table rows returned from a query
** one row at a time.
*/
typedef struct table_rowset
{
	char **table;   /* pointer returned by sqlite_get_table(). */
	int nRow;       /* number of rows. */
	int nCol;       /* number of columns. */
	int nIndex;     /* current row index. */
} table_rowset;

/*
** Initialize the table rowset structure from a SQL query.
*/
int sqaux_rowset_open( 
  sqlite *db,                 /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  table_rowset *pResult,      /* Write the result table_record here */
  char **pzErrMsg             /* Write error messages here */
)
{
	int rc;

	/* Validate arguments */
	assert(db && pResult && zSql);
	if (!db || !pResult || !zSql) return SQLITE_ERROR;

	rc = sqlite_get_table(db, zSql, &(pResult->table), &pResult->nRow, &pResult->nCol, pzErrMsg);
	if (rc != SQLITE_OK || pResult->nRow == 0 || pResult->nCol == 0)
	{
		/* call sqlite_free_table()? */

		pResult->table = (char**)NULL;
		pResult->nRow = pResult->nCol = 0;
		pResult->nIndex = pResult->nRow;
	}
	else
	{
		/* Point to just before the first record. */
		pResult->nIndex = -1;
	}

	return rc;
}

/*
int sqaux_rowset_prev(table_rowset *pRecord);
*/

/*
** Return the number of columns in the rowset.
*/
int sqaux_rowset_cols(const table_rowset *pRecord)
{
	assert(pRecord);
	if (!pRecord)
		return 0;

	return pRecord->nCol;
}

/*
** Return pointer to array of names of the columns.
** The number of columns is obtained from sqaux_rowset_cols().
*/
const char **sqaux_rowset_names(table_rowset *pRecord)
{
	assert(pRecord);
	if (!pRecord)
		return NULL;

	assert(pRecord->table);
	return (pRecord->table);
}

/*
** Advance the rowset to the next row and return pointer to its data.
** The number of columns is obtained from sqaux_rowset_cols().
** If the rowset was just opened, this will point to the first data row.
** Returns NULL on error or when there are no more rows.
*/
const char **sqaux_rowset_next(table_rowset *pRecord)
{
	char **pRow;

	assert(pRecord);
	if (!pRecord)
		return NULL;

	assert(pRecord->table);
	if (!pRecord->table)
		return NULL;

	pRecord->nIndex++;
	if (pRecord->nIndex >= pRecord->nRow)
		return NULL;

	/* Return a pointer to the data for this row.
	** The +1 skips the row that contains column names.
	*/
	pRow = pRecord->table + (pRecord->nRow+1)*pRecord->nCol;

	return pRow;
}

/*
** Close a rowset and free associated resources.
*/
void sqaux_rowset_close(table_rowset *pRecord)
{
	if (pRecord)
		sqlite_free_table(pRecord->table);
}
