예제 #1
0
        /// <summary>
        /// Executes an SQL statement and return the results.
        /// </summary>
        /// <param name="statement">The SQL statement to execute.</param>
        /// <param name="channel">The channel to use.</param>
        /// <returns>The Result object.</returns>
        public Result Execute(string statement, Channel channel)
        {
            if (TracingHelper.TraceEnabled)
            {
                TracingHelper.Write(statement);
            }

            Tokenizer c            = new Tokenizer(statement);
            Parser    p            = new Parser(this, c, channel);
            Result    rResult      = new Result();
            string    newStatement = string.Empty;
            int       updateCount  = 0;

            try
            {
                if (_log != null && _log.cCache != null)
                {
                    _log.cCache.CleanUp();
                }

                if (TracingHelper.AssertEnabled)
                {
                    TracingHelper.Assert(!channel.IsNestedTransaction);
                }

                TracingHelper.Check(channel != null, TracingHelper.ACCESS_IS_DENIED);
                TracingHelper.Check(!_shutDown, TracingHelper.DATABASE_IS_SHUTDOWN);

                while (true)
                {
                    int    begin  = c.Position;
                    bool   script = false;
                    string sToken = c.GetString();

                    if (sToken.Equals(""))
                    {
                        break;
                    }

                    switch (sToken)
                    {
                    case "SELECT":
                        rResult = p.ProcessSelect();
                        break;

                    case "INSERT":
                        rResult = p.ProcessInsert();
                        break;

                    case "UPDATE":
                        rResult = p.ProcessUpdate();
                        break;

                    case "DELETE":
                        rResult = p.ProcessDelete();
                        break;

                    case "ALTER":
                        rResult = p.ProcessAlter();
                        break;

                    case "CREATE":
                        rResult = ProcessCreate(c, channel);
                        script  = true;
                        break;

                    case "DROP":
                        rResult = ProcessDrop(c, channel);
                        script  = true;
                        break;

                    case "GRANT":
                        rResult = ProcessGrantOrRevoke(c, channel, true);
                        script  = true;
                        break;

                    case "REVOKE":
                        rResult = ProcessGrantOrRevoke(c, channel, false);
                        script  = true;
                        break;

                    case "CONNECT":
                        rResult = ProcessConnect(c, channel);
                        break;

                    case "DISCONNECT":
                        rResult = ProcessDisconnect(c, channel);
                        break;

                    case "SET":
                        rResult = ProcessSet(c, channel);
                        script  = true;
                        break;

                    case "SCRIPT":
                        rResult = ProcessScript(c, channel);
                        break;

                    case "COMMIT":
                        rResult = ProcessCommit(c, channel);
                        script  = true;
                        break;

                    case "ROLLBACK":
                        rResult = ProcessRollback(c, channel);
                        script  = true;
                        break;

                    case "SHUTDOWN":
                        rResult = ProcessShutdown(c, channel);
                        break;

                    case "CHECKPOINT":
                        rResult = ProcessCheckpoint(channel);
                        break;

                    case "CALL":
                        rResult = p.ProcessCall();
                        break;

                    case "SHOW":
                        rResult = ProcessShow(c, channel);
                        break;

                    case "DECLARE":
                        rResult = p.ProcessDeclare();
                        script  = true;
                        break;

                    case ";":
                        continue;

                    default:
                        throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken);
                    }

                    if (rResult != null && rResult.UpdateCount > updateCount)
                    {
                        updateCount = rResult.UpdateCount;
                    }

                    if (script && _log != null)
                    {
                        int end = c.Position;

                        _log.Write(channel, c.GetPart(begin, end));
                    }
                }
            }
            catch (Exception e)
            {
                rResult = new Result(TracingHelper.GetMessage(e) + " in statement [" + statement + "]");
            }

            if (rResult != null && rResult.UpdateCount < updateCount)
            {
                rResult.SetUpdateCount(updateCount);
            }

            return(rResult);
        }