public Node[] Parse(string command) { List <Node> tokens = new List <Node>(); var tokenReader = new SQLiteTokenReader((command + "").Trim()); if (tokenReader.EqualTo(SelectWord)) { ParseSelectOrGroupBy(tokenReader, tokens); } return(tokens.ToArray()); }
private void ParseExpression(SQLiteTokenReader tokenReader, List <Node> tokens, bool isHaving = false, bool isGroupBy = false, bool isOnClause = false) { tokenReader.MoveNext(); if (tokenReader.EqualTo(SelectWord)) { if (isHaving) { throw new Exception("Cannot have select in a having clause!"); } if (isGroupBy) { throw new Exception("Cannot have select in a group by clause!"); } if (isOnClause) { throw new Exception("Cannot have select in a on clause!"); } ParseSelectOrGroupBy(tokenReader, tokens); } else { do { if (tokenReader.EqualTo("(")) { // start of epxression... tokens.Add(new Node() { Code = JSqlOpCodes.OpenBrackets }); ParseExpression(tokenReader, tokens, isHaving); if (!tokenReader.EqualTo(")")) { throw new Exception("Expected closing ')'"); } else { tokens.Add(new Node() { Code = JSqlOpCodes.CloseBrackets }); tokenReader.MoveNext(); } } else { ParseVarOrLit(tokenReader, tokens); } if (tokenReader.CanMoveNext) { if (!isOnClause && !isHaving && !isGroupBy && tokenReader.EqualTo(GroupWord, GroupByWord)) { ParseSelectOrGroupBy(tokenReader, tokens, true); return; } else if (!isOnClause && !isHaving && tokenReader.EqualTo(HavingWord)) { ParseWhereOrHaving(tokenReader, tokens, true); return; } else if (tokenReader.EqualTo(")")) { // inside expression. return; } else { int prevpos = tokenReader._pos; ParseSymbol(tokenReader, tokens); if (tokenReader._pos == prevpos) { if (isOnClause) { return; } else { throw new Exception("Expected , or ; or from!"); } } } } else { return; } }while (true); } }
private void ParseSelectOrGroupBy(SQLiteTokenReader tokenReader, List <Node> tokens, bool isGroupBy = false) { tokenReader.MoveNext(); if (isGroupBy) { tokenReader.MoveNext(); tokens.Add(new Node() { Code = JSqlOpCodes.GroupClause }); } else { tokens.Add(new Node() { Code = JSqlOpCodes.SelectClause }); } bool skip = false; // we need to long all items.... do { if (!skip) { if (tokenReader.EqualTo("(")) { // start of epxression... tokens.Add(new Node() { Code = JSqlOpCodes.OpenBrackets }); ParseExpression(tokenReader, tokens, false, isGroupBy); if (!tokenReader.EqualTo(")")) { throw new Exception("Expected closing ')'"); } else { tokens.Add(new Node() { Code = JSqlOpCodes.CloseBrackets }); tokenReader.MoveNext(); } } else if (!isGroupBy && tokenReader.EqualTo("*")) { tokens.Add(new Node() { Code = JSqlOpCodes.SelectAll }); tokenReader.MoveNext(); } else { ParseVarOrLit(tokenReader, tokens); } } else { skip = false; } if (tokenReader.CanMoveNext) { if (!isGroupBy && tokenReader.EqualTo(FromWord)) { ParseFrom(tokenReader, tokens); return; } else if (isGroupBy && tokenReader.EqualTo(HavingWord)) { ParseWhereOrHaving(tokenReader, tokens, true); return; } else if (tokenReader.EqualTo(",")) { // continue; tokenReader.MoveNext(); } else if (!isGroupBy && tokenReader.Current.StartsWith("`")) { tokens.Add(new NodeString() { Code = JSqlOpCodes.Alias, Data1 = tokenReader.Current.Substring(1, tokenReader.Current.Length - 2) }); tokenReader.MoveNext(); skip = true; } else if (tokenReader.EqualTo(";")) { tokens.Add(new Node() { Code = JSqlOpCodes.EndOfQuery }); tokenReader.MoveNext(); return; } else if (tokenReader.EqualTo(")")) { // inside expression. return; } else { int prevpos = tokenReader._pos; ParseSymbol(tokenReader, tokens); if (tokenReader._pos == prevpos) { throw new Exception("Expected , or ; or from!"); } } } else { return; } }while (true); }
private bool ParseWhereOrHaving(SQLiteTokenReader tokenReader, List <Node> tokens, bool isHaving = false, bool isOnClause = false) { tokenReader.MoveNext(); if (isOnClause) { tokens.Add(new Node() { Code = JSqlOpCodes.OnClause }); } else { if (isHaving) { tokens.Add(new Node() { Code = JSqlOpCodes.HavingClause }); } else { tokens.Add(new Node() { Code = JSqlOpCodes.WhereClause }); } } do { if (tokenReader.EqualTo("(")) { // start of epxression... tokens.Add(new Node() { Code = JSqlOpCodes.OpenBrackets }); ParseExpression(tokenReader, tokens, isHaving, isOnClause); if (!tokenReader.EqualTo(")")) { throw new Exception("Expected closing ')'"); } else { tokens.Add(new Node() { Code = JSqlOpCodes.CloseBrackets }); tokenReader.MoveNext(); } } else { ParseVarOrLit(tokenReader, tokens); } if (tokenReader.CanMoveNext) { if (!isOnClause && !isHaving && tokenReader.EqualTo(GroupWord, GroupByWord)) { ParseSelectOrGroupBy(tokenReader, tokens); return(false); } else if (!isOnClause && !isHaving && tokenReader.EqualTo(HavingWord)) { ParseWhereOrHaving(tokenReader, tokens, true); return(false); } else if (tokenReader.EqualTo(")")) { // inside expression. return(false); } else { int prevpos = tokenReader._pos; if (ParseSymbol(tokenReader, tokens)) { // finished return(true); } if (tokenReader._pos == prevpos) { if (isOnClause) { // process in caller! return(false); } else { if (isHaving) { throw new Exception("Expected , or ;"); } else { throw new Exception("Expected , or ; or Group By or Having!"); } } } } } else { return(false); } }while (true); }
private void ParseFrom(SQLiteTokenReader tokenReader, List <Node> tokens) { tokenReader.MoveNext(); tokens.Add(new Node() { Code = JSqlOpCodes.FromClause }); bool skip = false; do { if (!skip) { if (tokenReader.EqualTo("(")) { // start of epxression... tokens.Add(new Node() { Code = JSqlOpCodes.OpenBrackets }); ParseExpression(tokenReader, tokens); if (!tokenReader.EqualTo(")")) { throw new Exception("Expected closing ')'"); } else { tokens.Add(new Node() { Code = JSqlOpCodes.CloseBrackets }); tokenReader.MoveNext(); } if (tokenReader.EqualTo("`")) { tokens.Add(new NodeString() { Code = JSqlOpCodes.Alias, Data1 = tokenReader.Current.Substring(1, tokenReader.Current.Length - 2) }); tokenReader.MoveNext(); } else { throw new Exception("From Clause on Expression needs Alias!"); } } else { ParseTableName(tokenReader, tokens); } } else { skip = false; } if (tokenReader.CanMoveNext) { if (tokenReader.EqualTo(WhereWord)) { ParseWhereOrHaving(tokenReader, tokens); return; } else if (tokenReader.EqualTo(GroupWord, GroupByWord)) { ParseSelectOrGroupBy(tokenReader, tokens, true); return; } else if (tokenReader.EqualTo(HavingWord)) { ParseWhereOrHaving(tokenReader, tokens, true); return; } else if (tokenReader.EqualTo(InnerWord, JoinWord)) { // continue; tokens.Add(new Node() { Code = JSqlOpCodes.InnerJoin }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(LeftWord, JoinWord)) { // continue; tokens.Add(new Node() { Code = JSqlOpCodes.LeftJoin }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(RightWord, JoinWord)) { // continue; tokens.Add(new Node() { Code = JSqlOpCodes.RightJoin }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(OuterWord, JoinWord)) { // continue; tokens.Add(new Node() { Code = JSqlOpCodes.OuterJoin }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(OnWord)) { // continue; if (ParseWhereOrHaving(tokenReader, tokens, false, true)) { return; } } else if (tokenReader.EqualTo(",")) { // continue; tokenReader.MoveNext(); } else if (tokenReader.Current.StartsWith("`")) { tokens.Add(new NodeString() { Code = JSqlOpCodes.Alias, Data1 = tokenReader.Current.Substring(1, tokenReader.Current.Length - 2) }); tokenReader.MoveNext(); skip = true; } else if (tokenReader.EqualTo(";")) { tokens.Add(new Node() { Code = JSqlOpCodes.EndOfQuery }); tokenReader.MoveNext(); return; } else if (tokenReader.EqualTo(")")) { // inside expression. return; } else { throw new Exception("Expected , or ; or from!"); } } else { return; } }while (true); }
private bool ParseSymbol(SQLiteTokenReader tokenReader, List <Node> tokens) { if (tokenReader.EqualTo("+")) { tokens.Add(new Node() { Code = JSqlOpCodes.Plus }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("-")) { tokens.Add(new Node() { Code = JSqlOpCodes.Minus }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("/")) { tokens.Add(new Node() { Code = JSqlOpCodes.Div }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("*")) { tokens.Add(new Node() { Code = JSqlOpCodes.Mul }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo(">")) { tokens.Add(new Node() { Code = JSqlOpCodes.Larger }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("<")) { tokens.Add(new Node() { Code = JSqlOpCodes.Smaller }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("=")) { tokens.Add(new Node() { Code = JSqlOpCodes.Equal }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("<", ">") || tokenReader.EqualTo("!", "=")) { tokens.Add(new Node() { Code = JSqlOpCodes.NotEqual }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo("|") || tokenReader.EqualTo("or")) { tokens.Add(new Node() { Code = JSqlOpCodes.Or }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("^")) { tokens.Add(new Node() { Code = JSqlOpCodes.BitWiseOr }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("&") || tokenReader.EqualTo("and")) { tokens.Add(new Node() { Code = JSqlOpCodes.And }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("%")) { tokens.Add(new Node() { Code = JSqlOpCodes.Mod }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo("&", "&")) { tokens.Add(new Node() { Code = JSqlOpCodes.And }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo("|", "|")) { tokens.Add(new Node() { Code = JSqlOpCodes.Or }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(">", "=")) { tokens.Add(new Node() { Code = JSqlOpCodes.LargerEqual }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo("<", "=")) { tokens.Add(new Node() { Code = JSqlOpCodes.SmallerEqual }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo(">", ">")) { tokens.Add(new Node() { Code = JSqlOpCodes.BitShiftRight }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo("<", "<")) { tokens.Add(new Node() { Code = JSqlOpCodes.BitShiftLeft }); tokenReader.MoveNext(2); } else if (tokenReader.EqualTo("!") || tokenReader.EqualTo("not")) { tokens.Add(new Node() { Code = JSqlOpCodes.Not }); tokenReader.MoveNext(); } else if (tokenReader.EqualTo(";")) { tokens.Add(new Node() { Code = JSqlOpCodes.EndOfQuery }); if (tokenReader.CanMoveNext) { tokenReader.MoveNext(); } return(true); } return(false); }