ds@1952: /* ds@1952: ** 2001 September 15 ds@1952: ** ds@1952: ** The author disclaims copyright to this source code. In place of ds@1952: ** a legal notice, here is a blessing: ds@1952: ** ds@1952: ** May you do good and not evil. ds@1952: ** May you find forgiveness for yourself and forgive others. ds@1952: ** May you share freely, never taking more than you give. ds@1952: ** ds@1952: ************************************************************************* ds@1952: ** This file contains the sqlite3_get_table() and sqlite3_free_table() ds@1952: ** interface routines. These are just wrappers around the main ds@1952: ** interface routine of sqlite3_exec(). ds@1952: ** ds@1952: ** These routines are in a separate files so that they will not be linked ds@1952: ** if they are not used. ds@1952: */ ds@1952: #include "sqliteInt.h" ds@1952: #include ds@1952: #include ds@1952: ds@1952: #ifndef SQLITE_OMIT_GET_TABLE ds@1952: ds@1952: /* ds@1952: ** This structure is used to pass data from sqlite3_get_table() through ds@1952: ** to the callback function is uses to build the result. ds@1952: */ ds@1952: typedef struct TabResult { ds@1952: char **azResult; ds@1952: char *zErrMsg; ds@1952: int nResult; ds@1952: int nAlloc; ds@1952: int nRow; ds@1952: int nColumn; ds@1952: int nData; ds@1952: int rc; ds@1952: } TabResult; ds@1952: ds@1952: /* ds@1952: ** This routine is called once for each row in the result table. Its job ds@1952: ** is to fill in the TabResult structure appropriately, allocating new ds@1952: ** memory as necessary. ds@1952: */ ds@1952: static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ ds@1952: TabResult *p = (TabResult*)pArg; ds@1952: int need; ds@1952: int i; ds@1952: char *z; ds@1952: ds@1952: /* Make sure there is enough space in p->azResult to hold everything ds@1952: ** we need to remember from this invocation of the callback. ds@1952: */ ds@1952: if( p->nRow==0 && argv!=0 ){ ds@1952: need = nCol*2; ds@1952: }else{ ds@1952: need = nCol; ds@1952: } ds@1952: if( p->nData + need >= p->nAlloc ){ ds@1952: char **azNew; ds@1952: p->nAlloc = p->nAlloc*2 + need + 1; ds@1952: azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc ); ds@1952: if( azNew==0 ) goto malloc_failed; ds@1952: p->azResult = azNew; ds@1952: } ds@1952: ds@1952: /* If this is the first row, then generate an extra row containing ds@1952: ** the names of all columns. ds@1952: */ ds@1952: if( p->nRow==0 ){ ds@1952: p->nColumn = nCol; ds@1952: for(i=0; iazResult[p->nData++] = z; ds@1952: } ds@1952: }else if( p->nColumn!=nCol ){ ds@1952: sqlite3SetString(&p->zErrMsg, ds@1952: "sqlite3_get_table() called with two or more incompatible queries", ds@1952: (char*)0); ds@1952: p->rc = SQLITE_ERROR; ds@1952: return 1; ds@1952: } ds@1952: ds@1952: /* Copy over the row data ds@1952: */ ds@1952: if( argv!=0 ){ ds@1952: for(i=0; iazResult[p->nData++] = z; ds@1952: } ds@1952: p->nRow++; ds@1952: } ds@1952: return 0; ds@1952: ds@1952: malloc_failed: ds@1952: p->rc = SQLITE_NOMEM; ds@1952: return 1; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** Query the database. But instead of invoking a callback for each row, ds@1952: ** malloc() for space to hold the result and return the entire results ds@1952: ** at the conclusion of the call. ds@1952: ** ds@1952: ** The result that is written to ***pazResult is held in memory obtained ds@1952: ** from malloc(). But the caller cannot free this memory directly. ds@1952: ** Instead, the entire table should be passed to sqlite3_free_table() when ds@1952: ** the calling procedure is finished using it. ds@1952: */ ds@1952: int sqlite3_get_table( ds@1952: sqlite3 *db, /* The database on which the SQL executes */ ds@1952: const char *zSql, /* The SQL to be executed */ ds@1952: char ***pazResult, /* Write the result table here */ ds@1952: int *pnRow, /* Write the number of rows in the result here */ ds@1952: int *pnColumn, /* Write the number of columns of result here */ ds@1952: char **pzErrMsg /* Write error messages here */ ds@1952: ){ ds@1952: int rc; ds@1952: TabResult res; ds@1952: if( pazResult==0 ){ return SQLITE_ERROR; } ds@1952: *pazResult = 0; ds@1952: if( pnColumn ) *pnColumn = 0; ds@1952: if( pnRow ) *pnRow = 0; ds@1952: res.zErrMsg = 0; ds@1952: res.nResult = 0; ds@1952: res.nRow = 0; ds@1952: res.nColumn = 0; ds@1952: res.nData = 1; ds@1952: res.nAlloc = 20; ds@1952: res.rc = SQLITE_OK; ds@1952: res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc ); ds@1952: if( res.azResult==0 ) return SQLITE_NOMEM; ds@1952: res.azResult[0] = 0; ds@1952: rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); ds@1952: #ifndef NDEBUG ds@1952: sqlite3_mutex_enter(db->mutex); ds@1952: assert((rc&db->errMask)==rc && (res.rc&db->errMask)==res.rc); ds@1952: sqlite3_mutex_leave(db->mutex); ds@1952: #endif ds@1952: if( res.azResult ){ ds@1952: assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); ds@1952: res.azResult[0] = (char*)res.nData; ds@1952: } ds@1952: if( (rc&0xff)==SQLITE_ABORT ){ ds@1952: sqlite3_free_table(&res.azResult[1]); ds@1952: if( res.zErrMsg ){ ds@1952: if( pzErrMsg ){ ds@1952: sqlite3_free(*pzErrMsg); ds@1952: *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); ds@1952: } ds@1952: sqlite3_free(res.zErrMsg); ds@1952: } ds@1952: sqlite3_mutex_enter(db->mutex); ds@1952: db->errCode = res.rc; ds@1952: sqlite3_mutex_leave(db->mutex); ds@1952: return res.rc; ds@1952: } ds@1952: sqlite3_free(res.zErrMsg); ds@1952: if( rc!=SQLITE_OK ){ ds@1952: sqlite3_free_table(&res.azResult[1]); ds@1952: return rc; ds@1952: } ds@1952: if( res.nAlloc>res.nData ){ ds@1952: char **azNew; ds@1952: azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) ); ds@1952: if( azNew==0 ){ ds@1952: sqlite3_free_table(&res.azResult[1]); ds@1952: return SQLITE_NOMEM; ds@1952: } ds@1952: res.nAlloc = res.nData+1; ds@1952: res.azResult = azNew; ds@1952: } ds@1952: *pazResult = &res.azResult[1]; ds@1952: if( pnColumn ) *pnColumn = res.nColumn; ds@1952: if( pnRow ) *pnRow = res.nRow; ds@1952: return rc; ds@1952: } ds@1952: ds@1952: /* ds@1952: ** This routine frees the space the sqlite3_get_table() malloced. ds@1952: */ ds@1952: void sqlite3_free_table( ds@1952: char **azResult /* Result returned from from sqlite3_get_table() */ ds@1952: ){ ds@1952: if( azResult ){ ds@1952: int i, n; ds@1952: azResult--; ds@1952: if( azResult==0 ) return; ds@1952: n = (int)azResult[0]; ds@1952: for(i=1; i