Example #1
0
        public QueryResult Execute(Session session, PreparedQuery preparedQuery)
        {
            if (preparedQuery.QueryType == Constants.QueryType.Select)
            {
                return(core.Documents.ExecuteSelect(session, preparedQuery));
            }

            throw new LeafSQLExecutionException("The query type has not been implemented.");
        }
Example #2
0
        static public PreparedQuery ParseQuery(string query)
        {
            PreparedQuery result = new PreparedQuery();

            Utilities.CleanQueryText(ref query);

            Dictionary <string, string> literalStrings = Utilities.SwapOutLiteralStrings(ref query);

            int    position = 0;
            string token    = string.Empty;

            token = Utilities.GetNextToken(query, ref position);

            QueryType queryType = QueryType.Select;

            if (Enum.TryParse <QueryType>(token, true, out queryType) == false)
            {
                throw new Exception("Invalid query. Found [" + token + "], expected select, insert, update or delete.");
            }

            result.QueryType = queryType;
            //--------------------------------------------------------------------------------------------------------------------------------------------
            if (queryType == QueryType.Delete)
            {
                token = Utilities.GetNextToken(query, ref position);
                if (token.ToLower() == "top")
                {
                    token = Utilities.GetNextToken(query, ref position);
                    int rowLimit = 0;

                    if (Int32.TryParse(token, out rowLimit) == false)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected numeric row limit.");
                    }

                    result.RowLimit = rowLimit;

                    //Get schema name:
                    token = Utilities.GetNextToken(query, ref position);
                }

                if (token == string.Empty || Utilities.IsValidIdentifier(token, "/\\") == false)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected schema name.");
                }
                result.Schema = token;

                token = Utilities.GetNextToken(query, ref position);
                if (token.ToLower() == "where")
                {
                    string conditionText = query.Substring(position).Trim();
                    if (conditionText == string.Empty)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected list of conditions.");
                    }

                    result.Conditions = ParseConditions(conditionText);
                }
                else if (token != string.Empty)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected end of statement.");
                }
            }
            //--------------------------------------------------------------------------------------------------------------------------------------------
            else if (queryType == QueryType.Update)
            {
                token = Utilities.GetNextToken(query, ref position);
                if (token.ToLower() == "top")
                {
                    token = Utilities.GetNextToken(query, ref position);
                    int rowLimit = 0;

                    if (Int32.TryParse(token, out rowLimit) == false)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected numeric row limit.");
                    }

                    result.RowLimit = rowLimit;

                    //Get schema name:
                    token = Utilities.GetNextToken(query, ref position);
                }

                if (token == string.Empty || Utilities.IsValidIdentifier(token, "/\\") == false)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected schema name.");
                }
                result.Schema = token;

                token = Utilities.GetNextToken(query, ref position);
                if (token.ToLower() != "set")
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected [SET].");
                }

                result.UpsertKeyValuePairs = ParseUpsertKeyValues(query, ref position);

                token = Utilities.GetNextToken(query, ref position);
                if (token != string.Empty && token.ToLower() != "where")
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected [WHERE] or end of statement.");
                }

                if (token.ToLower() == "where")
                {
                    string conditionText = query.Substring(position).Trim();
                    if (conditionText == string.Empty)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected list of conditions.");
                    }

                    result.Conditions = ParseConditions(conditionText);
                }
                else if (token != string.Empty)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected end of statement.");
                }
            }
            //--------------------------------------------------------------------------------------------------------------------------------------------
            else if (queryType == QueryType.Select)
            {
                token = Utilities.GetNextToken(query, ref position);
                if (token.ToLower() == "top")
                {
                    token = Utilities.GetNextToken(query, ref position);
                    int rowLimit = 0;

                    if (Int32.TryParse(token, out rowLimit) == false)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected numeric row limit.");
                    }

                    result.RowLimit = rowLimit;

                    token = Utilities.GetNextToken(query, ref position); //Select the first column name for the loop below.
                }

                while (true)
                {
                    if (token.ToLower() == "from" || token == string.Empty)
                    {
                        break;
                    }

                    if (Utilities.IsValidIdentifier(token) == false && token != "*")
                    {
                        throw new Exception("Invalid token. Found [" + token + "] a valid identifier.");
                    }

                    result.SelectFields.Add(token);

                    token = Utilities.GetNextToken(query, ref position);
                }

                if (token.ToLower() != "from")
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected [FROM].");
                }

                token = Utilities.GetNextToken(query, ref position);
                if (token == string.Empty || Utilities.IsValidIdentifier(token, ":") == false)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected schema name.");
                }

                result.Schema = token;

                token = Utilities.GetNextToken(query, ref position);
                if (token != string.Empty && token.ToLower() != "where")
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected [WHERE] or end of statement.");
                }

                if (token.ToLower() == "where")
                {
                    string conditionText = query.Substring(position).Trim();
                    if (conditionText == string.Empty)
                    {
                        throw new Exception("Invalid query. Found [" + token + "], expected list of conditions.");
                    }

                    result.Conditions = ParseConditions(conditionText);
                }
                else if (token != string.Empty)
                {
                    throw new Exception("Invalid query. Found [" + token + "], expected end of statement.");
                }
            }
            //--------------------------------------------------------------------------------------------------------------------------------------------

            foreach (var literalString in literalStrings)
            {
                if (result.Conditions != null)
                {
                    foreach (var kvp in result.Conditions.Flattened)
                    {
                        kvp.Key   = kvp.Key.Replace(literalString.Key, literalString.Value);
                        kvp.Value = kvp.Value.Replace(literalString.Key, literalString.Value);
                    }
                }

                if (result.UpsertKeyValuePairs != null)
                {
                    foreach (var kvp in result.UpsertKeyValuePairs.Collection)
                    {
                        kvp.Key   = kvp.Key.Replace(literalString.Key, literalString.Value);
                        kvp.Value = kvp.Value.Replace(literalString.Key, literalString.Value);
                    }
                }
            }

            if (result.Conditions != null)
            {
                foreach (var kvp in result.Conditions.Flattened)
                {
                    if (kvp.Key.StartsWith("\'") && kvp.Key.EndsWith("\'"))
                    {
                        kvp.Key           = kvp.Key.Substring(1, kvp.Key.Length - 2);
                        kvp.IsKeyConstant = true;
                    }

                    if (kvp.Value.StartsWith("\'") && kvp.Value.EndsWith("\'"))
                    {
                        kvp.Value           = kvp.Value.Substring(1, kvp.Value.Length - 2);
                        kvp.IsValueConstant = true;
                    }

                    //Process escape sequences:
                    kvp.Key   = kvp.Key.Replace("\\'", "\'");
                    kvp.Value = kvp.Value.Replace("\\'", "\'");

                    if (kvp.Key.All(Char.IsDigit))
                    {
                        kvp.IsKeyConstant = true;
                    }
                    if (kvp.Value.All(Char.IsDigit))
                    {
                        kvp.IsValueConstant = true;
                    }
                }
            }

            if (result.UpsertKeyValuePairs != null)
            {
                foreach (var kvp in result.UpsertKeyValuePairs.Collection)
                {
                    if (kvp.Key.StartsWith("\'") && kvp.Key.EndsWith("\'"))
                    {
                        kvp.Key           = kvp.Key.Substring(1, kvp.Key.Length - 2);
                        kvp.IsKeyConstant = true;
                    }

                    if (kvp.Value.StartsWith("\'") && kvp.Value.EndsWith("\'"))
                    {
                        kvp.Value           = kvp.Value.Substring(1, kvp.Value.Length - 2);
                        kvp.IsValueConstant = true;
                    }

                    //Process escape sequences:
                    kvp.Key   = kvp.Key.Replace("\\'", "\'");
                    kvp.Value = kvp.Value.Replace("\\'", "\'");

                    if (kvp.Key.All(Char.IsDigit))
                    {
                        kvp.IsKeyConstant = true;
                    }
                    if (kvp.Value.All(Char.IsDigit))
                    {
                        kvp.IsValueConstant = true;
                    }
                }
            }

            result.Conditions.MakeLowerCase();

            return(result);
        }