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