internal static FieldDataType GetFieldDataType(Type type, out bool nullable) { // make sure booleans returned as BooleanAsInteger instead of the more problematic Boolean if (type == typeof(bool)) { nullable = false; return(FieldDataType.BooleanAsInteger); } if (type == typeof(bool?) || type == typeof(SqlBoolean)) { nullable = true; return(FieldDataType.BooleanAsInteger); } for (int i = 0; i < _nullableHandlers.Length; i++) { SoodaFieldHandler handler = _nullableHandlers[i]; if (type == handler.GetFieldType()) { nullable = false; return((FieldDataType)i); } if (type == handler.GetNullableType() || type == handler.GetSqlType()) { nullable = true; return((FieldDataType)i); } } throw new ArgumentException("Unknown Sooda type for " + type); }
public void BuildCommandWithParameters(System.Data.IDbCommand command, bool append, string query, object[] par, bool isRaw) { if (append) { if (command.CommandText == null) { command.CommandText = ""; } else if (command.CommandText.Length > 0) { command.CommandText += ";\n"; } } else { command.CommandText = ""; command.Parameters.Clear(); } System.Text.StringBuilder sb = new System.Text.StringBuilder(query.Length * 2); StringCollection paramNames = new StringCollection(); for (int i = 0; i < query.Length; ++i) { char c = query[i]; if (c == '\'') { int j = ++i; for (;; ++j) { if (j >= query.Length) { throw new ArgumentException("Query has unbalanced quotes"); } if (query[j] == '\'') { if (j + 1 >= query.Length || query[j + 1] != '\'') { break; } // double apostrophe j++; } } string stringValue = query.Substring(i, j - i); char modifier = j + 1 < query.Length ? query[j + 1] : ' '; string paramName; switch (modifier) { case 'V': sb.Append('\''); sb.Append(stringValue); sb.Append('\''); j++; break; case 'D': paramName = AddParameterFromValue(command, DateTime.ParseExact(stringValue, "yyyyMMddHH:mm:ss", CultureInfo.InvariantCulture), null); sb.Append(paramName); j++; break; case 'A': stringValue = stringValue.Replace("''", "'"); paramName = AddParameterFromValue(command, stringValue, SoqlLiteralValueModifiers.AnsiString); sb.Append(paramName); j++; break; default: if (!isRaw && (!UseSafeLiterals || !IsStringSafeForLiteral(stringValue))) { stringValue = stringValue.Replace("''", "'"); paramName = AddParameterFromValue(command, stringValue, null); sb.Append(paramName); } else { sb.Append('\''); sb.Append(stringValue); sb.Append('\''); } break; } i = j; } else if (c == '{') { c = query[i + 1]; if (c == 'L') { // {L:fieldDataTypeName:value int startPos = i + 3; int endPos = query.IndexOf(':', startPos); if (endPos < 0) { throw new ArgumentException("Missing ':' in literal specification"); } SoqlLiteralValueModifiers modifier = SoqlParser.ParseLiteralValueModifiers(query.Substring(startPos, endPos - startPos)); FieldDataType fdt = modifier.DataTypeOverride; int valueStartPos = endPos + 1; bool anyEscape = false; for (i = valueStartPos; i < query.Length && query[i] != '}'; ++i) { if (query[i] == '\\') { i++; anyEscape = true; } } string literalValue = query.Substring(valueStartPos, i - valueStartPos); if (anyEscape) { literalValue = literalValue.Replace("\\}", "}"); literalValue = literalValue.Replace("\\\\", "\\"); } SoodaFieldHandler fieldHandler = FieldHandlerFactory.GetFieldHandler(fdt); object v = fieldHandler.RawDeserialize(literalValue); if (v == null) { sb.Append("null"); } else if (UseSafeLiterals && v is int) { sb.Append((int)v); } else if (UseSafeLiterals && v is string && IsStringSafeForLiteral((string)v)) { sb.Append('\''); sb.Append((string)v); sb.Append('\''); } else { IDbDataParameter p = command.CreateParameter(); p.Direction = ParameterDirection.Input; p.ParameterName = GetNameForParameter(command.Parameters.Count); fieldHandler.SetupDBParameter(p, v); command.Parameters.Add(p); sb.Append(p.ParameterName); } } else if (c >= '0' && c <= '9') { i++; int paramNumber = 0; do { paramNumber = paramNumber * 10 + c - '0'; c = query[++i]; } while (c >= '0' && c <= '9'); SoqlLiteralValueModifiers modifiers = null; if (c == ':') { int startPos = i + 1; i = query.IndexOf('}', startPos); if (i < 0) { throw new ArgumentException("Missing '}' in parameter specification"); } modifiers = SoqlParser.ParseLiteralValueModifiers(query.Substring(startPos, i - startPos)); } else if (c != '}') { throw new ArgumentException("Missing '}' in parameter specification"); } object v = par[paramNumber]; if (v is SoodaObject) { v = ((SoodaObject)v).GetPrimaryKeyValue(); } if (v == null) { sb.Append("null"); } else if (UseSafeLiterals && v is int) { sb.Append((int)v); } else if (UseSafeLiterals && v is string && IsStringSafeForLiteral((string)v)) { sb.Append('\''); sb.Append((string)v); sb.Append('\''); } else { sb.Append(AddNumberedParameter(command, v, modifiers, paramNames, paramNumber)); } } else { throw new ArgumentException("Unexpected character in parameter specification"); } } else if (c == '(' || c == ' ' || c == ',' || c == '=' || c == '>' || c == '<' || c == '+' || c == '-' || c == '*' || c == '/') { sb.Append(c); if (i < query.Length - 1) { c = query[i + 1]; if (c >= '0' && c <= '9' && !UseSafeLiterals) { int v = 0; double f = 0; double dp = 0; bool isDouble = false; do { if (c != '.') { if (!isDouble) { v = v * 10 + c - '0'; } else { f = f + dp * (c - '0'); dp = dp * 0.1; } } else { isDouble = true; f = v; dp = 0.1; } i++; if (i < query.Length - 1) { c = query[i + 1]; } } while (((c >= '0' && c <= '9') || c == '.') && (i < query.Length - 1)); if (!isDouble) { string paramName = AddParameterFromValue(command, v, null); sb.Append(paramName); } else { string paramName = AddParameterFromValue(command, f, null); sb.Append(paramName); } } } } else { sb.Append(c); } } command.CommandText += sb.ToString(); }