示例#1
0
        private async Task <IBifoqlObject> ApplyContainsOperator(IBifoqlObject subject, IBifoqlObject search)
        {
            var subjectAsStringObj = subject as IBifoqlString;

            if (subjectAsStringObj != null)
            {
                var searchAsStringObj = search as IBifoqlString;
                if (searchAsStringObj == null)
                {
                    return(new AsyncBoolean(false));
                }

                var subjectAsString = await subjectAsStringObj.Value;
                var searchAsString  = await searchAsStringObj.Value;

                return(new AsyncBoolean(subjectAsString.Contains(searchAsString)));
            }

            var subjectAsArray = subject as IBifoqlArrayInternal;

            if (subjectAsArray != null)
            {
                foreach (var itemObj in subjectAsArray)
                {
                    var item = await(itemObj());
                    if (await item.IsEqualTo(search))
                    {
                        return(new AsyncBoolean(true));
                    }
                }
            }

            return(new AsyncBoolean(false));
        }
示例#2
0
        internal static async Task <IBifoqlObject> GetDefaultValue(this IBifoqlObject o)
        {
            var func = GetDefaultValueFunc(o);

            return(func == null
                ? o
                : await func());
        }
示例#3
0
 public VariableScope AddVariable(string key, IBifoqlObject value)
 {
     if (ContainsKey(key))
     {
         throw new Exception($"Variable {key} already defined");
     }
     return(new VariableScope(this, key, value));
 }
示例#4
0
        private static Func <Task <IBifoqlObject> > GetDefaultValueFunc(IBifoqlObject o)
        {
            var hasDefault = o as IBifoqlHasDefaultValue;

            if (hasDefault != null)
            {
                return(hasDefault.GetDefaultValue());
            }
            return(null);
        }
示例#5
0
        private async Task <IBifoqlObject> GetKeyFromObject(IBifoqlObject target, QueryContext context)
        {
            // Propagate errors.
            if (target is IBifoqlError)
            {
                return(target);
            }

            var lookup = target as IBifoqlLookupInternal;

            if (lookup != null)
            {
                Func <Task <IBifoqlObject> > value;
                if (lookup.TryGetValue(_key, out value))
                {
                    return(await value());
                }
                else
                {
                    return(new AsyncError(Location, $"key '{_key}' not found"));
                }
            }

            var array = target as IBifoqlArrayInternal;

            if (array != null)
            {
                var result = new List <Func <Task <IBifoqlObject> > >();

                foreach (var item in array)
                {
                    var resolvedItem = await item();

                    var entry = GetKeyFromObject(resolvedItem, context);
                    result.Add(() => entry);
                }

                return(new AsyncArray(result));
            }

            if (target is IBifoqlUndefined)
            {
                return(AsyncUndefined.Instance);
            }

            var deferred = target as IBifoqlDeferredQueryInternal;

            if (deferred != null)
            {
                return(DeferredQueryWrapper.AddToQuery(deferred, RightHandSideString()));
            }

            return(new AsyncError(this.Location, "key expression must be applied to array or map"));
        }
示例#6
0
        public Task <bool> IsEqualTo(IBifoqlObject other)
        {
            if (this == other)
            {
                return(Task.FromResult(true));
            }

            var o = other as AsyncIndex;

            return(Task.FromResult(o?._lookup == this._lookup));
        }
示例#7
0
        public static async Task <IBifoqlObject> EvaluateDeferredQuery(IBifoqlObject bifoqlObject)
        {
            var deferred = bifoqlObject as DeferredQueryWrapper;

            if (deferred != null)
            {
                return((await deferred._obj.EvaluateQuery(deferred._query)).ToBifoqlObject());
            }
            else
            {
                return(bifoqlObject);
            }
        }
示例#8
0
        public Task <bool> IsEqualTo(IBifoqlObject other)
        {
            if (this == other)
            {
                return(Task.FromResult(true));
            }
            else
            {
                var o = other as AsyncError;

                return(Task.FromResult(o != null && Message == o.Message));
            }
        }
示例#9
0
        public async Task <bool> IsEqualTo(IBifoqlObject other)
        {
            if (this == other)
            {
                return(true);
            }

            var o = other as IBifoqlNumber;

            if (o == null)
            {
                return(false);
            }

            return((await o.Value) == await Value);
        }
示例#10
0
        public bool TryGetValue(string key, out IBifoqlObject result)
        {
            if (_name == key)
            {
                result = _value;
                return(true);
            }

            if (_previous != null)
            {
                return(_previous.TryGetValue(key, out result));
            }

            result = null;
            return(false);
        }
示例#11
0
        private async Task <IBifoqlObject> ApplyStartsWithEndsWithOperator(IBifoqlObject subject, IBifoqlObject target, bool startsWith)
        {
            var subjectAsStringObj = subject as IBifoqlString;
            var targetAsStringObj  = target as IBifoqlString;

            if (subjectAsStringObj != null && targetAsStringObj != null)
            {
                var subjectAsString = await subjectAsStringObj.Value;
                var targetAsString  = await targetAsStringObj.Value;

                var result = startsWith ? subjectAsString.StartsWith(targetAsString) : subjectAsString.EndsWith(targetAsString);

                return(new AsyncBoolean(result));
            }

            return(new AsyncError(this.Location, "Don't know how to do starts_with or ends_with on these types"));
        }
示例#12
0
        protected static void RunTest(object expected, string query, object input = null, IReadOnlyDictionary <string, object> arguments = null, IReadOnlyDictionary <string, CustomFunction> customFunctions = null)
        {
            if (input is JToken)
            {
                input = Helpers.ObjectConverter.ToBifoqlObject(input);
            }

            IBifoqlObject inputObj = input?.ToBifoqlObject();

            var result = Query(inputObj, query, arguments, customFunctions).Result;

            var actualJson = JsonConvert.SerializeObject(result);

            var expectedJson = JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(JsonConvert.SerializeObject(expected)));

            Assert.Equal(expectedJson, actualJson);
        }
示例#13
0
        private async Task <IBifoqlObject> ApplyInequalityOperator(IBifoqlObject lhs, IBifoqlObject rhs, string @operator)
        {
            var lhsNum = lhs as IBifoqlNumber;
            var rhsNum = rhs as IBifoqlNumber;

            if (lhsNum != null && rhsNum != null)
            {
                var lhsVal = await lhsNum.Value;
                var rhsVal = await rhsNum.Value;
                switch (@operator)
                {
                case "<": return(new AsyncBoolean(lhsVal < rhsVal));

                case ">": return(new AsyncBoolean(lhsVal > rhsVal));

                case "<=": return(new AsyncBoolean(lhsVal <= rhsVal));

                case ">=": return(new AsyncBoolean(lhsVal >= rhsVal));

                default: return(new AsyncError(this.Location, $"Unknown inequality {@operator}"));
                }
            }

            var lhsStr = lhs as IBifoqlString;
            var rhsStr = rhs as IBifoqlString;

            if (lhsStr != null && rhsStr != null)
            {
                var lhsVal = await lhsStr.Value;
                var rhsVal = await rhsStr.Value;
                switch (@operator)
                {
                case "<": return(new AsyncBoolean(lhsVal.CompareTo(rhsVal) == -1));

                case ">": return(new AsyncBoolean(lhsVal.CompareTo(rhsVal) == 11));

                case "<=": return(new AsyncBoolean(lhsVal.CompareTo(rhsVal) != 1));

                case ">=": return(new AsyncBoolean(lhsVal.CompareTo(rhsVal) != -1));

                default: return(new AsyncError(this.Location, $"Unknown inequality {@operator}"));
                }
            }

            return(new AsyncError(this.Location, $"Invalid equality operation"));
        }
示例#14
0
        // IEnumerator IEnumerable.GetEnumerator()
        // {
        //     return GetEnumerator();
        // }

        public async Task <bool> IsEqualTo(IBifoqlObject other)
        {
            if (this == other)
            {
                return(true);
            }

            var otherDict = other as IBifoqlMapInternal;

            if (otherDict == null)
            {
                return(false);
            }
            if (otherDict.Count != this.Count)
            {
                return(false);
            }

            // First go through the things that don't needs async; they'll be fast and cheap
            foreach (var key in this.Keys)
            {
                var unresolvedThis = this[key];
                Func <Task <IBifoqlObject> > unresolvedThat;
                if (!otherDict.TryGetValue(key, out unresolvedThat))
                {
                    return(false);
                }

                if (unresolvedThis == unresolvedThat)
                {
                    continue;
                }

                var thisObj = await unresolvedThis();

                var thatObj = await unresolvedThat();

                if (!(await thisObj.IsEqualTo(thatObj)))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#15
0
        private static Func <Task <IBifoqlObject> > GetDefaultValueFromIndexFunc(IBifoqlObject o)
        {
            if (o is IBifoqlIndexInternal)
            {
                if (o is IBifoqlHasDefaultValue)
                {
                    return(((IBifoqlHasDefaultValue)o).GetDefaultValue());
                }

                // Pass zero arguments to the index.
                return(async() => {
                    var obj = await((IBifoqlIndexInternal)o).Lookup(IndexArgumentList.CreateEmpty());
                    return obj.ToBifoqlObject();
                });
            }

            return(null);
        }
示例#16
0
        public async Task <bool> IsEqualTo(IBifoqlObject other)
        {
            if (this == other)
            {
                return(true);
            }

            var otherArray = other as IBifoqlArrayInternal;

            if (otherArray == null)
            {
                return(false);
            }
            if (otherArray.Count != this.Count)
            {
                return(false);
            }

            // First go through the things that don't needs async; they'll be fast and cheap
            for (var i = 0; i < Count; i++)
            {
                var unresolvedThis = this[i];
                var unresolvedThat = otherArray[i];

                if (unresolvedThis == unresolvedThat)
                {
                    continue;
                }

                var thisObj = await unresolvedThis();

                var thatObj = await unresolvedThat();

                if (!(await thisObj.IsEqualTo(thatObj)))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#17
0
        private IBifoqlObject AddArray(IBifoqlArrayInternal lhsArray, IBifoqlObject rhs)
        {
            var result = new List <Func <Task <IBifoqlObject> > >();

            foreach (var item in lhsArray)
            {
                result.Add(item);
            }

            var rhsArray = rhs as IBifoqlArrayInternal;

            if (rhsArray != null)
            {
                foreach (var item in rhsArray)
                {
                    result.Add(item);
                }
            }
            else
            {
                result.Add(() => Task.FromResult(rhs));
            }
            return(new AsyncArray(result));
        }
示例#18
0
        public static async Task <IBifoqlObject> Count(Location location, QueryContext context, IBifoqlObject value)
        {
            var str = value as IBifoqlString;

            if (str != null)
            {
                return(new AsyncNumber((await str.Value).Length));
            }

            var arr = value as IBifoqlArrayInternal;

            if (arr != null)
            {
                return(new AsyncNumber(arr.Count));
            }

            return(new AsyncError(location, "length accepts a number or string argument"));
        }
示例#19
0
 public VariableScope(VariableScope previous, string name, IBifoqlObject value)
 {
     _previous = previous == Empty ? null : previous;
     _name     = name;
     _value    = value;
 }
示例#20
0
        private static async Task <IBifoqlObject> MaxMin(Location location, QueryContext context, IBifoqlArrayInternal list, IBifoqlExpression keyQuery, bool max)
        {
            var pairs = new List <KeyValuePair <IBifoqlObject, IBifoqlObject> >();

            foreach (var value in list)
            {
                var val = await value();

                var newContext = context.ReplaceTarget(val);

                var key = keyQuery == null ? val : await keyQuery.Evaluate(newContext);

                pairs.Add(new KeyValuePair <IBifoqlObject, IBifoqlObject>(key, val));
            }

            var           resultNum = max ? double.MinValue : double.MaxValue;
            string        resultStr = null;
            bool          first     = true;
            bool          isNum     = false;
            IBifoqlObject result    = null;

            foreach (var val in pairs)
            {
                var curr = val.Key;
                if (first)
                {
                    first = false;
                    isNum = curr is IBifoqlNumber;
                }

                if (isNum)
                {
                    var currNumObj = curr as IBifoqlNumber;
                    if (currNumObj == null)
                    {
                        return(new AsyncError(location, "To take max, all members of the list must be a number or string"));
                    }
                    var currNum = await currNumObj.Value;

                    if ((max && currNum > resultNum) || (!max && currNum < resultNum))
                    {
                        resultNum = currNum;
                        result    = val.Value;
                    }
                }
                else
                {
                    var currStrObj = curr as IBifoqlString;
                    if (currStrObj == null)
                    {
                        return(new AsyncError(location, "To take max, all members of the list must be a number or string"));
                    }
                    var currStr = await currStrObj.Value;

                    if (resultStr == null || currStr.CompareTo(resultStr) == (max ? 1 : -1))
                    {
                        resultStr = currStr;
                        result    = val.Value;
                    }
                }
            }

            return(result);
        }
示例#21
0
 public Task <bool> IsEqualTo(IBifoqlObject o)
 {
     throw new Exception("Can't check equality on a lookup");
 }
示例#22
0
 public Task <bool> IsEqualTo(IBifoqlObject o)
 {
     throw new NotImplementedException();
 }
示例#23
0
 public DeferredQueryObject(object remoteObject)
 {
     _remoteObject = remoteObject.ToBifoqlObject();
 }
示例#24
0
        public Task <bool> IsEqualTo(IBifoqlObject o)
        {
            var other = o as AsyncExpression;

            return(Task.FromResult(other?._expr == this._expr));
        }
示例#25
0
 private static Task <IBifoqlObject> ToTask(IBifoqlObject o)
 {
     return(Task.FromResult(o));
 }
示例#26
0
        public Task <bool> IsEqualTo(IBifoqlObject o)
        {
            var other = o as DeferredQueryWrapper;

            return(Task.FromResult(o != null && _obj == other._obj && _query == other._query));
        }
示例#27
0
 public Task <bool> IsEqualTo(IBifoqlObject o)
 {
     return(Task.FromResult(this == o));
 }
示例#28
0
 public LiteralExpr(Location location, IBifoqlObject literal) : base(location)
 {
     Literal = literal;
 }
示例#29
0
 public Task <bool> IsEqualTo(IBifoqlObject o)
 {
     return(Task.FromResult(o is DeferredQueryObject));
 }
示例#30
0
 public Task <bool> IsEqualTo(IBifoqlObject other)
 {
     return(Task.FromResult(other is IBifoqlNull || other == null));
 }