Пример #1
0
        private void ExecuteWhileStmt(Ast.WhileStmt stmt, ScriptEnv env)
        {
            long condition;

            do
            {
                condition = EvaluateExpr <long>(stmt.Condition, env);
                if (condition == 1)
                {
                    ExecuteBlock(stmt.Block, env);
                    if (env.DidReturn || env.DidThrow)
                    {
                        return;
                    }
                    else if (env.DidBreak)
                    {
                        env.DidBreak = false;
                        break;
                    }
                    else if (env.DidContinue)
                    {
                        env.DidContinue = false;
                    }
                }
                else if (condition != 0)
                {
                    throw new ScriptException(
                              $"Evaluation of WHILE condition expression \"{stmt.Condition.Sql}\" " +
                              $"produced a value of {condition} instead of the expected 0 or 1.");
                }
            } while (condition == 1);
        }
Пример #2
0
        private void ExecuteExecuteStmt(Ast.ExecuteStmt stmt, ScriptEnv env)
        {
            var parser = new ScriptParser(_notebook);
            var runner = new ScriptRunner(_notebook, _scripts);
            var script = parser.Parse(GetScriptCode(stmt.ScriptName));
            var subEnv = new ScriptEnv();

            foreach (var arg in stmt.Arguments)
            {
                subEnv.Vars[arg.Name.ToLower()] = EvaluateExpr(arg.Value, env);
            }
            try {
                runner.Execute(script, subEnv);
            } catch (UncaughtErrorScriptException ex) {
                env.ErrorNumber  = ex.ErrorNumber;
                env.ErrorMessage = ex.ErrorMessage;
                env.ErrorState   = ex.ErrorState;
                env.DidThrow     = true;
                return;
            }
            env.Output.Append(subEnv.Output);
            var returnCode = subEnv.Output.ScalarResult;

            if (stmt.ReturnVariableName != null)
            {
                var name = stmt.ReturnVariableName.ToLower();
                env.Vars[name] = returnCode ?? 0L;
            }
        }
Пример #3
0
        public static long GetOptionLong(this Ast.OptionsList optionsList, string name, ScriptRunner runner,
                                         ScriptEnv env, long defaultValue, long?minValue = null, long?maxValue = null)
        {
            var  num        = optionsList.GetOption <long>(name, runner, env, defaultValue);
            bool outOfRange =
                (minValue.HasValue && num < minValue.Value) ||
                (maxValue.HasValue && num > maxValue.Value);

            if (outOfRange)
            {
                if (minValue.HasValue && !maxValue.HasValue)
                {
                    throw new Exception($"{name} must be an integer ≥ {minValue.Value}.");
                }
                else if (minValue.HasValue && maxValue.HasValue)
                {
                    throw new Exception($"{name} must be an integer between {minValue.Value} and {maxValue.Value}.");
                }
                else if (!minValue.HasValue && maxValue.HasValue)
                {
                    throw new Exception($"{name} must be an integer ≤ {maxValue.Value}.");
                }
            }
            return(num);
        }
Пример #4
0
        private void ExecuteSqlStmt(Ast.SqlStmt stmt, ScriptEnv env)
        {
            foreach (var beforeStmt in stmt.RunBefore)
            {
                ExecuteStmt(beforeStmt, env);
                if (env.DidThrow)
                {
                    return;
                }
            }

            try {
                var dt = _notebook.Query(stmt.Sql, env.Vars);
                if (dt.Columns.Any())
                {
                    env.Output.DataTables.Add(dt);
                }
            } finally {
                foreach (var afterStmt in stmt.RunAfter)
                {
                    ExecuteStmt(afterStmt, env);
                    if (env.DidThrow)
                    {
                        break;
                    }
                }
            }
        }
        private ExportTxtStmtRunner(INotebook notebook, ScriptEnv env, ScriptRunner runner, Ast.ExportTxtStmt stmt)
        {
            _notebook = notebook;
            _env      = env;
            _runner   = runner;
            _stmt     = stmt;

            _filePath = GetFilePath();

            foreach (var option in _stmt.OptionsList.GetOptionKeys())
            {
                switch (option)
                {
                case "TRUNCATE_EXISTING_FILE ":
                    _truncateExistingFile = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "FILE_ENCODING":
                    _fileEncoding =
                        _stmt.OptionsList.GetOptionEncoding(option, _runner, _env);
                    break;

                default:
                    throw new Exception($"\"{option}\" is not a recognized option name.");
                }
            }

            if (_fileEncoding == null)
            {
                _fileEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
            }
        }
Пример #6
0
 private void ExecuteImportXlsStmt(Ast.ImportXlsStmt stmt, ScriptEnv env)
 {
     try {
         ImportXlsStmtRunner.Run(_notebook, env, this, stmt);
     } catch (Exception ex) {
         Throw(env, ex.Message);
     }
 }
Пример #7
0
 private void ExecuteReturnStmt(Ast.ReturnStmt stmt, ScriptEnv env)
 {
     if (stmt.Value != null)
     {
         env.Output.ScalarResult = EvaluateExpr(stmt.Value, env);
     }
     env.DidReturn = true;
 }
Пример #8
0
        private void Throw(ScriptEnv env, object errorMessage)
        {
            env.ErrorMessage = errorMessage;
            env.DidThrow     = true;

            // make the error message available via the error_message() function
            _notebook.UserData.LastError.ErrorMessage = env.ErrorMessage;
        }
Пример #9
0
 private void ExecuteExportTxtStmt(Ast.ExportTxtStmt stmt, ScriptEnv env)
 {
     try {
         ExportTxtStmtRunner.Run(_notebook, env, this, stmt);
     } catch (Exception ex) {
         Throw(env, -1, ex.Message, -1);
     }
 }
Пример #10
0
 private void ExecuteTryCatchStmt(Ast.TryCatchStmt stmt, ScriptEnv env)
 {
     ExecuteBlock(stmt.TryBlock, env);
     if (env.DidThrow)
     {
         env.DidThrow = false;
         ExecuteBlock(stmt.CatchBlock, env);
     }
 }
Пример #11
0
 public ScriptOutput Execute(Ast.Script script, ScriptEnv env, IReadOnlyDictionary <string, object> args)
 {
     foreach (var arg in args)
     {
         var lowercaseKey = arg.Key.ToLower();
         env.Vars[lowercaseKey] = arg.Value;
     }
     Execute(script, env);
     return(env.Output);
 }
Пример #12
0
 private void ExecuteBlock(Ast.Block block, ScriptEnv env)
 {
     foreach (var stmt in block.Statements)
     {
         ExecuteStmt(stmt, env);
         if (env.DidReturn || env.DidBreak || env.DidContinue || env.DidThrow)
         {
             return;
         }
     }
 }
Пример #13
0
 public string EvaluateIdentifierOrExpr(Ast.IdentifierOrExpr idOrExpr, ScriptEnv env)
 {
     if (idOrExpr.Expr != null)
     {
         return(EvaluateExpr <string>(idOrExpr.Expr, env));
     }
     else
     {
         return(idOrExpr.Identifier);
     }
 }
Пример #14
0
 private void ExecuteThrowStmt(Ast.ThrowStmt stmt, ScriptEnv env)
 {
     if (stmt.HasErrorValues)
     {
         var errorMessage = EvaluateExpr(stmt.Message, env);;
         Throw(env, errorMessage);
     }
     else
     {
         env.DidThrow = true;
     }
 }
Пример #15
0
        private void ExecuteForStmt(Ast.ForStmt stmt, ScriptEnv env)
        {
            var firstNumber = EvaluateExpr <long>(stmt.FirstNumberExpr, env);
            var lastNumber  = EvaluateExpr <long>(stmt.LastNumberExpr, env);

            long step = firstNumber <= lastNumber ? 1 : -1;

            if (stmt.StepExpr != null)
            {
                step = EvaluateExpr <long>(stmt.StepExpr, env);
            }

            if (step == 0)
            {
                throw new ScriptException("The STEP value in a FOR statement must not be zero.");
            }
            else if (step < 0 && firstNumber < lastNumber)
            {
                throw new ScriptException(
                          "The STEP value in a FOR statement must be positive if \"first-number\" < \"last-number\".");
            }
            else if (step > 0 && firstNumber > lastNumber)
            {
                throw new ScriptException(
                          "The STEP value in a FOR statement must be negative if \"first-number\" > \"last-number\".");
            }

            var  upward  = step > 0;
            long counter = firstNumber;

            while ((upward && counter <= lastNumber) || (!upward && counter >= lastNumber))
            {
                env.Vars[stmt.VariableName] = counter;

                ExecuteBlock(stmt.Block, env);
                if (env.DidReturn || env.DidThrow)
                {
                    return;
                }
                else if (env.DidBreak)
                {
                    env.DidBreak = false;
                    break;
                }
                else if (env.DidContinue)
                {
                    env.DidContinue = false;
                }

                counter += step;
            }
        }
Пример #16
0
        private void ExecuteSetStmt(Ast.SetStmt stmt, ScriptEnv env)
        {
            var name = stmt.VariableName.ToLower();

            if (env.Vars.ContainsKey(name))
            {
                env.Vars[name] = EvaluateExpr(stmt.InitialValue, env);
            }
            else
            {
                throw new ScriptException($"Attempted to SET the undeclared variable \"{stmt.VariableName}\".");
            }
        }
Пример #17
0
        private void Throw(ScriptEnv env, object errorNumber, object errorMessage, object errorState)
        {
            env.ErrorNumber  = errorNumber;
            env.ErrorMessage = errorMessage;
            env.ErrorState   = errorState;
            env.DidThrow     = true;

            // make the error number, message, and state available via the error_number(), error_message(), and
            // error_state() functions.
            _notebook.UserData.LastError.ErrorNumber  = env.ErrorNumber;
            _notebook.UserData.LastError.ErrorMessage = env.ErrorMessage;
            _notebook.UserData.LastError.ErrorState   = env.ErrorState;
        }
Пример #18
0
        public static bool GetOptionBool(this Ast.OptionsList optionsList, string name, ScriptRunner runner,
                                         ScriptEnv env, bool defaultValue)
        {
            long num = optionsList.GetOption <long>(name, runner, env, defaultValue ? 1 : 0);

            if (num != 0 && num != 1)
            {
                throw new Exception($"{name} must be 0 or 1.");
            }
            else
            {
                return(num == 1);
            }
        }
Пример #19
0
        public static int GetOptionInt(this Ast.OptionsList optionsList, string name, ScriptRunner runner,
                                       ScriptEnv env, int defaultValue, int?minValue = null, int?maxValue = null)
        {
            var longValue = GetOptionLong(optionsList, name, runner, env, defaultValue, minValue, maxValue);

            if (longValue < int.MinValue || longValue > int.MaxValue)
            {
                throw new Exception($"{name} must be a 32-bit integer.");
            }
            else
            {
                return((int)longValue);
            }
        }
Пример #20
0
        public object EvaluateExpr(Ast.Expr expr, ScriptEnv env)
        {
            var dt = _notebook.Query($"SELECT ({expr.Sql})", env.Vars);

            if (dt.Columns.Count == 1 && dt.Rows.Count == 1)
            {
                return(dt.Rows[0][0]);
            }
            else
            {
                throw new ScriptException(
                          $"Evaluation of expression \"{expr.Sql}\" did not produce a value.");
            }
        }
Пример #21
0
        public T EvaluateExpr <T>(Ast.Expr expr, ScriptEnv env)
        {
            var value = EvaluateExpr(expr, env);

            if (typeof(T).IsAssignableFrom(value.GetType()))
            {
                return((T)value);
            }
            else
            {
                throw new ScriptException(
                          $"Evaluation of expression \"{expr.Sql}\" produced a value of type " +
                          $"\"{value.GetType().Name}\" instead of the expected \"{typeof(T).Name}\".");
            }
        }
Пример #22
0
        private void ExecuteDeclareStmt(Ast.DeclareStmt stmt, ScriptEnv env)
        {
            var name = stmt.VariableName.ToLower();
            var declarationExists = env.Vars.ContainsKey(name);

            if (stmt.IsParameter)
            {
                if (env.ParNames.Contains(name))
                {
                    throw new ScriptException($"Duplicate DECLARE for parameter \"{stmt.VariableName}\".");
                }
                else
                {
                    env.ParNames.Add(name);
                }

                if (declarationExists)
                {
                    // do nothing; the parameter value was specified by the caller
                }
                else if (stmt.InitialValue != null)
                {
                    // the caller did not specify a value, but there is an initial value in the DECLARE statement.
                    env.Vars[name] = EvaluateExpr(stmt.InitialValue, env);
                }
                else
                {
                    throw new ScriptException(
                              $"An argument value was not provided for parameter \"{stmt.VariableName}\".");
                }
            }
            else if (declarationExists)
            {
                throw new ScriptException($"Duplicate DECLARE for variable \"{stmt.VariableName}\".");
            }
            else
            {
                if (stmt.InitialValue != null)
                {
                    env.Vars[name] = EvaluateExpr(stmt.InitialValue, env);
                }
                else
                {
                    env.Vars[name] = 0L;
                }
            }
        }
Пример #23
0
        public void Execute(Ast.Script script, ScriptEnv env)
        {
            ExecuteBlock(script.Block, env);

            if (env.DidBreak)
            {
                throw new ScriptException($"Attempted to BREAK outside of a WHILE loop.");
            }
            else if (env.DidContinue)
            {
                throw new ScriptException($"Attempted to CONTINUE outside of a WHILE loop.");
            }
            else if (env.DidThrow)
            {
                throw new UncaughtErrorScriptException(env.ErrorNumber, env.ErrorMessage, env.ErrorState);
            }
        }
        private ImportCsvStmtRunner(INotebook notebook, ScriptEnv env, ScriptRunner runner, Ast.ImportCsvStmt stmt)
        {
            _notebook = notebook;
            _env      = env;
            _runner   = runner;
            _stmt     = stmt;

            foreach (var option in _stmt.OptionsList.GetOptionKeys())
            {
                switch (option)
                {
                case "SKIP_LINES":
                    _skipLines = _stmt.OptionsList.GetOptionLong(option, _runner, _env, 0, minValue: 0);
                    break;

                case "TAKE_LINES":
                    _takeLines = _stmt.OptionsList.GetOptionLong(option, _runner, _env, -1, minValue: -1);
                    break;

                case "HEADER_ROW":
                    _headerRow = _stmt.OptionsList.GetOptionBool(option, _runner, _env, true);
                    break;

                case "TRUNCATE_EXISTING_TABLE":
                    _truncateExistingTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "TEMPORARY_TABLE":
                    _temporaryTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "FILE_ENCODING":
                    _fileEncoding = _stmt.OptionsList.GetOptionEncoding(option, _runner, _env);
                    break;

                case "IF_CONVERSION_FAILS":
                    _ifConversionFails = (IfConversionFails)_stmt.OptionsList.GetOptionLong(
                        option, _runner, _env, 1, minValue: 1, maxValue: 3);
                    break;

                default:
                    throw new Exception($"\"{option}\" is not a recognized option name.");
                }
            }
        }
Пример #25
0
        private void ExecutePrintStmt(Ast.PrintStmt stmt, ScriptEnv env)
        {
            var value = EvaluateExpr(stmt.Value, env);

            var byteArray = value as byte[];

            if (byteArray != null)
            {
                if (ArrayUtil.IsSqlArray(byteArray))
                {
                    env.Output.TextOutput.Add(
                        "[" + string.Join(", ", ArrayUtil.GetArrayElements(byteArray)) + "]"
                        );
                    return;
                }
            }

            env.Output.TextOutput.Add(value.ToString());
        }
Пример #26
0
        private ImportTxtStmtRunner(INotebook notebook, ScriptEnv env, ScriptRunner runner, Ast.ImportTxtStmt stmt)
        {
            _notebook = notebook;
            _env      = env;
            _runner   = runner;
            _stmt     = stmt;

            _filePath             = GetFilePath();
            _tableName            = _runner.EvaluateIdentifierOrExpr(_stmt.TableName, _env);
            _lineNumberColumnName = _stmt.LineNumberColumnName == null ? null : _runner.EvaluateIdentifierOrExpr(_stmt.LineNumberColumnName, _env);
            _textColumnName       = _stmt.TextColumnName == null ? null : _runner.EvaluateIdentifierOrExpr(_stmt.TextColumnName, _env);

            foreach (var option in _stmt.OptionsList.GetOptionKeys())
            {
                switch (option)
                {
                case "SKIP_LINES":
                    _skipLines = _stmt.OptionsList.GetOptionLong(option, _runner, _env, 0, minValue: 0);
                    break;

                case "TAKE_LINES":
                    _takeLines = _stmt.OptionsList.GetOptionLong(option, _runner, _env, -1, minValue: -1);
                    break;

                case "TRUNCATE_EXISTING_TABLE":
                    _truncateExistingTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "TEMPORARY_TABLE":
                    _temporaryTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "FILE_ENCODING":
                    _fileEncoding = _stmt.OptionsList.GetOptionEncoding(option, _runner, _env);
                    break;

                default:
                    throw new Exception($"\"{option}\" is not a recognized option name.");
                }
            }
        }
Пример #27
0
        private void ExecuteIfStmt(Ast.IfStmt stmt, ScriptEnv env)
        {
            var condition = EvaluateExpr <long>(stmt.Condition, env);

            if (condition == 0)
            {
                if (stmt.ElseBlock != null)
                {
                    ExecuteBlock(stmt.ElseBlock, env);
                }
            }
            else if (condition == 1)
            {
                ExecuteBlock(stmt.Block, env);
            }
            else
            {
                throw new ScriptException(
                          $"Evaluation of IF condition expression \"{stmt.Condition.Sql}\" " +
                          $"produced a value of {condition} instead of the expected 0 or 1.");
            }
        }
Пример #28
0
        public static Encoding GetOptionEncoding(this Ast.OptionsList optionsList, string name, ScriptRunner runner,
                                                 ScriptEnv env)
        {
            var encodingNum = optionsList.GetOptionInt(name, runner, env, 0);

            if (encodingNum == 0)
            {
                return(null);
            }
            else if (encodingNum < 0 || encodingNum > 65535)
            {
                throw new Exception($"{name} must be between 0 and 65535.");
            }
            else
            {
                Encoding encoding = null;
                try {
                    encoding = Encoding.GetEncoding(encodingNum);
                } catch (ArgumentOutOfRangeException) {
                    // invalid codepage
                } catch (ArgumentException) {
                    // invalid codepage
                } catch (NotSupportedException) {
                    // invalid codepage
                }

                if (encoding == null)
                {
                    throw new Exception($"The code page {encodingNum} is invalid or is not supported on this system.");
                }
                else
                {
                    return(encoding);
                }
            }
        }
        // must be run from the SQLite thread
        public static void Run(INotebook notebook, ScriptEnv env, ScriptRunner runner, Ast.ExportTxtStmt stmt)
        {
            var exporter = new ExportTxtStmtRunner(notebook, env, runner, stmt);

            exporter.Export();
        }
Пример #30
0
        private ImportXlsStmtRunner(INotebook notebook, ScriptEnv env, ScriptRunner runner, Ast.ImportXlsStmt stmt)
        {
            _notebook = notebook;
            _env      = env;
            _runner   = runner;
            _stmt     = stmt;

            _filePath = _runner.EvaluateExpr <string>(_stmt.FilenameExpr, _env);
            if (!File.Exists(_filePath))
            {
                throw new Exception($"The specified XLS/XLSX file was not found: \"{_filePath}\"");
            }

            if (_stmt.WhichSheetExpr != null)
            {
                _whichSheet = _runner.EvaluateExpr(_stmt.WhichSheetExpr, _env);
            }

            int?index;

            foreach (var option in _stmt.OptionsList.GetOptionKeys())
            {
                switch (option)
                {
                case "FIRST_ROW":
                    _firstRowIndex = _stmt.OptionsList.GetOptionInt(option, _runner, _env, 1, minValue: 1) - 1;
                    break;

                case "LAST_ROW":
                    var lastRowNum = _stmt.OptionsList.GetOptionInt(option, _runner, _env, 0, minValue: 0);
                    if (lastRowNum == 0)
                    {
                        _lastRowIndex = null;
                    }
                    else
                    {
                        _lastRowIndex = lastRowNum - 1;
                    }
                    break;

                case "FIRST_COLUMN":
                    index = XlsUtil.ColumnRefToIndex(_stmt.OptionsList.GetOption <object>(option, _runner, _env, null));
                    if (index.HasValue)
                    {
                        _firstColumnIndex = index.Value;
                    }
                    else
                    {
                        throw new Exception($"The {option} option must be a valid column number or string.");
                    }
                    break;

                case "LAST_COLUMN":
                    var lastColumnValue = _stmt.OptionsList.GetOption <object>(option, _runner, _env, null);
                    if (lastColumnValue.Equals(0))
                    {
                        _lastColumnIndex = null;
                        break;
                    }
                    index = XlsUtil.ColumnRefToIndex(lastColumnValue);
                    if (index.HasValue)
                    {
                        _lastColumnIndex = index.Value;
                    }
                    else
                    {
                        throw new Exception($"The {option} option must be a valid column number or string.");
                    }
                    break;

                case "HEADER_ROW":
                    _headerRow = _stmt.OptionsList.GetOptionBool(option, _runner, _env, true);
                    break;

                case "TRUNCATE_EXISTING_TABLE":
                    _truncateExistingTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "TEMPORARY_TABLE":
                    _temporaryTable = _stmt.OptionsList.GetOptionBool(option, _runner, _env, false);
                    break;

                case "IF_CONVERSION_FAILS":
                    _ifConversionFails = (IfConversionFails)_stmt.OptionsList.GetOptionLong(
                        option, _runner, _env, 1, minValue: 1, maxValue: 3);
                    break;

                default:
                    throw new Exception($"\"{option}\" is not a recognized option name.");
                }
            }
        }