wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3 using System.Text;
4  
5 using Bitmask = System.UInt64;
6 using u8 = System.Byte;
7 using u16 = System.UInt16;
8 using u32 = System.UInt32;
9  
10 namespace Community.CsharpSqlite
11 {
12 public partial class Sqlite3
13 {
14 /*
15 ** 2009 November 25
16 **
17 ** The author disclaims copyright to this source code. In place of
18 ** a legal notice, here is a blessing:
19 **
20 ** May you do good and not evil.
21 ** May you find forgiveness for yourself and forgive others.
22 ** May you share freely, never taking more than you give.
23 **
24 *************************************************************************
25 **
26 ** This file contains code used to insert the values of host parameters
27 ** (aka "wildcards") into the SQL text output by sqlite3_trace().
28 *************************************************************************
29 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
30 ** C#-SQLite is an independent reimplementation of the SQLite software library
31 **
32 ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e
33 **
34 *************************************************************************
35 */
36 //#include "sqliteInt.h"
37 //#include "vdbeInt.h"
38  
39 #if !SQLITE_OMIT_TRACE
40  
41 /*
42 ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
43 ** bytes in this text up to but excluding the first character in
44 ** a host parameter. If the text contains no host parameters, return
45 ** the total number of bytes in the text.
46 */
47 static int findNextHostParameter( string zSql, int iOffset, ref int pnToken )
48 {
49 int tokenType = 0;
50 int nTotal = 0;
51 int n;
52  
53 pnToken = 0;
54 while ( iOffset < zSql.Length )
55 {
56 n = sqlite3GetToken( zSql, iOffset, ref tokenType );
57 Debug.Assert( n > 0 && tokenType != TK_ILLEGAL );
58 if ( tokenType == TK_VARIABLE )
59 {
60 pnToken = n;
61 break;
62 }
63 nTotal += n;
64 iOffset += n;// zSql += n;
65 }
66 return nTotal;
67 }
68  
69 /*
70 ** This function returns a pointer to a nul-terminated string in memory
71 ** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
72 ** string contains a copy of zRawSql but with host parameters expanded to
73 ** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1,
74 ** then the returned string holds a copy of zRawSql with "-- " prepended
75 ** to each line of text.
76 **
77 ** The calling function is responsible for making sure the memory returned
78 ** is eventually freed.
79 **
80 ** ALGORITHM: Scan the input string looking for host parameters in any of
81 ** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within
82 ** string literals, quoted identifier names, and comments. For text forms,
83 ** the host parameter index is found by scanning the perpared
84 ** statement for the corresponding OP_Variable opcode. Once the host
85 ** parameter index is known, locate the value in p->aVar[]. Then render
86 ** the value as a literal in place of the host parameter name.
87 */
88 static string sqlite3VdbeExpandSql(
89 Vdbe p, /* The prepared statement being evaluated */
90 string zRawSql /* Raw text of the SQL statement */
91 )
92 {
93 sqlite3 db; /* The database connection */
94 int idx = 0; /* Index of a host parameter */
95 int nextIndex = 1; /* Index of next ? host parameter */
96 int n; /* Length of a token prefix */
97 int nToken = 0; /* Length of the parameter token */
98 int i; /* Loop counter */
99 Mem pVar; /* Value of a host parameter */
100 StrAccum _out = new StrAccum( 1000 ); /* Accumulate the _output here */
101 ////StringBuilder zBase = new StringBuilder( 100 ); /* Initial working space */
102 int izRawSql = 0;
103  
104 db = p.db;
105 sqlite3StrAccumInit( _out, null, 100,
106 db.aLimit[SQLITE_LIMIT_LENGTH] );
107 _out.db = db;
108 if ( db.vdbeExecCnt > 1 )
109 {
110 while ( izRawSql < zRawSql.Length )
111 {
112 //string zStart = zRawSql;
113 while ( zRawSql[izRawSql++] != '\n' && izRawSql < zRawSql.Length )
114 ;
115 sqlite3StrAccumAppend( _out, "-- ", 3 );
116 sqlite3StrAccumAppend( _out, zRawSql, (int)izRawSql );//zRawSql - zStart );
117 }
118 }
119 else
120 {
121 while ( izRawSql < zRawSql.Length )
122 {
123 n = findNextHostParameter( zRawSql, izRawSql, ref nToken );
124 Debug.Assert( n > 0 );
125 sqlite3StrAccumAppend( _out, zRawSql.Substring( izRawSql, n ), n );
126 izRawSql += n;
127 Debug.Assert( izRawSql < zRawSql.Length || nToken == 0 );
128 if ( nToken == 0 )
129 break;
130 if ( zRawSql[izRawSql] == '?' )
131 {
132 if ( nToken > 1 )
133 {
134 Debug.Assert( sqlite3Isdigit( zRawSql[izRawSql + 1] ) );
135 sqlite3GetInt32( zRawSql, izRawSql + 1, ref idx );
136 }
137 else
138 {
139 idx = nextIndex;
140 }
141 }
142 else
143 {
144 Debug.Assert( zRawSql[izRawSql] == ':' || zRawSql[izRawSql] == '$' || zRawSql[izRawSql] == '@' );
145 testcase( zRawSql[izRawSql] == ':' );
146 testcase( zRawSql[izRawSql] == '$' );
147 testcase( zRawSql[izRawSql] == '@' );
148 idx = sqlite3VdbeParameterIndex( p, zRawSql.Substring( izRawSql, nToken ), nToken );
149 Debug.Assert( idx > 0 );
150 }
151 izRawSql += nToken;
152 nextIndex = idx + 1;
153 Debug.Assert( idx > 0 && idx <= p.nVar );
154 pVar = p.aVar[idx - 1];
155 if ( ( pVar.flags & MEM_Null ) != 0 )
156 {
157 sqlite3StrAccumAppend( _out, "NULL", 4 );
158 }
159 else if ( ( pVar.flags & MEM_Int ) != 0 )
160 {
161 sqlite3XPrintf( _out, "%lld", pVar.u.i );
162 }
163 else if ( ( pVar.flags & MEM_Real ) != 0 )
164 {
165 sqlite3XPrintf( _out, "%!.15g", pVar.r );
166 }
167 else if ( ( pVar.flags & MEM_Str ) != 0 )
168 {
169 #if !SQLITE_OMIT_UTF16
170 u8 enc = ENC(db);
171 if( enc!=SQLITE_UTF8 ){
172 Mem utf8;
173 memset(&utf8, 0, sizeof(utf8));
174 utf8.db = db;
175 sqlite3VdbeMemSetStr(&utf8, pVar.z, pVar.n, enc, SQLITE_STATIC);
176 sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
177 sqlite3XPrintf(_out, "'%.*q'", utf8.n, utf8.z);
178 sqlite3VdbeMemRelease(&utf8);
179 }else
180 #endif
181 {
182 sqlite3XPrintf( _out, "'%.*q'", pVar.n, pVar.z );
183 }
184 }
185 else if ( ( pVar.flags & MEM_Zero ) != 0 )
186 {
187 sqlite3XPrintf( _out, "zeroblob(%d)", pVar.u.nZero );
188 }
189 else
190 {
191 Debug.Assert( ( pVar.flags & MEM_Blob ) != 0 );
192 sqlite3StrAccumAppend( _out, "x'", 2 );
193 for ( i = 0; i < pVar.n; i++ )
194 {
195 sqlite3XPrintf( _out, "%02x", pVar.zBLOB[i] & 0xff );
196 }
197 sqlite3StrAccumAppend( _out, "'", 1 );
198 }
199 }
200 }
201 return sqlite3StrAccumFinish( _out );
202 }
203  
204 #endif //* #if !SQLITE_OMIT_TRACE */
205 }
206 }