wasCSharpSQLite – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Text; |
||
4 | |||
5 | namespace Community.CsharpSqlite |
||
6 | { |
||
7 | using sqlite3_value = Sqlite3.Mem; |
||
8 | |||
9 | public partial class Sqlite3 |
||
10 | { |
||
11 | /* |
||
12 | ** 2008 June 18 |
||
13 | ** |
||
14 | ** The author disclaims copyright to this source code. In place of |
||
15 | ** a legal notice, here is a blessing: |
||
16 | ** |
||
17 | ** May you do good and not evil. |
||
18 | ** May you find forgiveness for yourself and forgive others. |
||
19 | ** May you share freely, never taking more than you give. |
||
20 | ** |
||
21 | ************************************************************************* |
||
22 | ** |
||
23 | ** This module implements the sqlite3_status() interface and related |
||
24 | ** functionality. |
||
25 | ************************************************************************* |
||
26 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
27 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
28 | ** |
||
29 | ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e |
||
30 | ** |
||
31 | ************************************************************************* |
||
32 | */ |
||
33 | //#include "sqliteInt.h" |
||
34 | //#include "vdbeInt.h" |
||
35 | |||
36 | /* |
||
37 | ** Variables in which to record status information. |
||
38 | */ |
||
39 | //typedef struct sqlite3StatType sqlite3StatType; |
||
40 | public class sqlite3StatType |
||
41 | { |
||
42 | public int[] nowValue = new int[10]; /* Current value */ |
||
43 | public int[] mxValue = new int[10]; /* Maximum value */ |
||
44 | } |
||
45 | public static sqlite3StatType sqlite3Stat = new sqlite3StatType(); |
||
46 | |||
47 | /* The "wsdStat" macro will resolve to the status information |
||
48 | ** state vector. If writable static data is unsupported on the target, |
||
49 | ** we have to locate the state vector at run-time. In the more common |
||
50 | ** case where writable static data is supported, wsdStat can refer directly |
||
51 | ** to the "sqlite3Stat" state vector declared above. |
||
52 | */ |
||
53 | #if SQLITE_OMIT_WSD |
||
54 | //# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) |
||
55 | //# define wsdStat x[0] |
||
56 | #else |
||
57 | //# define wsdStatInit |
||
58 | static void wsdStatInit() |
||
59 | { |
||
60 | } |
||
61 | //# define wsdStat sqlite3Stat |
||
62 | static sqlite3StatType wsdStat = sqlite3Stat; |
||
63 | #endif |
||
64 | |||
65 | /* |
||
66 | ** Return the current value of a status parameter. |
||
67 | */ |
||
68 | static int sqlite3StatusValue( int op ) |
||
69 | { |
||
70 | wsdStatInit(); |
||
71 | Debug.Assert( op >= 0 && op < ArraySize( wsdStat.nowValue ) ); |
||
72 | return wsdStat.nowValue[op]; |
||
73 | } |
||
74 | |||
75 | /* |
||
76 | ** Add N to the value of a status record. It is assumed that the |
||
77 | ** caller holds appropriate locks. |
||
78 | */ |
||
79 | static void sqlite3StatusAdd( int op, int N ) |
||
80 | { |
||
81 | wsdStatInit(); |
||
82 | Debug.Assert( op >= 0 && op < ArraySize( wsdStat.nowValue ) ); |
||
83 | wsdStat.nowValue[op] += N; |
||
84 | if ( wsdStat.nowValue[op] > wsdStat.mxValue[op] ) |
||
85 | { |
||
86 | wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
||
87 | } |
||
88 | } |
||
89 | |||
90 | /* |
||
91 | ** Set the value of a status to X. |
||
92 | */ |
||
93 | static void sqlite3StatusSet( int op, int X ) |
||
94 | { |
||
95 | wsdStatInit(); |
||
96 | Debug.Assert( op >= 0 && op < ArraySize( wsdStat.nowValue ) ); |
||
97 | wsdStat.nowValue[op] = X; |
||
98 | if ( wsdStat.nowValue[op] > wsdStat.mxValue[op] ) |
||
99 | { |
||
100 | wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
||
101 | } |
||
102 | } |
||
103 | |||
104 | /* |
||
105 | ** Query status information. |
||
106 | ** |
||
107 | ** This implementation assumes that reading or writing an aligned |
||
108 | ** 32-bit integer is an atomic operation. If that assumption is not true, |
||
109 | ** then this routine is not threadsafe. |
||
110 | */ |
||
111 | static int sqlite3_status( int op, ref int pCurrent, ref int pHighwater, int resetFlag ) |
||
112 | { |
||
113 | wsdStatInit(); |
||
114 | if ( op < 0 || op >= ArraySize( wsdStat.nowValue ) ) |
||
115 | { |
||
116 | return SQLITE_MISUSE_BKPT(); |
||
117 | } |
||
118 | pCurrent = wsdStat.nowValue[op]; |
||
119 | pHighwater = wsdStat.mxValue[op]; |
||
120 | if ( resetFlag != 0 ) |
||
121 | { |
||
122 | wsdStat.mxValue[op] = wsdStat.nowValue[op]; |
||
123 | } |
||
124 | return SQLITE_OK; |
||
125 | } |
||
126 | /* |
||
127 | ** Query status information for a single database connection |
||
128 | */ |
||
129 | static int sqlite3_db_status( |
||
130 | sqlite3 db, /* The database connection whose status is desired */ |
||
131 | int op, /* Status verb */ |
||
132 | ref int pCurrent, /* Write current value here */ |
||
133 | ref int pHighwater, /* Write high-water mark here */ |
||
134 | int resetFlag /* Reset high-water mark if true */ |
||
135 | ) |
||
136 | { |
||
137 | int rc = SQLITE_OK; /* Return code */ |
||
138 | sqlite3_mutex_enter( db.mutex ); |
||
139 | switch ( op ) |
||
140 | { |
||
141 | case SQLITE_DBSTATUS_LOOKASIDE_USED: |
||
142 | { |
||
143 | pCurrent = db.lookaside.nOut; |
||
144 | pHighwater = db.lookaside.mxOut; |
||
145 | if ( resetFlag != 0 ) |
||
146 | { |
||
147 | db.lookaside.mxOut = db.lookaside.nOut; |
||
148 | } |
||
149 | break; |
||
150 | } |
||
151 | case SQLITE_DBSTATUS_LOOKASIDE_HIT: |
||
152 | case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: |
||
153 | case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: |
||
154 | { |
||
155 | testcase( op == SQLITE_DBSTATUS_LOOKASIDE_HIT ); |
||
156 | testcase( op == SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); |
||
157 | testcase( op == SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); |
||
158 | Debug.Assert( ( op - SQLITE_DBSTATUS_LOOKASIDE_HIT ) >= 0 ); |
||
159 | Debug.Assert( ( op - SQLITE_DBSTATUS_LOOKASIDE_HIT ) < 3 ); |
||
160 | pCurrent = 0; |
||
161 | pHighwater = db.lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; |
||
162 | if ( resetFlag != 0 ) |
||
163 | { |
||
164 | db.lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; |
||
165 | } |
||
166 | break; |
||
167 | } |
||
168 | |||
169 | /* |
||
170 | ** Return an approximation for the amount of memory currently used |
||
171 | ** by all pagers associated with the given database connection. The |
||
172 | ** highwater mark is meaningless and is returned as zero. |
||
173 | */ |
||
174 | case SQLITE_DBSTATUS_CACHE_USED: |
||
175 | { |
||
176 | int totalUsed = 0; |
||
177 | int i; |
||
178 | sqlite3BtreeEnterAll( db ); |
||
179 | for ( i = 0; i < db.nDb; i++ ) |
||
180 | { |
||
181 | Btree pBt = db.aDb[i].pBt; |
||
182 | if ( pBt != null ) |
||
183 | { |
||
184 | Pager pPager = sqlite3BtreePager( pBt ); |
||
185 | totalUsed += sqlite3PagerMemUsed( pPager ); |
||
186 | } |
||
187 | } |
||
188 | sqlite3BtreeLeaveAll( db ); |
||
189 | pCurrent = totalUsed; |
||
190 | pHighwater = 0; |
||
191 | break; |
||
192 | } |
||
193 | |||
194 | /* |
||
195 | ** *pCurrent gets an accurate estimate of the amount of memory used |
||
196 | ** to store the schema for all databases (main, temp, and any ATTACHed |
||
197 | ** databases. *pHighwater is set to zero. |
||
198 | */ |
||
199 | case SQLITE_DBSTATUS_SCHEMA_USED: |
||
200 | { |
||
201 | int i; /* Used to iterate through schemas */ |
||
202 | int nByte = 0; /* Used to accumulate return value */ |
||
203 | |||
204 | sqlite3BtreeEnterAll( db ); |
||
205 | //db.pnBytesFreed = nByte; |
||
206 | for ( i = 0; i < db.nDb; i++ ) |
||
207 | { |
||
208 | Schema pSchema = db.aDb[i].pSchema; |
||
209 | if ( ALWAYS( pSchema != null ) ) |
||
210 | { |
||
211 | HashElem p; |
||
212 | |||
213 | //nByte += (int)(sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( |
||
214 | // pSchema.tblHash.count |
||
215 | // + pSchema.trigHash.count |
||
216 | // + pSchema.idxHash.count |
||
217 | // + pSchema.fkeyHash.count |
||
218 | //)); |
||
219 | //nByte += (int)sqlite3MallocSize( pSchema.tblHash.ht ); |
||
220 | //nByte += (int)sqlite3MallocSize( pSchema.trigHash.ht ); |
||
221 | //nByte += (int)sqlite3MallocSize( pSchema.idxHash.ht ); |
||
222 | //nByte += (int)sqlite3MallocSize( pSchema.fkeyHash.ht ); |
||
223 | |||
224 | for ( p = sqliteHashFirst( pSchema.trigHash ); p != null; p = sqliteHashNext( p ) ) |
||
225 | { |
||
226 | Trigger t = (Trigger)sqliteHashData( p ); |
||
227 | sqlite3DeleteTrigger( db, ref t ); |
||
228 | } |
||
229 | for ( p = sqliteHashFirst( pSchema.tblHash ); p != null; p = sqliteHashNext( p ) ) |
||
230 | { |
||
231 | Table t = (Table)sqliteHashData( p ); |
||
232 | sqlite3DeleteTable( db, ref t ); |
||
233 | } |
||
234 | } |
||
235 | } |
||
236 | db.pnBytesFreed = 0; |
||
237 | sqlite3BtreeLeaveAll( db ); |
||
238 | |||
239 | pHighwater = 0; |
||
240 | pCurrent = nByte; |
||
241 | break; |
||
242 | } |
||
243 | |||
244 | /* |
||
245 | ** *pCurrent gets an accurate estimate of the amount of memory used |
||
246 | ** to store all prepared statements. |
||
247 | ** *pHighwater is set to zero. |
||
248 | */ |
||
249 | case SQLITE_DBSTATUS_STMT_USED: |
||
250 | { |
||
251 | Vdbe pVdbe; /* Used to iterate through VMs */ |
||
252 | int nByte = 0; /* Used to accumulate return value */ |
||
253 | |||
254 | //db.pnBytesFreed = nByte; |
||
255 | for ( pVdbe = db.pVdbe; pVdbe != null; pVdbe = pVdbe.pNext ) |
||
256 | { |
||
257 | sqlite3VdbeDeleteObject( db, ref pVdbe ); |
||
258 | } |
||
259 | db.pnBytesFreed = 0; |
||
260 | |||
261 | pHighwater = 0; |
||
262 | pCurrent = nByte; |
||
263 | |||
264 | break; |
||
265 | } |
||
266 | |||
267 | default: |
||
268 | { |
||
269 | rc = SQLITE_ERROR; |
||
270 | break; |
||
271 | } |
||
272 | } |
||
273 | sqlite3_mutex_leave( db.mutex ); |
||
274 | return rc; |
||
275 | } |
||
276 | } |
||
277 | } |