wasCSharpSQLite – Blame information for rev
?pathlinks?
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 | } |