Annotation of embedaddon/php/ext/sqlite/libsqlite/src/table.c, revision 1.1.1.1
1.1 misho 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: */
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: static 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: */
125: 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: 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: */
192: void 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>