source: trunk/src/3rdparty/sqlite/table.c@ 205

Last change on this file since 205 was 205, checked in by rudi, 14 years ago

Added SQLite 2.8.17 sources. This allows to build at least one of the sql drivers / plugins.

File size: 5.3 KB
Line 
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 <stdlib.h>
20#include <string.h>
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*/
27typedef 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*/
43static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
44 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 if( p->nRow==0 && argv!=0 ){
53 need = nCol*2;
54 }else{
55 need = nCol;
56 }
57 if( p->nData + need >= p->nAlloc ){
58 char **azNew;
59 p->nAlloc = p->nAlloc*2 + need + 1;
60 azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
61 if( azNew==0 ){
62 p->rc = SQLITE_NOMEM;
63 return 1;
64 }
65 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 if( p->nRow==0 ){
72 p->nColumn = nCol;
73 for(i=0; i<nCol; i++){
74 if( colv[i]==0 ){
75 z = 0;
76 }else{
77 z = malloc( strlen(colv[i])+1 );
78 if( z==0 ){
79 p->rc = SQLITE_NOMEM;
80 return 1;
81 }
82 strcpy(z, colv[i]);
83 }
84 p->azResult[p->nData++] = z;
85 }
86 }else if( p->nColumn!=nCol ){
87 sqliteSetString(&p->zErrMsg,
88 "sqlite_get_table() called with two or more incompatible queries",
89 (char*)0);
90 p->rc = SQLITE_ERROR;
91 return 1;
92 }
93
94 /* Copy over the row data
95 */
96 if( argv!=0 ){
97 for(i=0; i<nCol; i++){
98 if( argv[i]==0 ){
99 z = 0;
100 }else{
101 z = malloc( strlen(argv[i])+1 );
102 if( z==0 ){
103 p->rc = SQLITE_NOMEM;
104 return 1;
105 }
106 strcpy(z, argv[i]);
107 }
108 p->azResult[p->nData++] = z;
109 }
110 p->nRow++;
111 }
112 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*/
125int 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 if( pazResult==0 ){ return SQLITE_ERROR; }
136 *pazResult = 0;
137 if( pnColumn ) *pnColumn = 0;
138 if( pnRow ) *pnRow = 0;
139 res.zErrMsg = 0;
140 res.nResult = 0;
141 res.nRow = 0;
142 res.nColumn = 0;
143 res.nData = 1;
144 res.nAlloc = 20;
145 res.rc = SQLITE_OK;
146 res.azResult = malloc( sizeof(char*)*res.nAlloc );
147 if( res.azResult==0 ){
148 return SQLITE_NOMEM;
149 }
150 res.azResult[0] = 0;
151 rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
152 if( res.azResult ){
153 res.azResult[0] = (char*)res.nData;
154 }
155 if( rc==SQLITE_ABORT ){
156 sqlite_free_table(&res.azResult[1]);
157 if( res.zErrMsg ){
158 if( pzErrMsg ){
159 free(*pzErrMsg);
160 *pzErrMsg = res.zErrMsg;
161 sqliteStrRealloc(pzErrMsg);
162 }else{
163 sqliteFree(res.zErrMsg);
164 }
165 }
166 return res.rc;
167 }
168 sqliteFree(res.zErrMsg);
169 if( rc!=SQLITE_OK ){
170 sqlite_free_table(&res.azResult[1]);
171 return rc;
172 }
173 if( res.nAlloc>res.nData ){
174 char **azNew;
175 azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
176 if( azNew==0 ){
177 sqlite_free_table(&res.azResult[1]);
178 return SQLITE_NOMEM;
179 }
180 res.nAlloc = res.nData+1;
181 res.azResult = azNew;
182 }
183 *pazResult = &res.azResult[1];
184 if( pnColumn ) *pnColumn = res.nColumn;
185 if( pnRow ) *pnRow = res.nRow;
186 return rc;
187}
188
189/*
190** This routine frees the space the sqlite_get_table() malloced.
191*/
192void sqlite_free_table(
193 char **azResult /* Result returned from from sqlite_get_table() */
194){
195 if( azResult ){
196 int i, n;
197 azResult--;
198 if( azResult==0 ) return;
199 n = (int)(long)azResult[0];
200 for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
201 free(azResult);
202 }
203}
Note: See TracBrowser for help on using the repository browser.