| 2 |      1 | /*
 | 
|  |      2 | ** 2001 September 15
 | 
|  |      3 | **
 | 
|  |      4 | ** The author disclaims copyright to this source code.  In place of
 | 
|  |      5 | ** a legal notice, here is a blessing:
 | 
|  |      6 | **
 | 
|  |      7 | **    May you do good and not evil.
 | 
|  |      8 | **    May you find forgiveness for yourself and forgive others.
 | 
|  |      9 | **    May you share freely, never taking more than you give.
 | 
|  |     10 | **
 | 
|  |     11 | *************************************************************************
 | 
|  |     12 | ** This file contains the sqlite3_get_table() and sqlite3_free_table()
 | 
|  |     13 | ** interface routines.  These are just wrappers around the main
 | 
|  |     14 | ** interface routine of sqlite3_exec().
 | 
|  |     15 | **
 | 
|  |     16 | ** These routines are in a separate files so that they will not be linked
 | 
|  |     17 | ** if they are not used.
 | 
|  |     18 | */
 | 
|  |     19 | #include "sqliteInt.h"
 | 
|  |     20 | #include <stdlib.h>
 | 
|  |     21 | #include <string.h>
 | 
|  |     22 | 
 | 
|  |     23 | #ifndef SQLITE_OMIT_GET_TABLE
 | 
|  |     24 | 
 | 
|  |     25 | /*
 | 
|  |     26 | ** This structure is used to pass data from sqlite3_get_table() through
 | 
|  |     27 | ** to the callback function is uses to build the result.
 | 
|  |     28 | */
 | 
|  |     29 | typedef struct TabResult {
 | 
|  |     30 |   char **azResult;
 | 
|  |     31 |   char *zErrMsg;
 | 
|  |     32 |   int nResult;
 | 
|  |     33 |   int nAlloc;
 | 
|  |     34 |   int nRow;
 | 
|  |     35 |   int nColumn;
 | 
|  |     36 |   int nData;
 | 
|  |     37 |   int rc;
 | 
|  |     38 | } TabResult;
 | 
|  |     39 | 
 | 
|  |     40 | /*
 | 
|  |     41 | ** This routine is called once for each row in the result table.  Its job
 | 
|  |     42 | ** is to fill in the TabResult structure appropriately, allocating new
 | 
|  |     43 | ** memory as necessary.
 | 
|  |     44 | */
 | 
|  |     45 | static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
 | 
|  |     46 |   TabResult *p = (TabResult*)pArg;
 | 
|  |     47 |   int need;
 | 
|  |     48 |   int i;
 | 
|  |     49 |   char *z;
 | 
|  |     50 | 
 | 
|  |     51 |   /* Make sure there is enough space in p->azResult to hold everything
 | 
|  |     52 |   ** we need to remember from this invocation of the callback.
 | 
|  |     53 |   */
 | 
|  |     54 |   if( p->nRow==0 && argv!=0 ){
 | 
|  |     55 |     need = nCol*2;
 | 
|  |     56 |   }else{
 | 
|  |     57 |     need = nCol;
 | 
|  |     58 |   }
 | 
|  |     59 |   if( p->nData + need >= p->nAlloc ){
 | 
|  |     60 |     char **azNew;
 | 
|  |     61 |     p->nAlloc = p->nAlloc*2 + need + 1;
 | 
|  |     62 |     azNew = (char**)sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
 | 
|  |     63 |     if( azNew==0 ) goto malloc_failed;
 | 
|  |     64 |     p->azResult = azNew;
 | 
|  |     65 |   }
 | 
|  |     66 | 
 | 
|  |     67 |   /* If this is the first row, then generate an extra row containing
 | 
|  |     68 |   ** the names of all columns.
 | 
|  |     69 |   */
 | 
|  |     70 |   if( p->nRow==0 ){
 | 
|  |     71 |     p->nColumn = nCol;
 | 
|  |     72 |     for(i=0; i<nCol; i++){
 | 
|  |     73 |       if( colv[i]==0 ){
 | 
|  |     74 |         z = sqlite3_mprintf("");
 | 
|  |     75 |       }else{
 | 
|  |     76 |         z = sqlite3_mprintf("%s", colv[i]);
 | 
|  |     77 |       }
 | 
|  |     78 |       p->azResult[p->nData++] = z;
 | 
|  |     79 |     }
 | 
|  |     80 |   }else if( p->nColumn!=nCol ){
 | 
|  |     81 |     sqlite3SetString(&p->zErrMsg,
 | 
|  |     82 |        "sqlite3_get_table() called with two or more incompatible queries",
 | 
|  |     83 |        (char*)0);
 | 
|  |     84 |     p->rc = SQLITE_ERROR;
 | 
|  |     85 |     return 1;
 | 
|  |     86 |   }
 | 
|  |     87 | 
 | 
|  |     88 |   /* Copy over the row data
 | 
|  |     89 |   */
 | 
|  |     90 |   if( argv!=0 ){
 | 
|  |     91 |     for(i=0; i<nCol; i++){
 | 
|  |     92 |       if( argv[i]==0 ){
 | 
|  |     93 |         z = 0;
 | 
|  |     94 |       }else{
 | 
|  |     95 |         int n = strlen(argv[i])+1;
 | 
|  |     96 |         z = (char*)sqlite3_malloc( n );
 | 
|  |     97 |         if( z==0 ) goto malloc_failed;
 | 
|  |     98 |         memcpy(z, argv[i], n);
 | 
|  |     99 |       }
 | 
|  |    100 |       p->azResult[p->nData++] = z;
 | 
|  |    101 |     }
 | 
|  |    102 |     p->nRow++;
 | 
|  |    103 |   }
 | 
|  |    104 |   return 0;
 | 
|  |    105 | 
 | 
|  |    106 | malloc_failed:
 | 
|  |    107 |   p->rc = SQLITE_NOMEM;
 | 
|  |    108 |   return 1;
 | 
|  |    109 | }
 | 
|  |    110 | 
 | 
|  |    111 | /*
 | 
|  |    112 | ** Query the database.  But instead of invoking a callback for each row,
 | 
|  |    113 | ** malloc() for space to hold the result and return the entire results
 | 
|  |    114 | ** at the conclusion of the call.
 | 
|  |    115 | **
 | 
|  |    116 | ** The result that is written to ***pazResult is held in memory obtained
 | 
|  |    117 | ** from malloc().  But the caller cannot free this memory directly.  
 | 
|  |    118 | ** Instead, the entire table should be passed to sqlite3_free_table() when
 | 
|  |    119 | ** the calling procedure is finished using it.
 | 
|  |    120 | */
 | 
|  |    121 | EXPORT_C int sqlite3_get_table(
 | 
|  |    122 |   sqlite3 *db,                /* The database on which the SQL executes */
 | 
|  |    123 |   const char *zSql,           /* The SQL to be executed */
 | 
|  |    124 |   char ***pazResult,          /* Write the result table here */
 | 
|  |    125 |   int *pnRow,                 /* Write the number of rows in the result here */
 | 
|  |    126 |   int *pnColumn,              /* Write the number of columns of result here */
 | 
|  |    127 |   char **pzErrMsg             /* Write error messages here */
 | 
|  |    128 | ){
 | 
|  |    129 |   int rc;
 | 
|  |    130 |   TabResult res;
 | 
|  |    131 |   if( pazResult==0 ){ return SQLITE_ERROR; }
 | 
|  |    132 |   *pazResult = 0;
 | 
|  |    133 |   if( pnColumn ) *pnColumn = 0;
 | 
|  |    134 |   if( pnRow ) *pnRow = 0;
 | 
|  |    135 |   res.zErrMsg = 0;
 | 
|  |    136 |   res.nResult = 0;
 | 
|  |    137 |   res.nRow = 0;
 | 
|  |    138 |   res.nColumn = 0;
 | 
|  |    139 |   res.nData = 1;
 | 
|  |    140 |   res.nAlloc = 20;
 | 
|  |    141 |   res.rc = SQLITE_OK;
 | 
|  |    142 |   res.azResult = (char**)sqlite3_malloc( sizeof(char*)*res.nAlloc );
 | 
|  |    143 |   if( res.azResult==0 ) return SQLITE_NOMEM;
 | 
|  |    144 |   res.azResult[0] = 0;
 | 
|  |    145 |   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
 | 
|  |    146 | #ifndef NDEBUG
 | 
|  |    147 |   sqlite3_mutex_enter(db->mutex);
 | 
|  |    148 |   assert((rc&db->errMask)==rc && (res.rc&db->errMask)==res.rc);
 | 
|  |    149 |   sqlite3_mutex_leave(db->mutex);
 | 
|  |    150 | #endif
 | 
|  |    151 |   if( res.azResult ){
 | 
|  |    152 |     assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
 | 
|  |    153 |     res.azResult[0] = (char*)res.nData;
 | 
|  |    154 |   }
 | 
|  |    155 |   if( (rc&0xff)==SQLITE_ABORT ){
 | 
|  |    156 |     sqlite3_free_table(&res.azResult[1]);
 | 
|  |    157 |     if( res.zErrMsg ){
 | 
|  |    158 |       if( pzErrMsg ){
 | 
|  |    159 |         sqlite3_free(*pzErrMsg);
 | 
|  |    160 |         *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
 | 
|  |    161 |       }
 | 
|  |    162 |       sqlite3_free(res.zErrMsg);
 | 
|  |    163 |     }
 | 
|  |    164 |     sqlite3_mutex_enter(db->mutex);
 | 
|  |    165 |     db->errCode = res.rc;
 | 
|  |    166 |     sqlite3_mutex_leave(db->mutex);
 | 
|  |    167 |     return res.rc;
 | 
|  |    168 |   }
 | 
|  |    169 |   sqlite3_free(res.zErrMsg);
 | 
|  |    170 |   if( rc!=SQLITE_OK ){
 | 
|  |    171 |     sqlite3_free_table(&res.azResult[1]);
 | 
|  |    172 |     return rc;
 | 
|  |    173 |   }
 | 
|  |    174 |   if( res.nAlloc>res.nData ){
 | 
|  |    175 |     char **azNew;
 | 
|  |    176 |     azNew = (char**)sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
 | 
|  |    177 |     if( azNew==0 ){
 | 
|  |    178 |       sqlite3_free_table(&res.azResult[1]);
 | 
|  |    179 |       return SQLITE_NOMEM;
 | 
|  |    180 |     }
 | 
|  |    181 |     res.nAlloc = res.nData+1;
 | 
|  |    182 |     res.azResult = azNew;
 | 
|  |    183 |   }
 | 
|  |    184 |   *pazResult = &res.azResult[1];
 | 
|  |    185 |   if( pnColumn ) *pnColumn = res.nColumn;
 | 
|  |    186 |   if( pnRow ) *pnRow = res.nRow;
 | 
|  |    187 |   return rc;
 | 
|  |    188 | }
 | 
|  |    189 | 
 | 
|  |    190 | /*
 | 
|  |    191 | ** This routine frees the space the sqlite3_get_table() malloced.
 | 
|  |    192 | */
 | 
|  |    193 | EXPORT_C void sqlite3_free_table(
 | 
|  |    194 |   char **azResult            /* Result returned from from sqlite3_get_table() */
 | 
|  |    195 | ){
 | 
|  |    196 |   if( azResult ){
 | 
|  |    197 |     int i, n;
 | 
|  |    198 |     azResult--;
 | 
|  |    199 |     if( azResult==0 ) return;
 | 
|  |    200 |     n = (int)azResult[0];
 | 
|  |    201 |     for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
 | 
|  |    202 |     sqlite3_free(azResult);
 | 
|  |    203 |   }
 | 
|  |    204 | }
 | 
|  |    205 | 
 | 
|  |    206 | #endif /* SQLITE_OMIT_GET_TABLE */
 |