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 */