1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/SQLite/table.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,201 @@
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 +** $Id: table.c,v 1.36 2008/07/08 22:28:49 shane Exp $
1.23 +*/
1.24 +#include "sqliteInt.h"
1.25 +#include <stdlib.h>
1.26 +#include <string.h>
1.27 +
1.28 +#ifndef SQLITE_OMIT_GET_TABLE
1.29 +
1.30 +/*
1.31 +** This structure is used to pass data from sqlite3_get_table() through
1.32 +** to the callback function is uses to build the result.
1.33 +*/
1.34 +typedef struct TabResult {
1.35 + char **azResult;
1.36 + char *zErrMsg;
1.37 + int nResult;
1.38 + int nAlloc;
1.39 + int nRow;
1.40 + int nColumn;
1.41 + int nData;
1.42 + int rc;
1.43 +} TabResult;
1.44 +
1.45 +/*
1.46 +** This routine is called once for each row in the result table. Its job
1.47 +** is to fill in the TabResult structure appropriately, allocating new
1.48 +** memory as necessary.
1.49 +*/
1.50 +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
1.51 + TabResult *p = (TabResult*)pArg;
1.52 + int need;
1.53 + int i;
1.54 + char *z;
1.55 +
1.56 + /* Make sure there is enough space in p->azResult to hold everything
1.57 + ** we need to remember from this invocation of the callback.
1.58 + */
1.59 + if( p->nRow==0 && argv!=0 ){
1.60 + need = nCol*2;
1.61 + }else{
1.62 + need = nCol;
1.63 + }
1.64 + if( p->nData + need >= p->nAlloc ){
1.65 + char **azNew;
1.66 + p->nAlloc = p->nAlloc*2 + need + 1;
1.67 + azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
1.68 + if( azNew==0 ) goto malloc_failed;
1.69 + p->azResult = azNew;
1.70 + }
1.71 +
1.72 + /* If this is the first row, then generate an extra row containing
1.73 + ** the names of all columns.
1.74 + */
1.75 + if( p->nRow==0 ){
1.76 + p->nColumn = nCol;
1.77 + for(i=0; i<nCol; i++){
1.78 + z = sqlite3_mprintf("%s", colv[i]);
1.79 + if( z==0 ) goto malloc_failed;
1.80 + p->azResult[p->nData++] = z;
1.81 + }
1.82 + }else if( p->nColumn!=nCol ){
1.83 + sqlite3_free(p->zErrMsg);
1.84 + p->zErrMsg = sqlite3_mprintf(
1.85 + "sqlite3_get_table() called with two or more incompatible queries"
1.86 + );
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 +
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 ){
1.147 + db->errCode = SQLITE_NOMEM;
1.148 + return SQLITE_NOMEM;
1.149 + }
1.150 + res.azResult[0] = 0;
1.151 + rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
1.152 + assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
1.153 + res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
1.154 + if( (rc&0xff)==SQLITE_ABORT ){
1.155 + sqlite3_free_table(&res.azResult[1]);
1.156 + if( res.zErrMsg ){
1.157 + if( pzErrMsg ){
1.158 + sqlite3_free(*pzErrMsg);
1.159 + *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
1.160 + }
1.161 + sqlite3_free(res.zErrMsg);
1.162 + }
1.163 + db->errCode = res.rc; /* Assume 32-bit assignment is atomic */
1.164 + return res.rc;
1.165 + }
1.166 + sqlite3_free(res.zErrMsg);
1.167 + if( rc!=SQLITE_OK ){
1.168 + sqlite3_free_table(&res.azResult[1]);
1.169 + return rc;
1.170 + }
1.171 + if( res.nAlloc>res.nData ){
1.172 + char **azNew;
1.173 + azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
1.174 + if( azNew==0 ){
1.175 + sqlite3_free_table(&res.azResult[1]);
1.176 + db->errCode = SQLITE_NOMEM;
1.177 + return SQLITE_NOMEM;
1.178 + }
1.179 + res.nAlloc = res.nData+1;
1.180 + res.azResult = azNew;
1.181 + }
1.182 + *pazResult = &res.azResult[1];
1.183 + if( pnColumn ) *pnColumn = res.nColumn;
1.184 + if( pnRow ) *pnRow = res.nRow;
1.185 + return rc;
1.186 +}
1.187 +
1.188 +/*
1.189 +** This routine frees the space the sqlite3_get_table() malloced.
1.190 +*/
1.191 +void sqlite3_free_table(
1.192 + char **azResult /* Result returned from from sqlite3_get_table() */
1.193 +){
1.194 + if( azResult ){
1.195 + int i, n;
1.196 + azResult--;
1.197 + assert( azResult!=0 );
1.198 + n = SQLITE_PTR_TO_INT(azResult[0]);
1.199 + for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
1.200 + sqlite3_free(azResult);
1.201 + }
1.202 +}
1.203 +
1.204 +#endif /* SQLITE_OMIT_GET_TABLE */