xref: /sqlite-3.40.0/src/table.c (revision 7c68d60b)
1 /*
2 ** This file contains the sqlite_get_table() and sqlite_free_table()
3 ** interface routines.  These are just wrappers around the main
4 ** interface routine of sqlite_exec().
5 **
6 ** This routines are in a separate files to that they will not be linked
7 ** if they are not used.
8 */
9 #include <stdlib.h>
10 #include "sqlite.h"
11 
12 /*
13 ** This structure is used to pass data from sqlite_get_table() through
14 ** to the callback function is uses to build the result.
15 */
16 typedef struct TabResult {
17   char **azResult;
18   int nResult;
19   int nAlloc;
20   int nRow;
21   int nColumn;
22   int nData;
23   int rc;
24 } TabResult;
25 
26 /*
27 ** This routine is called once for each row in the result table.  Its job
28 ** is to fill in the TabResult structure appropriately, allocating new
29 ** memory as necessary.
30 */
31 static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
32   TabResult *p = (TabResult*)pArg;
33   int need;
34   int i;
35   char *z;
36 
37   /* Make sure there is enough space in p->azResult to hold everything
38   ** we need to remember from this invocation of the callback.
39   */
40   if( p->nRow==0 ){
41     p->nColumn = nCol;
42     need = nCol*2;
43   }else{
44     need = nCol;
45   }
46   if( p->nData + need >= p->nAlloc ){
47     p->nAlloc = p->nAlloc*2 + need + 1;
48     p->azResult = realloc( p->azResult, sizeof(char*)*p->nAlloc );
49     if( p->azResult==0 ){
50       p->rc = SQLITE_NOMEM;
51       return 1;
52     }
53   }
54 
55   /* If this is the first row, then generate an extra row containing
56   ** the names of all columns.
57   */
58   if( p->nRow==0 ){
59     for(i=0; i<nCol; i++){
60       if( colv[i]==0 ){
61         z = 0;
62       }else{
63         z = malloc( strlen(colv[i])+1 );
64         if( z==0 ){
65           p->rc = SQLITE_NOMEM;
66           return 1;
67         }
68         strcpy(z, colv[i]);
69       }
70       p->azResult[p->nData++] = z;
71     }
72   }
73 
74   /* Copy over the row data
75   */
76   for(i=0; i<nCol; i++){
77     if( argv[i]==0 ){
78       z = 0;
79     }else{
80       z = malloc( strlen(argv[i])+1 );
81       if( z==0 ){
82         p->rc = SQLITE_NOMEM;
83         return 1;
84       }
85       strcpy(z, argv[i]);
86     }
87     p->azResult[p->nData++] = z;
88   }
89   p->nRow++;
90   return 0;
91 }
92 
93 /*
94 ** Query the database.  But instead of invoking a callback for each row,
95 ** malloc() for space to hold the result and return the entire results
96 ** at the conclusion of the call.
97 **
98 ** The result that is written to ***pazResult is held in memory obtained
99 ** from malloc().  But the caller cannot free this memory directly.
100 ** Instead, the entire table should be passed to sqlite_free_table() when
101 ** the calling procedure is finished using it.
102 */
103 int sqlite_get_table(
104   sqlite *db,                 /* The database on which the SQL executes */
105   char *zSql,                 /* The SQL to be executed */
106   char ***pazResult,          /* Write the result table here */
107   int *pnRow,                 /* Write the number of rows in the result here */
108   int *pnColumn,              /* Write the number of columns of result here */
109   char **pzErrMsg             /* Write error messages here */
110 ){
111   int rc;
112   TabResult res;
113   if( pazResult==0 ){ return SQLITE_ERROR; }
114   *pazResult = 0;
115   if( pnColumn ) *pnColumn = 0;
116   if( pnRow ) *pnRow = 0;
117   res.nResult = 0;
118   res.nRow = 0;
119   res.nColumn = 0;
120   res.nData = 1;
121   res.nAlloc = 200;
122   res.rc = SQLITE_OK;
123   res.azResult = malloc( sizeof(char*)*res.nAlloc );
124   if( res.azResult==0 ){
125     return SQLITE_NOMEM;
126   }
127   res.azResult[0] = 0;
128   rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
129   if( res.azResult ){
130     res.azResult[0] = (char*)res.nData;
131   }
132   if( rc==SQLITE_ABORT ){
133     sqlite_free_table(&res.azResult[1]);
134     return res.rc;
135   }
136   if( rc!=SQLITE_OK ){
137     sqlite_free_table(&res.azResult[1]);
138     return rc;
139   }
140   if( res.nAlloc>res.nData ){
141     res.azResult = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
142     if( res.azResult==0 ) return SQLITE_NOMEM;
143   }
144   *pazResult = &res.azResult[1];
145   if( pnColumn ) *pnColumn = res.nColumn;
146   if( pnRow ) *pnRow = res.nRow;
147   return rc;
148 }
149 
150 /*
151 ** This routine frees the space the sqlite_get_table() malloced.
152 */
153 void sqlite_free_table(
154   char **azResult             /* Result returned from from sqlite_get_table() */
155 ){
156   if( azResult ){
157     int i, n;
158     azResult--;
159     n = (int)azResult[0];
160     for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
161     free(azResult);
162   }
163 }
164