コード例 #1
0
ファイル: NpgsqlDataSet.cs プロジェクト: calc33/PgTools
        private static List <string> GetParameterNames(string sql)
        {
            List <string>             l    = new List <string>();
            Dictionary <string, bool> dict = new Dictionary <string, bool>();
            TokenizedSQL tsql = new TokenizedSQL(sql);
            int          n    = tsql.Tokens.Length;

            for (int i = 0; i < n; i++)
            {
                Token t = tsql.Tokens[i];
                if (t.ID == TokenID.Colon)
                {
                    i++;
                    t = tsql.Tokens[i];
                    Token t0 = t;
                    for (; i < n && tsql.Tokens[i].ID == TokenID.Identifier; t = tsql.Tokens[i++])
                    {
                        ;
                    }
                    string p = DequoteIdentifier(tsql.Extract(t0, t));
                    if (!dict.ContainsKey(p))
                    {
                        l.Add(p);
                        dict.Add(p, true);
                    }
                }
            }
            return(l);
        }
コード例 #2
0
ファイル: NpgsqlDataSet.lex.cs プロジェクト: calc33/PgTools
 internal Token(TokenizedSQL owner, TokenKind kind, TokenID identifier, int start, int current)
 {
     _owner = owner;
     Kind   = kind;
     ID     = identifier;
     Start  = new TokenPosition(owner, start);
     End    = new TokenPosition(owner, current - 1);
 }
コード例 #3
0
        public override Tuple <int, int> GetWordAt(string sql, int position)
        {
            TokenizedSQL tsql = new TokenizedSQL(sql, position);
            Token        sel  = tsql.Selected;

            if (sel == null)
            {
                return(null);
            }
            return(new Tuple <int, int>(sel.Start.Index, sel.End.Index - sel.Start.Index + 1));
        }
コード例 #4
0
        public override Tuple <int, int> GetErrorPosition(Exception t, string sql, int offset)
        {
            if (!(t is Npgsql.PostgresException))
            {
                return(null);
            }
            Npgsql.PostgresException ex = (Npgsql.PostgresException)t;
            int p0 = ex.Position;

            if (p0 <= 0)
            {
                return(null);
            }
            p0--;
            TokenizedSQL             tsql     = new TokenizedSQL(sql.Substring(offset));
            bool                     wasColon = false;
            int                      seq      = 1;
            Dictionary <string, int> pdict    = new Dictionary <string, int>();

            foreach (Token token in tsql.Tokens)
            {
                if (wasColon && token.Kind == TokenKind.Identifier)
                {
                    // パラメータは内部的に数字に置換して実行し、
                    // 置換後のSQLでの文字位置が返るため
                    // そのままでは位置がずれてしまう
                    int idx;
                    if (!pdict.TryGetValue(token.Value, out idx))
                    {
                        idx = seq++;
                        pdict.Add(token.Value, idx);
                    }
                    p0 += (token.Value.Length - idx.ToString().Length);
                }
                wasColon = (token.ID == TokenID.Colon);
            }
            int n = sql.Length;
            int p;

            for (p = p0; p < n && !char.IsWhiteSpace(sql, p); p++)
            {
                ;
            }
            if (p0 < offset)
            {
                return(null);
            }
            return(new Tuple <int, int>(p0 - offset, p - p0));
        }
コード例 #5
0
ファイル: NpgsqlDataSet.lex.cs プロジェクト: calc33/PgTools
            internal Token(TokenizedSQL owner, TokenKind kind, string ids, int start, int current)
            {
                _owner = owner;
                Kind   = kind;
                byte[] bytes = Encoding.ASCII.GetBytes(ids);
                int    v     = 0;

                foreach (byte b in bytes)
                {
                    v = v << 8 | b;
                }
                ID    = (TokenID)v;
                Start = new TokenPosition(owner, start);
                End   = new TokenPosition(owner, current - 1);
            }
コード例 #6
0
ファイル: NpgsqlDataSet.lex.cs プロジェクト: calc33/PgTools
        public override SQLParts SplitSQL(string sql)
        {
            List <SQLPart> l    = new List <SQLPart>();
            TokenizedSQL   tsql = new TokenizedSQL(sql);
            int            i    = 0;
            int            n    = tsql.Tokens.Length;

            while (i < n)
            {
                //Token t = tsql.Tokens[i];
                for (; i < n; i++)
                {
                    Token t = tsql.Tokens[i];
                    if (t.Kind != TokenKind.Space && t.Kind != TokenKind.NewLine && t.Kind != TokenKind.Comment)
                    {
                        break;
                    }
                }
                int   i0           = i;
                Token t0           = tsql.Tokens[i0];
                bool  endByNewLine = false;
                if (t0.Kind == TokenKind.Identifier && (string.Compare(t0.Value, "begin") == 0 || string.Compare(t0.Value, "start") == 0))
                {
                    endByNewLine = true;
                }
                for (; i < n && tsql.Tokens[i].Kind != TokenKind.Semicolon && (!endByNewLine || tsql.Tokens[i].Kind != TokenKind.NewLine); i++)
                {
                    ;
                }
                string  s  = tsql.Extract(t0, tsql.Tokens[i - 1]);
                SQLPart sp = new SQLPart()
                {
                    Offset         = t0.Start.Index,
                    SQL            = s,
                    ParameterNames = GetParameterNames(s).ToArray(),
                };
                l.Add(sp);
                i++;
            }

            return(new SQLParts()
            {
                Items = l.ToArray(),
                ParameterNames = GetParameterNames(sql).ToArray()
            });
        }
コード例 #7
0
ファイル: NpgsqlDataSet.lex.cs プロジェクト: calc33/PgTools
            public TokenPosition(TokenizedSQL sql, int index)
            {
                // 前回の位置情報を使って高速化(可能なら)
                TokenPosition previous = sql._lastPos;

                if (index < previous.Index)
                {
                    previous = Empty;
                }
                string text = sql.Sql;

                Line   = previous.Line;
                Column = previous.Column;
                Index  = previous.Index;
                int  i     = Index;
                int  l     = Line;
                int  c     = Column;
                int  n     = Math.Min(index, text.Length - 1);
                bool wasCR = false;
                bool wasLF = false;

                while (i <= n)
                {
                    char ch = text[i];
                    if (wasCR && ch != '\n' || wasLF)
                    {
                        l++;
                        c = 1;
                    }

                    Index  = i;
                    Line   = l;
                    Column = c;

                    i++;
                    c++;
                    if (char.IsSurrogate(ch))
                    {
                        i++;
                        c++;
                    }
                    wasCR = (ch == '\r');
                    wasLF = (ch == '\n');
                }
                sql._lastPos = this;
            }
コード例 #8
0
ファイル: NpgsqlDataSet.parse.cs プロジェクト: calc33/PgTools
 public static ExprNode Parse(TokenizedSQL sql, Token token, ref int tokenIndex, SyntaxTreeNode prior, SyntaxTreeNode parent)
 {
     throw new NotImplementedException();
 }
コード例 #9
0
ファイル: NpgsqlDataSet.lex.cs プロジェクト: calc33/PgTools
        public override string NormalizeSQL(string sql, CaseRule reservedRule, CaseRule identifierRule)
        {
            if (string.IsNullOrEmpty(sql))
            {
                return(sql);
            }
            StringBuilder buf         = new StringBuilder();
            TokenizedSQL  tsql        = new TokenizedSQL(sql);
            bool          wasLanguage = false;
            bool          isSqlDef    = false;

            foreach (Token t in tsql.Tokens)
            {
                if (t.Kind == TokenKind.Space || t.Kind == TokenKind.NewLine || t.Kind == TokenKind.Comment)
                {
                    continue;
                }
                if (wasLanguage && t.Kind == TokenKind.Identifier)
                {
                    string lang = t.Value.ToLower();
                    if (lang == "plpgsql" || lang == "sql")
                    {
                        isSqlDef = true;
                        break;
                    }
                }
                wasLanguage = (t.Kind == TokenKind.Identifier && t.Value.ToLower() == "language");
            }
            bool  noQuote   = false;
            Token holdedSpc = null;

            foreach (Token t in tsql.Tokens)
            {
                // 行末の空白を除去
                if (holdedSpc != null && t.Kind != TokenKind.NewLine)
                {
                    buf.Append(holdedSpc.Value);
                }
                holdedSpc = null;
                switch (t.Kind)
                {
                case TokenKind.Identifier:
                    if (IsReservedWord(t.Value))
                    {
                        buf.Append(NormalizeIdentifier(t.Value, reservedRule, true));
                    }
                    else
                    {
                        buf.Append(NormalizeIdentifier(t.Value, identifierRule, noQuote));
                    }
                    break;

                case TokenKind.DefBody:
                    if (isSqlDef)
                    {
                        buf.Append(NormalizeDefBody(t.Value, reservedRule, identifierRule));
                    }
                    else
                    {
                        buf.Append(t.Value);
                    }
                    break;

                case TokenKind.Space:
                    // 行末の空白を除去(次のトークンを見て判断)
                    holdedSpc = t;
                    break;

                case TokenKind.NewLine:
                    // 改行をCRLFに統一
                    buf.AppendLine();
                    break;

                default:
                    buf.Append(t.Value);
                    break;
                }
                noQuote = (t.Kind == TokenKind.Operator) && (t.ID == TokenID.Colon);
            }
            return(buf.ToString());
        }