monotone

monotone Mtn Source Tree

Root/sqlite/table.c

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

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status