2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A** 2001 September 15
2N/A**
2N/A** The author disclaims copyright to this source code. In place of
2N/A** a legal notice, here is a blessing:
2N/A**
2N/A** May you do good and not evil.
2N/A** May you find forgiveness for yourself and forgive others.
2N/A** May you share freely, never taking more than you give.
2N/A**
2N/A*************************************************************************
2N/A** This file contains the sqlite_get_table() and sqlite_free_table()
2N/A** interface routines. These are just wrappers around the main
2N/A** interface routine of sqlite_exec().
2N/A**
2N/A** These routines are in a separate files so that they will not be linked
2N/A** if they are not used.
2N/A*/
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include "sqliteInt.h"
2N/A
2N/A/*
2N/A** This structure is used to pass data from sqlite_get_table() through
2N/A** to the callback function is uses to build the result.
2N/A*/
2N/Atypedef struct TabResult {
2N/A char **azResult;
2N/A char *zErrMsg;
2N/A int nResult;
2N/A int nAlloc;
2N/A int nRow;
2N/A int nColumn;
2N/A long nData;
2N/A int rc;
2N/A} TabResult;
2N/A
2N/A/*
2N/A** This routine is called once for each row in the result table. Its job
2N/A** is to fill in the TabResult structure appropriately, allocating new
2N/A** memory as necessary.
2N/A*/
2N/Astatic int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
2N/A TabResult *p = (TabResult*)pArg;
2N/A int need;
2N/A int i;
2N/A char *z;
2N/A
2N/A /* Make sure there is enough space in p->azResult to hold everything
2N/A ** we need to remember from this invocation of the callback.
2N/A */
2N/A if( p->nRow==0 && argv!=0 ){
2N/A need = nCol*2;
2N/A }else{
2N/A need = nCol;
2N/A }
2N/A if( p->nData + need >= p->nAlloc ){
2N/A char **azNew;
2N/A p->nAlloc = p->nAlloc*2 + need + 1;
2N/A azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
2N/A if( azNew==0 ){
2N/A p->rc = SQLITE_NOMEM;
2N/A return 1;
2N/A }
2N/A p->azResult = azNew;
2N/A }
2N/A
2N/A /* If this is the first row, then generate an extra row containing
2N/A ** the names of all columns.
2N/A */
2N/A if( p->nRow==0 ){
2N/A p->nColumn = nCol;
2N/A for(i=0; i<nCol; i++){
2N/A if( colv[i]==0 ){
2N/A z = 0;
2N/A }else{
2N/A z = malloc( strlen(colv[i])+1 );
2N/A if( z==0 ){
2N/A p->rc = SQLITE_NOMEM;
2N/A return 1;
2N/A }
2N/A strcpy(z, colv[i]);
2N/A }
2N/A p->azResult[p->nData++] = z;
2N/A }
2N/A }else if( p->nColumn!=nCol ){
2N/A sqliteSetString(&p->zErrMsg,
2N/A "sqlite_get_table() called with two or more incompatible queries",
2N/A (char*)0);
2N/A p->rc = SQLITE_ERROR;
2N/A return 1;
2N/A }
2N/A
2N/A /* Copy over the row data
2N/A */
2N/A if( argv!=0 ){
2N/A for(i=0; i<nCol; i++){
2N/A if( argv[i]==0 ){
2N/A z = 0;
2N/A }else{
2N/A z = malloc( strlen(argv[i])+1 );
2N/A if( z==0 ){
2N/A p->rc = SQLITE_NOMEM;
2N/A return 1;
2N/A }
2N/A strcpy(z, argv[i]);
2N/A }
2N/A p->azResult[p->nData++] = z;
2N/A }
2N/A p->nRow++;
2N/A }
2N/A return 0;
2N/A}
2N/A
2N/A/*
2N/A** Query the database. But instead of invoking a callback for each row,
2N/A** malloc() for space to hold the result and return the entire results
2N/A** at the conclusion of the call.
2N/A**
2N/A** The result that is written to ***pazResult is held in memory obtained
2N/A** from malloc(). But the caller cannot free this memory directly.
2N/A** Instead, the entire table should be passed to sqlite_free_table() when
2N/A** the calling procedure is finished using it.
2N/A*/
2N/Aint sqlite_get_table(
2N/A sqlite *db, /* The database on which the SQL executes */
2N/A const char *zSql, /* The SQL to be executed */
2N/A char ***pazResult, /* Write the result table here */
2N/A int *pnRow, /* Write the number of rows in the result here */
2N/A int *pnColumn, /* Write the number of columns of result here */
2N/A char **pzErrMsg /* Write error messages here */
2N/A){
2N/A int rc;
2N/A TabResult res;
2N/A if( pazResult==0 ){ return SQLITE_ERROR; }
2N/A *pazResult = 0;
2N/A if( pnColumn ) *pnColumn = 0;
2N/A if( pnRow ) *pnRow = 0;
2N/A res.zErrMsg = 0;
2N/A res.nResult = 0;
2N/A res.nRow = 0;
2N/A res.nColumn = 0;
2N/A res.nData = 1;
2N/A res.nAlloc = 20;
2N/A res.rc = SQLITE_OK;
2N/A res.azResult = malloc( sizeof(char*)*res.nAlloc );
2N/A if( res.azResult==0 ){
2N/A return SQLITE_NOMEM;
2N/A }
2N/A res.azResult[0] = 0;
2N/A rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
2N/A if( res.azResult ){
2N/A res.azResult[0] = (char*)res.nData;
2N/A }
2N/A if( rc==SQLITE_ABORT ){
2N/A sqlite_free_table(&res.azResult[1]);
2N/A if( res.zErrMsg ){
2N/A if( pzErrMsg ){
2N/A free(*pzErrMsg);
2N/A *pzErrMsg = res.zErrMsg;
2N/A sqliteStrRealloc(pzErrMsg);
2N/A }else{
2N/A sqliteFree(res.zErrMsg);
2N/A }
2N/A }
2N/A return res.rc;
2N/A }
2N/A sqliteFree(res.zErrMsg);
2N/A if( rc!=SQLITE_OK ){
2N/A sqlite_free_table(&res.azResult[1]);
2N/A return rc;
2N/A }
2N/A if( res.nAlloc>res.nData ){
2N/A char **azNew;
2N/A azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
2N/A if( azNew==0 ){
2N/A sqlite_free_table(&res.azResult[1]);
2N/A return SQLITE_NOMEM;
2N/A }
2N/A res.nAlloc = res.nData+1;
2N/A res.azResult = azNew;
2N/A }
2N/A *pazResult = &res.azResult[1];
2N/A if( pnColumn ) *pnColumn = res.nColumn;
2N/A if( pnRow ) *pnRow = res.nRow;
2N/A return rc;
2N/A}
2N/A
2N/A/*
2N/A** This routine frees the space the sqlite_get_table() malloced.
2N/A*/
2N/Avoid sqlite_free_table(
2N/A char **azResult /* Result returned from from sqlite_get_table() */
2N/A){
2N/A if( azResult ){
2N/A int i, n;
2N/A azResult--;
2N/A if( azResult==0 ) return;
2N/A n = (int)(long)azResult[0];
2N/A for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
2N/A free(azResult);
2N/A }
2N/A}