예제 #1
0
파일: ShellProgram.cs 프로젝트: apkd/LiteDB
        public static void Start(InputCommand input, Display display)
        {
            var commands = new List<ICommand>();
            var env = new Env();

            // register commands
            RegisterCommands(commands);

            display.TextWriters.Add(Console.Out);

            // show welcome message
            display.WriteWelcome();

            while (input.Running)
            {
                // read next command from user or queue
                var cmd = input.ReadCommand();

                if (string.IsNullOrEmpty(cmd)) continue;

                try
                {
                    var s = new StringScanner(cmd);

                    var found = false;

                    // test all commands
                    foreach (var command in commands)
                    {
                        if (!command.IsCommand(s)) continue;

                        // test if command it's only shell command
                        if (command.Access == DataAccess.None)
                        {
                            command.Execute(null, s, display, input, env);
                        }
                        else
                        {
                            using (var engine = env.CreateEngine(command.Access))
                            {
                                command.Execute(engine, s, display, input, env);
                            }
                        }

                        found = true;
                        break;
                    }

                    if (!found) throw new ShellExpcetion("Command not found");
                }
                catch (Exception ex)
                {
                    display.WriteError(ex.Message);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// If command is a console command, execute and returns true - if not, just returns false
        /// </summary>
        public static bool TryExecute(string command, ref IShellEngine engine, Display display, InputCommand input)
        {
            var s = new StringScanner(command);

            foreach (var cmd in _commands)
            {
                if (cmd.IsCommand(s))
                {
                    cmd.Execute(ref engine, s, display, input);
                    return true;
                }
            }

            return false;
        }
예제 #3
0
        /// <summary>
        /// If command is a console command, execute and returns true - if not, just returns false
        /// </summary>
        public static bool TryExecute(string command, LiteShell shell, Display display, InputCommand input)
        {
            var s = new StringScanner(command);

            foreach (var cmd in Commands)
            {
                if (cmd.IsCommand(s))
                {
                    cmd.Execute(shell, s, display, input);
                    return true;
                }
            }

            return false;
        }
예제 #4
0
        public BsonValue Run(DbEngine engine, string command)
        {
            if (string.IsNullOrEmpty(command)) return BsonValue.Null;

            var s = new StringScanner(command);

            foreach (var cmd in _commands)
            {
                if (cmd.IsCommand(s))
                {
                    return cmd.Execute(engine, s);
                }
            }

            throw LiteException.InvalidCommand(command);
        }
예제 #5
0
 public abstract void Execute(ref IShellEngine engine, StringScanner s, Display display, InputCommand input);
예제 #6
0
 /// <summary>
 /// Read Id file
 /// </summary>
 public string ReadId(StringScanner s)
 {
     return(s.Scan(LiteFileInfo.ID_PATTERN.Substring(1, LiteFileInfo.ID_PATTERN.Length - 2)));
 }
예제 #7
0
 public bool IsCommand(StringScanner s)
 {
     return(this.IsCollectionCommand(s, "select"));
 }
예제 #8
0
 public bool IsCommand(StringScanner s)
 {
     return(this.IsCollectionCommand(s, "drop[iI]ndex"));
 }
예제 #9
0
 public bool IsCommand(StringScanner s)
 {
     return(this.IsFileCommand(s, "delete"));
 }
예제 #10
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col = this.ReadCollection(engine, s);

            // single document update
            if (s.Match(@"\s*\{"))
            {
                var doc = JsonSerializer.Deserialize(s.ToString()).AsDocument;

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, doc));
            }
            // query update
            else
            {
                // db.colName.update
                //     field = value,
                //     array += valueToAdd,
                // where _id = 1
                //   and ...

                var query   = Query.All();
                var updates = new Update();

                while (!s.HasTerminated)
                {
                    var path   = BsonExpression.ReadExpression(s, true, true).Source;
                    var action = s.Scan(@"\s*(\+)?=\s*", 1).ThrowIfEmpty("Invalid operator (support = or +=)", s);
                    var value  = this.ReadBsonValue(s);
                    var expr   = value == null?BsonExpression.ReadExpression(s, true, false)?.Source : null;

                    if (action == "+" && value != null)
                    {
                        updates.Add(path, value);
                    }
                    else if (action == "+" && expr != null)
                    {
                        updates.AddExpr(path, expr);
                    }
                    else if (action == "" && value != null)
                    {
                        updates.Set(path, value);
                    }
                    else if (action == "" && expr != null)
                    {
                        updates.SetExpr(path, expr);
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }

                    s.Scan(@"\s*");

                    if (s.Scan(@",\s*").Length > 0)
                    {
                        continue;
                    }
                    else if (s.Scan(@"where\s*").Length > 0 || s.HasTerminated)
                    {
                        break;
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }
                }

                if (!s.HasTerminated)
                {
                    query = this.ReadQuery(s, false);
                }

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, query, updates));
            }
        }
예제 #11
0
 public abstract void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input);
예제 #12
0
 public bool IsCommand(StringScanner s)
 {
     return(s.Scan(@"db.info$").Length > 0);
 }
예제 #13
0
 public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
 {
     yield return(engine.Info());
 }
예제 #14
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col = this.ReadCollection(engine, s);

            yield return(engine.DropCollection(col));
        }
예제 #15
0
 public bool IsFileCommand(StringScanner s, string command)
 {
     return(s.Scan(@"fs\." + command + @"\s*").Length > 0);
 }
예제 #16
0
 public abstract bool IsCommand(StringScanner s);
예제 #17
0
 /// <summary>
 /// Read collection name from db.(collection).(command)
 /// </summary>
 public string ReadCollection(LiteEngine db, StringScanner s)
 {
     return(s.Scan(@"db\.([\w-]+)\.\w+\s*", 1));
 }
예제 #18
0
 public bool IsCollectionCommand(StringScanner s, string command)
 {
     return(s.Match(@"db\.[\w-]+\." + command));
 }
예제 #19
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col = this.ReadCollection(engine, s);

            // single document update
            if (s.Match(@"\s*\{"))
            {
                var doc = JsonSerializer.Deserialize(s.ToString()).AsDocument;

                s.ThrowIfNotFinish();

                yield return(engine.Update(col, doc));
            }
            // query update
            else
            {
                // db.colName.update
                //     field = value,
                //     array += valueToAdd,
                // where _id = 1
                //   and ...

                var updates = new List <UpdateData>();
                var query   = Query.All();

                while (!s.HasTerminated)
                {
                    var path   = BsonExpression.ReadExpression(s, true, true).Source;
                    var action = s.Scan(@"\s*\+?=\s*").Trim().ThrowIfEmpty("Invalid operator (support = or +=)", s);
                    var value  = this.ReadBsonValue(s);
                    var expr   = value == null?BsonExpression.ReadExpression(s, true, false) : null;

                    if (action != "+=" && action != "=")
                    {
                        throw LiteException.SyntaxError(s);
                    }
                    if (value == null && expr == null)
                    {
                        throw LiteException.SyntaxError(s);
                    }

                    updates.Add(new UpdateData {
                        Path = path, Value = value, Expr = expr, Add = action == "+="
                    });

                    s.Scan(@"\s*");

                    if (s.Scan(@",\s*").Length > 0)
                    {
                        continue;
                    }
                    else if (s.Scan(@"where\s*").Length > 0 || s.HasTerminated)
                    {
                        break;
                    }
                    else
                    {
                        throw LiteException.SyntaxError(s);
                    }
                }

                if (!s.HasTerminated)
                {
                    query = this.ReadQuery(s, false);
                }

                s.ThrowIfNotFinish();

                // fetch documents to update
                var count = engine.Update(col, this.FetchDocuments(engine, col, query, updates));

                yield return(count);
            }
        }
예제 #20
0
 public abstract void Execute(LiteShell shell, StringScanner s, Display display, InputCommand input);
예제 #21
0
        public static void Start(InputCommand input, Display display)
        {
            var commands = new List <ICommand>();
            var env      = new Env();

            LiteEngine engine = null;

            // register commands
            RegisterCommands(commands);

            display.TextWriters.Add(Console.Out);

            // show welcome message
            display.WriteWelcome();

            while (input.Running)
            {
                // read next command from user or queue
                var cmd = input.ReadCommand();

                if (string.IsNullOrEmpty(cmd))
                {
                    continue;
                }

                try
                {
                    var s = new StringScanner(cmd);

                    var found = false;

                    // test all commands
                    foreach (var command in commands)
                    {
                        if (!command.IsCommand(s))
                        {
                            continue;
                        }

                        command.Execute(engine, s, display, input, env);

                        if (env.Filename != null && engine == null)
                        {
                            engine = env.CreateEngine(DataAccess.Write);
                        }

                        found = true;
                        break;
                    }

                    if (!found)
                    {
                        throw new ShellExpcetion("Command not found");
                    }
                }
                catch (Exception ex)
                {
                    display.WriteError(ex.Message);
                }
            }
        }
예제 #22
0
 public abstract void Execute(ref IShellEngine engine, StringScanner s, Display display, InputCommand input);
예제 #23
0
        public IEnumerable <BsonValue> Execute(StringScanner s, LiteEngine engine)
        {
            var col    = this.ReadCollection(engine, s);
            var fields = new Dictionary <string, BsonExpression>();
            var index  = 0;

            // read all fields definitions (support AS as keyword no name field)
            while (!s.HasTerminated)
            {
                // try read any kind of expression
                var expression = BsonExpression.ReadExpression(s, false, false);

                // if not found a valid one, try read only as path (will add $. before)
                if (expression == null)
                {
                    expression = BsonExpression.ReadExpression(s, true, true);
                }
                //var expression = BsonExpression.ReadExpression(s, true, false);

                var key = s.Scan(@"\s*as\s+([\w-]+)", 1).TrimToNull()
                          ?? this.NamedField(expression)
                          ?? ("expr" + (++index));

                // if key already exits, add with another name
                while (fields.ContainsKey(key))
                {
                    key = "expr" + (++index);
                }

                fields.Add(key, expression);

                if (s.Scan(@"\s*,\s*").Length > 0)
                {
                    continue;
                }
                break;
            }

            // select command required output value, path or expression
            if (fields.Count == 0)
            {
                throw LiteException.SyntaxError(s, "Missing select path");
            }

            var query = Query.All();

            if (s.Scan(@"\s*where\s*").Length > 0)
            {
                query = this.ReadQuery(s, true);
            }

            var skipLimit = this.ReadSkipLimit(s);
            var includes  = this.ReadIncludes(s);

            s.ThrowIfNotFinish();

            var docs = engine.Find(col, query, includes, skipLimit.Key, skipLimit.Value);

            foreach (var doc in docs)
            {
                // if is a single value, return as just field
                if (fields.Count == 1)
                {
                    foreach (var value in fields.Values.First().Execute(doc, false))
                    {
                        yield return(value);
                    }
                }
                else
                {
                    var output = new BsonDocument();

                    foreach (var field in fields)
                    {
                        output[field.Key] = field.Value.Execute(doc, true).First();
                    }

                    yield return(output);
                }
            }
        }
예제 #24
0
 public abstract bool IsCommand(StringScanner s);
예제 #25
0
 public bool IsCommand(StringScanner s)
 {
     return(this.IsFileCommand(s, "upload"));
 }
예제 #26
0
 public abstract void Execute(ref LiteDatabase db, StringScanner s, Display display, InputCommand input);