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."); }
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); }