public string ExpandSql(string rawSql) { Context ctx = Ctx; // The database connection TextBuilder b = new TextBuilder(); // Accumulate the _output here TextBuilder.Init(b, 100, ctx.Limits[(int)LIMIT.LENGTH]); b.Tag = ctx; int rawSqlIdx = 0; int nextIndex = 1; // Index of next ? host parameter int idx = 0; // Index of a host parameter if (ctx.VdbeExecCnt > 1) while (rawSqlIdx < rawSql.Length) { while (rawSql[rawSqlIdx++] != '\n' && rawSqlIdx < rawSql.Length) ; b.Append("-- ", 3); b.Append(rawSql, (int)rawSqlIdx); } else while (rawSqlIdx < rawSql.Length) { int tokenLength = 0; // Length of the parameter token int n = FindNextHostParameter(rawSql, rawSqlIdx, ref tokenLength); // Length of a token prefix Debug.Assert(n > 0); b.Append(rawSql.Substring(rawSqlIdx, n), n); rawSqlIdx += n; Debug.Assert(rawSqlIdx < rawSql.Length || tokenLength == 0); if (tokenLength == 0) break; if (rawSql[rawSqlIdx] == '?') { if (tokenLength > 1) { Debug.Assert(char.IsDigit(rawSql[rawSqlIdx + 1])); ConvertEx.Atoi(rawSql, rawSqlIdx + 1, ref idx); } else idx = nextIndex; } else { Debug.Assert(rawSql[rawSqlIdx] == ':' || rawSql[rawSqlIdx] == '$' || rawSql[rawSqlIdx] == '@'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == ':'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == '$'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == '@'); idx = ParameterIndex(this, rawSql.Substring(rawSqlIdx, tokenLength), tokenLength); Debug.Assert(idx > 0); } rawSqlIdx += tokenLength; nextIndex = idx + 1; Debug.Assert(idx > 0 && idx <= Vars.length); Mem var = Vars[idx - 1]; // Value of a host parameter if ((var.Flags & MEM.Null) != 0) b.Append("NULL", 4); else if ((var.Flags & MEM.Int) != 0) b.AppendFormat("%lld", var.u.I); else if ((var.Flags & MEM.Real) != 0) b.AppendFormat("%!.15g", var.R); else if ((var.Flags & MEM.Str) != 0) { #if !OMIT_UTF16 TEXTENCODE encode = E.CTXENCODE(ctx); if (encode != TEXTENCODE.UTF8) { Mem utf8; //C._memset(&utf8, 0, sizeof(utf8)); utf8.Ctx = ctx; MemSetStr(utf8, var.Z, var.N, encode, C.DESTRUCTOR_STATIC); ChangeEncoding(utf8, TEXTENCODE.UTF8); b.AppendFormat("'%.*q'", utf8.N, utf8.Z); MemRelease(utf8); } else #endif b.AppendFormat("'%.*q'", var.N, var.Z); } else if ((var.Flags & MEM.Zero) != 0) b.AppendFormat("zeroblob(%d)", var.u.Zeros); else { Debug.Assert((var.Flags & MEM.Blob) != 0); b.Append("x'", 2); for (int i = 0; i < var.N; i++) b.AppendFormat("%02x", var.u.Zeros[i] & 0xff); b.Append("'", 1); } } return b.ToString(); }
private static void AppendOperand(TextBuilder text, OperandType operandType, object operand) { text.Append(' '); switch (operandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: { if (operand is Instruction opInst) { AppendLabel(text, opInst); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineSwitch: { if (operand is Instruction[] labels) { text.AppendDelimit(',', labels, AppendLabel !); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineString: { if (!(operand is string str)) { str = operand.ToString() ?? string.Empty; } text.Append('"') .Append(str) .Append('"'); break; } case OperandType.InlineField: { if (operand is FieldInfo field) { text.AppendDump(field); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineI: case OperandType.ShortInlineI: { if (operand is IntPtr intPtr) { text.AppendFormat(intPtr, "X"); } else if (operand is int integer) { text.Append(integer); } else if (operand is sbyte signedByte) { text.Append(signedByte); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineI8: { if (operand is byte b) { text.Append(b) .Append('b'); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineMethod: { if (operand is MethodBase methodBase) { text.AppendDump(methodBase); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineR: case OperandType.ShortInlineR: { if (operand is float f) { text.Append(f) .Append('f'); } else if (operand is double d) { text.Append(d) .Append('d'); } else if (operand is decimal m) { text.Append(m) .Append('m'); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineType: { if (operand is Type type) { text.AppendDump(type); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineTok: { if (operand is MemberInfo member) { text.AppendDump(member); } else { throw new InvalidOperationException(); } break; } case OperandType.InlineVar: case OperandType.ShortInlineVar: { // Variables? text.AppendDump(operand); break; } case OperandType.InlineNone: //case OperandType.InlinePhi: case OperandType.InlineSig: default: { Hold.Debug(operandType, operand); text.Append(operand); break; } } }
public string ExpandSql(string rawSql) { Context ctx = Ctx; // The database connection TextBuilder b = new TextBuilder(); // Accumulate the _output here TextBuilder.Init(b, 100, ctx.Limits[(int)LIMIT.LENGTH]); b.Tag = ctx; int rawSqlIdx = 0; int nextIndex = 1; // Index of next ? host parameter int idx = 0; // Index of a host parameter if (ctx.VdbeExecCnt > 1) { while (rawSqlIdx < rawSql.Length) { while (rawSql[rawSqlIdx++] != '\n' && rawSqlIdx < rawSql.Length) { ; } b.Append("-- ", 3); b.Append(rawSql, (int)rawSqlIdx); } } else { while (rawSqlIdx < rawSql.Length) { int tokenLength = 0; // Length of the parameter token int n = FindNextHostParameter(rawSql, rawSqlIdx, ref tokenLength); // Length of a token prefix Debug.Assert(n > 0); b.Append(rawSql.Substring(rawSqlIdx, n), n); rawSqlIdx += n; Debug.Assert(rawSqlIdx < rawSql.Length || tokenLength == 0); if (tokenLength == 0) { break; } if (rawSql[rawSqlIdx] == '?') { if (tokenLength > 1) { Debug.Assert(char.IsDigit(rawSql[rawSqlIdx + 1])); ConvertEx.Atoi(rawSql, rawSqlIdx + 1, ref idx); } else { idx = nextIndex; } } else { Debug.Assert(rawSql[rawSqlIdx] == ':' || rawSql[rawSqlIdx] == '$' || rawSql[rawSqlIdx] == '@'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == ':'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == '$'); C.ASSERTCOVERAGE(rawSql[rawSqlIdx] == '@'); idx = ParameterIndex(this, rawSql.Substring(rawSqlIdx, tokenLength), tokenLength); Debug.Assert(idx > 0); } rawSqlIdx += tokenLength; nextIndex = idx + 1; Debug.Assert(idx > 0 && idx <= Vars.length); Mem var = Vars[idx - 1]; // Value of a host parameter if ((var.Flags & MEM.Null) != 0) { b.Append("NULL", 4); } else if ((var.Flags & MEM.Int) != 0) { b.AppendFormat("%lld", var.u.I); } else if ((var.Flags & MEM.Real) != 0) { b.AppendFormat("%!.15g", var.R); } else if ((var.Flags & MEM.Str) != 0) { #if !OMIT_UTF16 TEXTENCODE encode = E.CTXENCODE(ctx); if (encode != TEXTENCODE.UTF8) { Mem utf8; //C._memset(&utf8, 0, sizeof(utf8)); utf8.Ctx = ctx; MemSetStr(utf8, var.Z, var.N, encode, C.DESTRUCTOR_STATIC); ChangeEncoding(utf8, TEXTENCODE.UTF8); b.AppendFormat("'%.*q'", utf8.N, utf8.Z); MemRelease(utf8); } else #endif b.AppendFormat("'%.*q'", var.N, var.Z); } else if ((var.Flags & MEM.Zero) != 0) { b.AppendFormat("zeroblob(%d)", var.u.Zeros); } else { Debug.Assert((var.Flags & MEM.Blob) != 0); b.Append("x'", 2); for (int i = 0; i < var.N; i++) { b.AppendFormat("%02x", var.u.Zeros[i] & 0xff); } b.Append("'", 1); } } } return(b.ToString()); }