Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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();
        }