File Coverage

table.c
Criterion Covered Total %
statement 0 88 0.0
branch 0 60 0.0
condition n/a
subroutine n/a
pod n/a
total 0 148 0.0


line stmt bran cond sub pod time code
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 sqlite_get_table() and sqlite_free_table()
13             ** interface routines. These are just wrappers around the main
14             ** interface routine of sqlite_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
20             #include
21             #include "sqliteInt.h"
22              
23             /*
24             ** This structure is used to pass data from sqlite_get_table() through
25             ** to the callback function is uses to build the result.
26             */
27             typedef struct TabResult {
28             char **azResult;
29             char *zErrMsg;
30             int nResult;
31             int nAlloc;
32             int nRow;
33             int nColumn;
34             long nData;
35             int rc;
36             } TabResult;
37              
38             /*
39             ** This routine is called once for each row in the result table. Its job
40             ** is to fill in the TabResult structure appropriately, allocating new
41             ** memory as necessary.
42             */
43 0           static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
44 0           TabResult *p = (TabResult*)pArg;
45             int need;
46             int i;
47             char *z;
48              
49             /* Make sure there is enough space in p->azResult to hold everything
50             ** we need to remember from this invocation of the callback.
51             */
52 0 0         if( p->nRow==0 && argv!=0 ){
    0          
53 0           need = nCol*2;
54             }else{
55 0           need = nCol;
56             }
57 0 0         if( p->nData + need >= p->nAlloc ){
58             char **azNew;
59 0           p->nAlloc = p->nAlloc*2 + need + 1;
60 0           azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
61 0 0         if( azNew==0 ){
62 0           p->rc = SQLITE_NOMEM;
63 0           return 1;
64             }
65 0           p->azResult = azNew;
66             }
67              
68             /* If this is the first row, then generate an extra row containing
69             ** the names of all columns.
70             */
71 0 0         if( p->nRow==0 ){
72 0           p->nColumn = nCol;
73 0 0         for(i=0; i
74 0 0         if( colv[i]==0 ){
75 0           z = 0;
76             }else{
77 0           z = malloc( strlen(colv[i])+1 );
78 0 0         if( z==0 ){
79 0           p->rc = SQLITE_NOMEM;
80 0           return 1;
81             }
82 0           strcpy(z, colv[i]);
83             }
84 0           p->azResult[p->nData++] = z;
85             }
86 0 0         }else if( p->nColumn!=nCol ){
87 0           sqliteSetString(&p->zErrMsg,
88             "sqlite_get_table() called with two or more incompatible queries",
89             (char*)0);
90 0           p->rc = SQLITE_ERROR;
91 0           return 1;
92             }
93              
94             /* Copy over the row data
95             */
96 0 0         if( argv!=0 ){
97 0 0         for(i=0; i
98 0 0         if( argv[i]==0 ){
99 0           z = 0;
100             }else{
101 0           z = malloc( strlen(argv[i])+1 );
102 0 0         if( z==0 ){
103 0           p->rc = SQLITE_NOMEM;
104 0           return 1;
105             }
106 0           strcpy(z, argv[i]);
107             }
108 0           p->azResult[p->nData++] = z;
109             }
110 0           p->nRow++;
111             }
112 0           return 0;
113             }
114              
115             /*
116             ** Query the database. But instead of invoking a callback for each row,
117             ** malloc() for space to hold the result and return the entire results
118             ** at the conclusion of the call.
119             **
120             ** The result that is written to ***pazResult is held in memory obtained
121             ** from malloc(). But the caller cannot free this memory directly.
122             ** Instead, the entire table should be passed to sqlite_free_table() when
123             ** the calling procedure is finished using it.
124             */
125 0           int sqlite_get_table(
126             sqlite *db, /* The database on which the SQL executes */
127             const char *zSql, /* The SQL to be executed */
128             char ***pazResult, /* Write the result table here */
129             int *pnRow, /* Write the number of rows in the result here */
130             int *pnColumn, /* Write the number of columns of result here */
131             char **pzErrMsg /* Write error messages here */
132             ){
133             int rc;
134             TabResult res;
135 0 0         if( pazResult==0 ){ return SQLITE_ERROR; }
136 0           *pazResult = 0;
137 0 0         if( pnColumn ) *pnColumn = 0;
138 0 0         if( pnRow ) *pnRow = 0;
139 0           res.zErrMsg = 0;
140 0           res.nResult = 0;
141 0           res.nRow = 0;
142 0           res.nColumn = 0;
143 0           res.nData = 1;
144 0           res.nAlloc = 20;
145 0           res.rc = SQLITE_OK;
146 0           res.azResult = malloc( sizeof(char*)*res.nAlloc );
147 0 0         if( res.azResult==0 ){
148 0           return SQLITE_NOMEM;
149             }
150 0           res.azResult[0] = 0;
151 0           rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
152 0 0         if( res.azResult ){
153 0           res.azResult[0] = (char*)res.nData;
154             }
155 0 0         if( rc==SQLITE_ABORT ){
156 0           sqlite_free_table(&res.azResult[1]);
157 0 0         if( res.zErrMsg ){
158 0 0         if( pzErrMsg ){
159 0           free(*pzErrMsg);
160 0           *pzErrMsg = res.zErrMsg;
161             sqliteStrRealloc(pzErrMsg);
162             }else{
163 0           sqliteFree(res.zErrMsg);
164             }
165             }
166 0           return res.rc;
167             }
168 0           sqliteFree(res.zErrMsg);
169 0 0         if( rc!=SQLITE_OK ){
170 0           sqlite_free_table(&res.azResult[1]);
171 0           return rc;
172             }
173 0 0         if( res.nAlloc>res.nData ){
174             char **azNew;
175 0           azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
176 0 0         if( azNew==0 ){
177 0           sqlite_free_table(&res.azResult[1]);
178 0           return SQLITE_NOMEM;
179             }
180 0           res.nAlloc = res.nData+1;
181 0           res.azResult = azNew;
182             }
183 0           *pazResult = &res.azResult[1];
184 0 0         if( pnColumn ) *pnColumn = res.nColumn;
185 0 0         if( pnRow ) *pnRow = res.nRow;
186 0           return rc;
187             }
188              
189             /*
190             ** This routine frees the space the sqlite_get_table() malloced.
191             */
192 0           void sqlite_free_table(
193             char **azResult /* Result returned from from sqlite_get_table() */
194             ){
195 0 0         if( azResult ){
196             int i, n;
197 0           azResult--;
198 0 0         if( azResult==0 ) return;
199 0           n = (int)(long)azResult[0];
200 0 0         for(i=1; i
    0          
201 0           free(azResult);
202             }
203             }