Back to index

php5  5.3.10
table.c
Go to the documentation of this file.
00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains the sqlite_get_table() and sqlite_free_table()
00013 ** interface routines.  These are just wrappers around the main
00014 ** interface routine of sqlite_exec().
00015 **
00016 ** These routines are in a separate files so that they will not be linked
00017 ** if they are not used.
00018 */
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include "sqliteInt.h"
00022 
00023 /*
00024 ** This structure is used to pass data from sqlite_get_table() through
00025 ** to the callback function is uses to build the result.
00026 */
00027 typedef struct TabResult {
00028   char **azResult;
00029   char *zErrMsg;
00030   int nResult;
00031   int nAlloc;
00032   int nRow;
00033   int nColumn;
00034   long nData;
00035   int rc;
00036 } TabResult;
00037 
00038 /*
00039 ** This routine is called once for each row in the result table.  Its job
00040 ** is to fill in the TabResult structure appropriately, allocating new
00041 ** memory as necessary.
00042 */
00043 static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
00044   TabResult *p = (TabResult*)pArg;
00045   int need;
00046   int i;
00047   char *z;
00048 
00049   /* Make sure there is enough space in p->azResult to hold everything
00050   ** we need to remember from this invocation of the callback.
00051   */
00052   if( p->nRow==0 && argv!=0 ){
00053     need = nCol*2;
00054   }else{
00055     need = nCol;
00056   }
00057   if( p->nData + need >= p->nAlloc ){
00058     char **azNew;
00059     p->nAlloc = p->nAlloc*2 + need + 1;
00060     azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
00061     if( azNew==0 ){
00062       p->rc = SQLITE_NOMEM;
00063       return 1;
00064     }
00065     p->azResult = azNew;
00066   }
00067 
00068   /* If this is the first row, then generate an extra row containing
00069   ** the names of all columns.
00070   */
00071   if( p->nRow==0 ){
00072     p->nColumn = nCol;
00073     for(i=0; i<nCol; i++){
00074       if( colv[i]==0 ){
00075         z = 0;
00076       }else{
00077         z = malloc( strlen(colv[i])+1 );
00078         if( z==0 ){
00079           p->rc = SQLITE_NOMEM;
00080           return 1;
00081         }
00082         strcpy(z, colv[i]);
00083       }
00084       p->azResult[p->nData++] = z;
00085     }
00086   }else if( p->nColumn!=nCol ){
00087     sqliteSetString(&p->zErrMsg,
00088        "sqlite_get_table() called with two or more incompatible queries",
00089        (char*)0);
00090     p->rc = SQLITE_ERROR;
00091     return 1;
00092   }
00093 
00094   /* Copy over the row data
00095   */
00096   if( argv!=0 ){
00097     for(i=0; i<nCol; i++){
00098       if( argv[i]==0 ){
00099         z = 0;
00100       }else{
00101         z = malloc( strlen(argv[i])+1 );
00102         if( z==0 ){
00103           p->rc = SQLITE_NOMEM;
00104           return 1;
00105         }
00106         strcpy(z, argv[i]);
00107       }
00108       p->azResult[p->nData++] = z;
00109     }
00110     p->nRow++;
00111   }
00112   return 0;
00113 }
00114 
00115 /*
00116 ** Query the database.  But instead of invoking a callback for each row,
00117 ** malloc() for space to hold the result and return the entire results
00118 ** at the conclusion of the call.
00119 **
00120 ** The result that is written to ***pazResult is held in memory obtained
00121 ** from malloc().  But the caller cannot free this memory directly.  
00122 ** Instead, the entire table should be passed to sqlite_free_table() when
00123 ** the calling procedure is finished using it.
00124 */
00125 int sqlite_get_table(
00126   sqlite *db,                 /* The database on which the SQL executes */
00127   const char *zSql,           /* The SQL to be executed */
00128   char ***pazResult,          /* Write the result table here */
00129   int *pnRow,                 /* Write the number of rows in the result here */
00130   int *pnColumn,              /* Write the number of columns of result here */
00131   char **pzErrMsg             /* Write error messages here */
00132 ){
00133   int rc;
00134   TabResult res;
00135   if( pazResult==0 ){ return SQLITE_ERROR; }
00136   *pazResult = 0;
00137   if( pnColumn ) *pnColumn = 0;
00138   if( pnRow ) *pnRow = 0;
00139   res.zErrMsg = 0;
00140   res.nResult = 0;
00141   res.nRow = 0;
00142   res.nColumn = 0;
00143   res.nData = 1;
00144   res.nAlloc = 20;
00145   res.rc = SQLITE_OK;
00146   res.azResult = malloc( sizeof(char*)*res.nAlloc );
00147   if( res.azResult==0 ){
00148     return SQLITE_NOMEM;
00149   }
00150   res.azResult[0] = 0;
00151   rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
00152   if( res.azResult ){
00153     res.azResult[0] = (char*)res.nData;
00154   }
00155   if( rc==SQLITE_ABORT ){
00156     sqlite_free_table(&res.azResult[1]);
00157     if( res.zErrMsg ){
00158       if( pzErrMsg ){
00159         free(*pzErrMsg);
00160         *pzErrMsg = res.zErrMsg;
00161         sqliteStrRealloc(pzErrMsg);
00162       }else{
00163         sqliteFree(res.zErrMsg);
00164       }
00165     }
00166     return res.rc;
00167   }
00168   sqliteFree(res.zErrMsg);
00169   if( rc!=SQLITE_OK ){
00170     sqlite_free_table(&res.azResult[1]);
00171     return rc;
00172   }
00173   if( res.nAlloc>res.nData ){
00174     char **azNew;
00175     azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
00176     if( azNew==0 ){
00177       sqlite_free_table(&res.azResult[1]);
00178       return SQLITE_NOMEM;
00179     }
00180     res.nAlloc = res.nData+1;
00181     res.azResult = azNew;
00182   }
00183   *pazResult = &res.azResult[1];
00184   if( pnColumn ) *pnColumn = res.nColumn;
00185   if( pnRow ) *pnRow = res.nRow;
00186   return rc;
00187 }
00188 
00189 /*
00190 ** This routine frees the space the sqlite_get_table() malloced.
00191 */
00192 void sqlite_free_table(
00193   char **azResult             /* Result returned from from sqlite_get_table() */
00194 ){
00195   if( azResult ){
00196     int i, n;
00197     azResult--;
00198     if( azResult==0 ) return;
00199     n = (int)(long)azResult[0];
00200     for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
00201     free(azResult);
00202   }
00203 }