Пример #1
0
        //========================================================================================
        // Parse()
        //========================================================================================

        #region Parse

        private void Parse(int start, int delimIndex, StatementCollection statements)
        {
            if ((sql == null) || (sql.Length == 0) || (start >= sql.Length))
            {
                return;
            }

            if (sql[start] == ' ')
            {
                start++;
            }

            // extract first keyword in query

            string word;
            int    space = sql.IndexOf(' ', start);

            if (space < 0)
            {
                // found last word.  now strip the final semicolon
                int end = sql.IndexOf(';', start);
                if (end < 0)
                {
                    word = sql.Substring(start).Trim();
                }
                else
                {
                    word = sql.Substring(start, end - start).Trim();
                }
            }
            else
            {
                word = sql.Substring(start, sql.IndexOf(' ', start) - start).ToUpper();
            }

            // test extract keyword for important delimeters

            if (word.Equals("/"))
            {
                // ignore the / command
                Parse(start + 2, delimIndex, statements);
            }
            else if (word.Equals("EXIT"))
            {
                // ignore the EXIT command
                Parse(start + 5, delimIndex, statements);
            }
            else if (complexCmds.Contains(word) && IsPackageDef(start + word.Length + 1))
            {
                // parse multi-depth DDL
                ParseComplex(ref start, statements);
                if (start < sql.Length)
                {
                    Parse(start, delimIndex, statements);
                }
            }
            else
            {
                // TODO: use start-delimeter[] to determine end point rather than manually
                // looking for the next semi-colon (which might be embedded in a string)

                // simple query, seek end
                int end = IndexOfUnquoted(sql, start, ';');

                string query;
                if (end < 0)
                {
                    query = sql.Substring(start);
                }
                else
                {
                    query = sql.Substring(start, end - start);
                }

                statements.Add(query.Trim());

                if (end < 0)
                {
                    return;
                }

                end++;
                if (end < sql.Length)
                {
                    Parse(end, delimIndex + 1, statements);
                }
            }
        }
Пример #2
0
        //========================================================================================
        // ParseComplex()
        //========================================================================================

        private void ParseComplex(ref int start, StatementCollection statements)
        {
            int  i         = start;
            int  saveStart = start;
            int  depth     = 0;
            bool found     = false;
            bool inString  = false;
            char c         = Char.MinValue;

            var    token = new StringBuilder();
            string word;

            while ((i < sql.Length) && !found)
            {
                c = sql[i];

                if (inString)
                {
                    if (c == '\'')
                    {
                        inString = false;
                    }

                    token.Append(c);
                }
                else if (c == ';')
                {
                    if (depth < 0)
                    {
                        found = true;
                    }
                    else if (token.Length > 0)
                    {
                        word = token.ToString().ToUpper();
                        if (word.Equals("END"))
                        {
                            depth--;
                        }

                        if (depth < 0)
                        {
                            found = true;
                        }
                    }

                    token.Length = 0;
                }
                else if (Char.IsWhiteSpace(c))
                {
                    word = token.ToString().ToUpper();

                    if (blockCmds.Contains(word))
                    {
                        depth++;
                    }
                    else if (word.Equals("END"))
                    {
                        depth--;
                    }

                    token.Length = 0;
                }
                else
                {
                    if (c == '\'')
                    {
                        inString = true;
                    }

                    token.Append(c);
                }

                i++;
            }

            var query = new StringBuilder();

            if (found)
            {
                query.Append(sql.Substring(start, i - start));
                if (query[query.Length - 1] != ';')
                {
                    query.Append(';');
                }

                start = i + 1;
            }
            else
            {
                query.Append(sql.Substring(start));
                if (query[query.Length - 1] != ';')
                {
                    query.Append(';');
                }

                start = sql.Length;
            }

            if (isOptimized)
            {
                statements.Add(query.ToString());
            }
            else
            {
                int a = (int)map[saveStart];
                int b = (int)map[i - 1];

                query.Length = 0;
                query.Append(text.Substring(a, b - a + 1));
                if (query[query.Length - 1] != ';')
                {
                    query.Append(';');
                }

                statements.Add(query.ToString());
            }
        }
Пример #3
0
        //========================================================================================
        // ExecuteExternalScript()
        //========================================================================================

        private void ExecuteExternalScript(Query query)
        {
            isNested = true;

            try
            {
                string filnam = query.SQL.Substring(1);
                if (filnam[filnam.Length - 1] == ';')
                {
                    filnam = filnam.Substring(0, filnam.Length - 1);
                }

                if (Path.GetDirectoryName(filnam) == String.Empty)
                {
                    filnam = basePath + "\\" + filnam;
                }

                StreamReader reader = File.OpenText(filnam);
                string       text   = reader.ReadToEnd().Trim();
                reader.Close();

                if (text.Length == 0)
                {
                    return;
                }

                string savePath = basePath;
                basePath = Path.GetDirectoryName(filnam);

                // create nested query collection processing...

                var queries = new QueryCollection();
                var parser  = new StatementParser();
                StatementCollection statements = parser.Parse(text);

                // build collection of parsed queries
                Query q;
                System.Collections.Specialized.StringEnumerator e = statements.GetEnumerator();
                while (e.MoveNext())
                {
                    q = new Query(e.Current);
                    parser.ParseStatement(dbase, q, browser);
                    queries.Add(q);
                }
                //[end create nested]

                // execute query collection

                try
                {
                    foreach (Query q2 in queries)
                    {
                        ExecuteQuery(q2);
                    }
                }
                catch (Exception exc)
                {
                    Dialogs.ExceptionDialog.ShowException(exc);
                }
                finally
                {
                    basePath = savePath;
                }
            }
            catch (Exception exc)
            {
                query.AddMessage(exc);
            }

            isNested = false;
        }