using System; using System.Collections.Generic; using System.Text; namespace FastReport.FastQueryBuilder { class SelectCommand_From : ParserBase { public override bool CanParse(SqlParser parser) { return parser.Token.Type == SqlTokenType.Keyword && parser.Token.Text == "from"; } public override void Parse(SqlParser parser) { SqlToken token = parser.NextToken(); while (token.Type != SqlTokenType.EOF) { if (token.Type == SqlTokenType.Keyword) return; ReadGroup(parser, ref token); if (token.Type == SqlTokenType.Punctuation && token.Text == ",") token = parser.NextToken(); } } /// /// read current token, returns next /// /// /// /// public void ReadGroup(SqlParser parser, ref SqlToken token) { while (token.Type == SqlTokenType.Punctuation && token.Text == ",") token = parser.NextToken(); if (token.Type == SqlTokenType.Punctuation && token.Text == "(") { token = parser.NextToken(); //read group ReadGroup(parser, ref token); if (token.Type == SqlTokenType.Punctuation && token.Text == ")") token = parser.NextToken(); } else { ReadTable(parser, ref token); } if(token.Type == SqlTokenType.Keyword) { string table = null; QueryEnums.JoinTypes joinType = QueryEnums.JoinTypes.Where; switch (token.LowerText) { case "inner join": token = parser.NextToken(); table = ReadTable(parser, ref token); joinType = QueryEnums.JoinTypes.InnerJoin; break; case "left outer join": token = parser.NextToken(); table = ReadTable(parser, ref token); joinType = QueryEnums.JoinTypes.LeftOuterJoin; break; case "right outer join": token = parser.NextToken(); table = ReadTable(parser, ref token); joinType = QueryEnums.JoinTypes.RightOuterJoin; break; case "full outer join": token = parser.NextToken(); table = ReadTable(parser, ref token); joinType = QueryEnums.JoinTypes.FullOuterJoin; break; } if(table != null ) { if(token.Type != SqlTokenType.Keyword || token.LowerText != "on" ) { parser.ThrowFormat(token, "on"); } SqlParser.FieldStruct one = ReadField(parser, ref token); QueryEnums.WhereTypes op; token = parser.NextToken(); switch (token.LowerText) { //, "<>", ">=", ">", "<=", "<", "LIKE", "NOT LIKE" case "=": op = QueryEnums.WhereTypes.Equal; break; case "<>": op = QueryEnums.WhereTypes.NotEqual; break; case ">=": op = QueryEnums.WhereTypes.GreaterOrEqual; break; case ">": op = QueryEnums.WhereTypes.Greater; break; case "<=": op = QueryEnums.WhereTypes.LessOrEqual; break; case "<": op = QueryEnums.WhereTypes.Less; break; case "like": op = QueryEnums.WhereTypes.Like; break; case "not like": op = QueryEnums.WhereTypes.NotLike; break; default: parser.ThrowFormat(token, "where types"); return; } SqlParser.FieldStruct two = ReadField(parser, ref token); //read token after field , or ) or next command token = parser.NextToken(); SqlParser.LinkStruct link = new SqlParser.LinkStruct(); link.One = one; link.Two = two; link.WhereType = op; link.JoinType = joinType; link.Table = table; parser.Links.Add(link); } } } /// /// read current token, returns next /// /// /// /// public string ReadTable(SqlParser parser, ref SqlToken token) { string table = null; string alias = null; if (token.Type != SqlTokenType.Name) parser.ThrowFormat(token, "name"); table = token.Text; token = parser.NextToken(); if (token.Type == SqlTokenType.Name) { alias = token.Text; token = parser.NextToken(); } SqlParser.TableStruct tableStruct = new SqlParser.TableStruct(); tableStruct.Name = table; tableStruct.Alias = alias; parser.Tables.Add(tableStruct); return table; } /// /// ignore current token, read from next, returns current i.e not next /// /// /// /// public SqlParser.FieldStruct ReadField(SqlParser parser, ref SqlToken token) { string table = null; string variable = null; token = parser.NextToken(); if (token.Type != SqlTokenType.Name) parser.ThrowFormat(token, "name"); table = token.Text; token = parser.NextToken(); if (token.Type != SqlTokenType.Punctuation || token.Text != ".") parser.ThrowFormat(token, "."); token = parser.NextToken(); if (token.Type != SqlTokenType.Name) parser.ThrowFormat(token, "name"); variable = token.Text; SqlParser.FieldStruct result = new SqlParser.FieldStruct(); result.Table = table; result.Name = variable; return result; } } }