wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3  
4 using i64 = System.Int64;
5  
6 namespace Community.CsharpSqlite
7 {
8 public partial class Sqlite3
9 {
10 /*
11 ** 2001 September 15
12 **
13 ** The author disclaims copyright to this source code. In place of
14 ** a legal notice, here is a blessing:
15 **
16 ** May you do good and not evil.
17 ** May you find forgiveness for yourself and forgive others.
18 ** May you share freely, never taking more than you give.
19 **
20 *************************************************************************
21 ** This file contains the sqlite3_get_table() and //sqlite3_free_table()
22 ** interface routines. These are just wrappers around the main
23 ** interface routine of sqlite3_exec().
24 **
25 ** These routines are in a separate files so that they will not be linked
26 ** if they are not used.
27 *************************************************************************
28 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
29 ** C#-SQLite is an independent reimplementation of the SQLite software library
30 **
31 ** SQLITE_SOURCE_ID: 2010-08-23 18:52:01 42537b60566f288167f1b5864a5435986838e3a3
32 **
33 *************************************************************************
34 */
35 //#include "sqliteInt.h"
36 //#include <stdlib.h>
37 //#include <string.h>
38  
39 #if !SQLITE_OMIT_GET_TABLE
40  
41 /*
42 ** This structure is used to pass data from sqlite3_get_table() through
43 ** to the callback function is uses to build the result.
44 */
45 class TabResult {
46 public string[] azResult;
47 public string zErrMsg;
48 public int nResult;
49 public int nAlloc;
50 public int nRow;
51 public int nColumn;
52 public int nData;
53 public int rc;
54 };
55  
56 /*
57 ** This routine is called once for each row in the result table. Its job
58 ** is to fill in the TabResult structure appropriately, allocating new
59 ** memory as necessary.
60 */
61 static public int sqlite3_get_table_cb( object pArg, i64 nCol, object Oargv, object Ocolv )
62 {
63 string[] argv = (string[])Oargv;
64 string[]colv = (string[])Ocolv;
65 TabResult p = (TabResult)pArg;
66 int need;
67 int i;
68 string z;
69  
70 /* Make sure there is enough space in p.azResult to hold everything
71 ** we need to remember from this invocation of the callback.
72 */
73 if( p.nRow==0 && argv!=null ){
74 need = (int)nCol*2;
75 }else{
76 need = (int)nCol;
77 }
78 if( p.nData + need >= p.nAlloc ){
79 string[] azNew;
80 p.nAlloc = p.nAlloc*2 + need + 1;
81 azNew = new string[p.nAlloc];//sqlite3_realloc( p.azResult, sizeof(char*)*p.nAlloc );
82 if( azNew==null ) goto malloc_failed;
83 p.azResult = azNew;
84 }
85  
86 /* If this is the first row, then generate an extra row containing
87 ** the names of all columns.
88 */
89 if( p.nRow==0 ){
90 p.nColumn = (int)nCol;
91 for(i=0; i<nCol; i++){
92 z = sqlite3_mprintf("%s", colv[i]);
93 if( z==null ) goto malloc_failed;
94 p.azResult[p.nData++ -1] = z;
95 }
96 }else if( p.nColumn!=nCol ){
97 //sqlite3_free(ref p.zErrMsg);
98 p.zErrMsg = sqlite3_mprintf(
99 "sqlite3_get_table() called with two or more incompatible queries"
100 );
101 p.rc = SQLITE_ERROR;
102 return 1;
103 }
104  
105 /* Copy over the row data
106 */
107 if( argv!=null ){
108 for(i=0; i<nCol; i++){
109 if( argv[i]==null ){
110 z = null;
111 }else{
112 int n = sqlite3Strlen30(argv[i])+1;
113 //z = sqlite3_malloc( n );
114 //if( z==0 ) goto malloc_failed;
115 z= argv[i];//memcpy(z, argv[i], n);
116 }
117 p.azResult[p.nData++ -1] = z;
118 }
119 p.nRow++;
120 }
121 return 0;
122  
123 malloc_failed:
124 p.rc = SQLITE_NOMEM;
125 return 1;
126 }
127  
128 /*
129 ** Query the database. But instead of invoking a callback for each row,
130 ** malloc() for space to hold the result and return the entire results
131 ** at the conclusion of the call.
132 **
133 ** The result that is written to ***pazResult is held in memory obtained
134 ** from malloc(). But the caller cannot free this memory directly.
135 ** Instead, the entire table should be passed to //sqlite3_free_table() when
136 ** the calling procedure is finished using it.
137 */
138 static public int sqlite3_get_table(
139 sqlite3 db, /* The database on which the SQL executes */
140 string zSql, /* The SQL to be executed */
141 ref string[] pazResult, /* Write the result table here */
142 ref int pnRow, /* Write the number of rows in the result here */
143 ref int pnColumn, /* Write the number of columns of result here */
144 ref string pzErrMsg /* Write error messages here */
145 ){
146 int rc;
147 TabResult res = new TabResult();
148  
149 pazResult = null;
150 pnColumn = 0;
151 pnRow = 0;
152 pzErrMsg = string.Empty;
153 res.zErrMsg = string.Empty;
154 res.nResult = 0;
155 res.nRow = 0;
156 res.nColumn = 0;
157 res.nData = 1;
158 res.nAlloc = 20;
159 res.rc = SQLITE_OK;
160 res.azResult = new string[res.nAlloc];// sqlite3_malloc( sizeof( char* ) * res.nAlloc );
161 if( res.azResult==null ){
162 db.errCode = SQLITE_NOMEM;
163 return SQLITE_NOMEM;
164 }
165 res.azResult[0] = null;
166 rc = sqlite3_exec(db, zSql, (dxCallback) sqlite3_get_table_cb, res, ref pzErrMsg);
167 //Debug.Assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
168 //res.azResult = SQLITE_INT_TO_PTR( res.nData );
169 if( (rc&0xff)==SQLITE_ABORT ){
170 //sqlite3_free_table(ref res.azResult[1] );
171 if( res.zErrMsg.Length > 0){
172 if( pzErrMsg != null ){
173 //sqlite3_free(ref pzErrMsg);
174 pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
175 }
176 //sqlite3_free(ref res.zErrMsg);
177 }
178 db.errCode = res.rc; /* Assume 32-bit assignment is atomic */
179 return res.rc;
180 }
181 //sqlite3_free(ref res.zErrMsg);
182 if( rc!=SQLITE_OK ){
183 //sqlite3_free_table(ref res.azResult[1]);
184 return rc;
185 }
186 if( res.nAlloc>res.nData ){
187 string[] azNew;
188 Array.Resize(ref res.azResult, res.nData-1);//sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
189 //if( azNew==null ){
190 // //sqlite3_free_table(ref res.azResult[1]);
191 // db.errCode = SQLITE_NOMEM;
192 // return SQLITE_NOMEM;
193 //}
194 res.nAlloc = res.nData+1;
195 //res.azResult = azNew;
196 }
197 pazResult = res.azResult;
198 pnColumn = res.nColumn;
199 pnRow = res.nRow;
200 return rc;
201 }
202  
203 /*
204 ** This routine frees the space the sqlite3_get_table() malloced.
205 */
206 static void //sqlite3_free_table(
207 ref string azResult /* Result returned from from sqlite3_get_table() */
208 ){
209 if( azResult !=null){
210 int i, n;
211 //azResult--;
212 //Debug.Assert( azResult!=0 );
213 //n = SQLITE_PTR_TO_INT(azResult[0]);
214 //for(i=1; i<n; i++){ if( azResult[i] ) //sqlite3_free(azResult[i]); }
215 //sqlite3_free(ref azResult);
216 }
217 }
218  
219 #endif //* SQLITE_OMIT_GET_TABLE */
220 }
221 }