extensions/sqlite/sqlite-source/table.c
changeset 1952 b7aa2b626807
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/extensions/sqlite/sqlite-source/table.c	Sun Mar 30 07:00:22 2008 +0000
     1.3 @@ -0,0 +1,206 @@
     1.4 +/*
     1.5 +** 2001 September 15
     1.6 +**
     1.7 +** The author disclaims copyright to this source code.  In place of
     1.8 +** a legal notice, here is a blessing:
     1.9 +**
    1.10 +**    May you do good and not evil.
    1.11 +**    May you find forgiveness for yourself and forgive others.
    1.12 +**    May you share freely, never taking more than you give.
    1.13 +**
    1.14 +*************************************************************************
    1.15 +** This file contains the sqlite3_get_table() and sqlite3_free_table()
    1.16 +** interface routines.  These are just wrappers around the main
    1.17 +** interface routine of sqlite3_exec().
    1.18 +**
    1.19 +** These routines are in a separate files so that they will not be linked
    1.20 +** if they are not used.
    1.21 +*/
    1.22 +#include "sqliteInt.h"
    1.23 +#include <stdlib.h>
    1.24 +#include <string.h>
    1.25 +
    1.26 +#ifndef SQLITE_OMIT_GET_TABLE
    1.27 +
    1.28 +/*
    1.29 +** This structure is used to pass data from sqlite3_get_table() through
    1.30 +** to the callback function is uses to build the result.
    1.31 +*/
    1.32 +typedef struct TabResult {
    1.33 +  char **azResult;
    1.34 +  char *zErrMsg;
    1.35 +  int nResult;
    1.36 +  int nAlloc;
    1.37 +  int nRow;
    1.38 +  int nColumn;
    1.39 +  int nData;
    1.40 +  int rc;
    1.41 +} TabResult;
    1.42 +
    1.43 +/*
    1.44 +** This routine is called once for each row in the result table.  Its job
    1.45 +** is to fill in the TabResult structure appropriately, allocating new
    1.46 +** memory as necessary.
    1.47 +*/
    1.48 +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
    1.49 +  TabResult *p = (TabResult*)pArg;
    1.50 +  int need;
    1.51 +  int i;
    1.52 +  char *z;
    1.53 +
    1.54 +  /* Make sure there is enough space in p->azResult to hold everything
    1.55 +  ** we need to remember from this invocation of the callback.
    1.56 +  */
    1.57 +  if( p->nRow==0 && argv!=0 ){
    1.58 +    need = nCol*2;
    1.59 +  }else{
    1.60 +    need = nCol;
    1.61 +  }
    1.62 +  if( p->nData + need >= p->nAlloc ){
    1.63 +    char **azNew;
    1.64 +    p->nAlloc = p->nAlloc*2 + need + 1;
    1.65 +    azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
    1.66 +    if( azNew==0 ) goto malloc_failed;
    1.67 +    p->azResult = azNew;
    1.68 +  }
    1.69 +
    1.70 +  /* If this is the first row, then generate an extra row containing
    1.71 +  ** the names of all columns.
    1.72 +  */
    1.73 +  if( p->nRow==0 ){
    1.74 +    p->nColumn = nCol;
    1.75 +    for(i=0; i<nCol; i++){
    1.76 +      if( colv[i]==0 ){
    1.77 +        z = sqlite3_mprintf("");
    1.78 +      }else{
    1.79 +        z = sqlite3_mprintf("%s", colv[i]);
    1.80 +      }
    1.81 +      p->azResult[p->nData++] = z;
    1.82 +    }
    1.83 +  }else if( p->nColumn!=nCol ){
    1.84 +    sqlite3SetString(&p->zErrMsg,
    1.85 +       "sqlite3_get_table() called with two or more incompatible queries",
    1.86 +       (char*)0);
    1.87 +    p->rc = SQLITE_ERROR;
    1.88 +    return 1;
    1.89 +  }
    1.90 +
    1.91 +  /* Copy over the row data
    1.92 +  */
    1.93 +  if( argv!=0 ){
    1.94 +    for(i=0; i<nCol; i++){
    1.95 +      if( argv[i]==0 ){
    1.96 +        z = 0;
    1.97 +      }else{
    1.98 +        int n = strlen(argv[i])+1;
    1.99 +        z = sqlite3_malloc( n );
   1.100 +        if( z==0 ) goto malloc_failed;
   1.101 +        memcpy(z, argv[i], n);
   1.102 +      }
   1.103 +      p->azResult[p->nData++] = z;
   1.104 +    }
   1.105 +    p->nRow++;
   1.106 +  }
   1.107 +  return 0;
   1.108 +
   1.109 +malloc_failed:
   1.110 +  p->rc = SQLITE_NOMEM;
   1.111 +  return 1;
   1.112 +}
   1.113 +
   1.114 +/*
   1.115 +** Query the database.  But instead of invoking a callback for each row,
   1.116 +** malloc() for space to hold the result and return the entire results
   1.117 +** at the conclusion of the call.
   1.118 +**
   1.119 +** The result that is written to ***pazResult is held in memory obtained
   1.120 +** from malloc().  But the caller cannot free this memory directly.  
   1.121 +** Instead, the entire table should be passed to sqlite3_free_table() when
   1.122 +** the calling procedure is finished using it.
   1.123 +*/
   1.124 +int sqlite3_get_table(
   1.125 +  sqlite3 *db,                /* The database on which the SQL executes */
   1.126 +  const char *zSql,           /* The SQL to be executed */
   1.127 +  char ***pazResult,          /* Write the result table here */
   1.128 +  int *pnRow,                 /* Write the number of rows in the result here */
   1.129 +  int *pnColumn,              /* Write the number of columns of result here */
   1.130 +  char **pzErrMsg             /* Write error messages here */
   1.131 +){
   1.132 +  int rc;
   1.133 +  TabResult res;
   1.134 +  if( pazResult==0 ){ return SQLITE_ERROR; }
   1.135 +  *pazResult = 0;
   1.136 +  if( pnColumn ) *pnColumn = 0;
   1.137 +  if( pnRow ) *pnRow = 0;
   1.138 +  res.zErrMsg = 0;
   1.139 +  res.nResult = 0;
   1.140 +  res.nRow = 0;
   1.141 +  res.nColumn = 0;
   1.142 +  res.nData = 1;
   1.143 +  res.nAlloc = 20;
   1.144 +  res.rc = SQLITE_OK;
   1.145 +  res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc );
   1.146 +  if( res.azResult==0 ) return SQLITE_NOMEM;
   1.147 +  res.azResult[0] = 0;
   1.148 +  rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
   1.149 +#ifndef NDEBUG
   1.150 +  sqlite3_mutex_enter(db->mutex);
   1.151 +  assert((rc&db->errMask)==rc && (res.rc&db->errMask)==res.rc);
   1.152 +  sqlite3_mutex_leave(db->mutex);
   1.153 +#endif
   1.154 +  if( res.azResult ){
   1.155 +    assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
   1.156 +    res.azResult[0] = (char*)res.nData;
   1.157 +  }
   1.158 +  if( (rc&0xff)==SQLITE_ABORT ){
   1.159 +    sqlite3_free_table(&res.azResult[1]);
   1.160 +    if( res.zErrMsg ){
   1.161 +      if( pzErrMsg ){
   1.162 +        sqlite3_free(*pzErrMsg);
   1.163 +        *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
   1.164 +      }
   1.165 +      sqlite3_free(res.zErrMsg);
   1.166 +    }
   1.167 +    sqlite3_mutex_enter(db->mutex);
   1.168 +    db->errCode = res.rc;
   1.169 +    sqlite3_mutex_leave(db->mutex);
   1.170 +    return res.rc;
   1.171 +  }
   1.172 +  sqlite3_free(res.zErrMsg);
   1.173 +  if( rc!=SQLITE_OK ){
   1.174 +    sqlite3_free_table(&res.azResult[1]);
   1.175 +    return rc;
   1.176 +  }
   1.177 +  if( res.nAlloc>res.nData ){
   1.178 +    char **azNew;
   1.179 +    azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
   1.180 +    if( azNew==0 ){
   1.181 +      sqlite3_free_table(&res.azResult[1]);
   1.182 +      return SQLITE_NOMEM;
   1.183 +    }
   1.184 +    res.nAlloc = res.nData+1;
   1.185 +    res.azResult = azNew;
   1.186 +  }
   1.187 +  *pazResult = &res.azResult[1];
   1.188 +  if( pnColumn ) *pnColumn = res.nColumn;
   1.189 +  if( pnRow ) *pnRow = res.nRow;
   1.190 +  return rc;
   1.191 +}
   1.192 +
   1.193 +/*
   1.194 +** This routine frees the space the sqlite3_get_table() malloced.
   1.195 +*/
   1.196 +void sqlite3_free_table(
   1.197 +  char **azResult            /* Result returned from from sqlite3_get_table() */
   1.198 +){
   1.199 +  if( azResult ){
   1.200 +    int i, n;
   1.201 +    azResult--;
   1.202 +    if( azResult==0 ) return;
   1.203 +    n = (int)azResult[0];
   1.204 +    for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
   1.205 +    sqlite3_free(azResult);
   1.206 +  }
   1.207 +}
   1.208 +
   1.209 +#endif /* SQLITE_OMIT_GET_TABLE */