xref: /sqlite-3.40.0/src/legacy.c (revision ef5ecb41)
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 ** Main file for the SQLite library.  The routines in this file
13 ** implement the programmer interface to the library.  Routines in
14 ** other files are for internal use by SQLite and should not be
15 ** accessed by users of the library.
16 **
17 ** $Id: legacy.c,v 1.3 2004/05/26 23:25:31 drh Exp $
18 */
19 
20 #include "sqliteInt.h"
21 #include "os.h"
22 #include <ctype.h>
23 
24 /*
25 ** Execute SQL code.  Return one of the SQLITE_ success/failure
26 ** codes.  Also write an error message into memory obtained from
27 ** malloc() and make *pzErrMsg point to that message.
28 **
29 ** If the SQL is a query, then for each row in the query result
30 ** the xCallback() function is called.  pArg becomes the first
31 ** argument to xCallback().  If xCallback=NULL then no callback
32 ** is invoked, even for queries.
33 */
34 int sqlite3_exec(
35   sqlite *db,                 /* The database on which the SQL executes */
36   const char *zSql,           /* The SQL to be executed */
37   sqlite_callback xCallback,  /* Invoke this callback routine */
38   void *pArg,                 /* First argument to xCallback() */
39   char **pzErrMsg             /* Write error messages here */
40 ){
41   int rc = SQLITE_OK;
42   const char *zLeftover;
43   sqlite3_stmt *pStmt = 0;
44   char **azCols = 0;
45 
46   int nRetry = 0;
47   int nChange = 0;
48   int nCallback;
49 
50   if( zSql==0 ) return SQLITE_OK;
51   while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
52     int nCol;
53     char **azVals = 0;
54 
55     pStmt = 0;
56     rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
57     if( rc!=SQLITE_OK ){
58       if( pStmt ) sqlite3_finalize(pStmt);
59       continue;
60     }
61     if( !pStmt ){
62       /* this happens for a comment or white-space */
63       zSql = zLeftover;
64       continue;
65     }
66 
67     db->nChange += nChange;
68     nCallback = 0;
69 
70     nCol = sqlite3_column_count(pStmt);
71     azCols = sqliteMalloc(2*nCol*sizeof(const char *));
72     if( nCol && !azCols ){
73       rc = SQLITE_NOMEM;
74       goto exec_out;
75     }
76 
77     while( 1 ){
78       int i;
79       rc = sqlite3_step(pStmt);
80 
81       /* Invoke the callback function if required */
82       if( xCallback && (SQLITE_ROW==rc ||
83           (SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){
84         if( 0==nCallback ){
85           for(i=0; i<nCol; i++){
86             azCols[i] = (char *)sqlite3_column_name(pStmt, i);
87           }
88           nCallback++;
89         }
90         if( rc==SQLITE_ROW ){
91           azVals = &azCols[nCol];
92           for(i=0; i<nCol; i++){
93             azVals[i] = (char *)sqlite3_column_text(pStmt, i);
94           }
95         }
96         if( xCallback(pArg, nCol, azVals, azCols) ){
97           rc = SQLITE_ABORT;
98           goto exec_out;
99         }
100       }
101 
102       if( rc!=SQLITE_ROW ){
103         rc = sqlite3_finalize(pStmt);
104         pStmt = 0;
105         if( db->pVdbe==0 ){
106           nChange = db->nChange;
107         }
108         if( rc!=SQLITE_SCHEMA ){
109           nRetry = 0;
110           zSql = zLeftover;
111           while( isspace(zSql[0]) ) zSql++;
112         }
113         break;
114       }
115     }
116 
117     sqliteFree(azCols);
118     azCols = 0;
119   }
120 
121 exec_out:
122   if( pStmt ) sqlite3_finalize(pStmt);
123   if( azCols ) sqliteFree(azCols);
124 
125   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
126     *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
127     if( *pzErrMsg ){
128       strcpy(*pzErrMsg, sqlite3_errmsg(db));
129     }
130   }else if( pzErrMsg ){
131     *pzErrMsg = 0;
132   }
133 
134   return rc;
135 }
136