public void Smart_parse_values() { object vi = JExtensions.SmartParse("123"); Assert.IsTrue(vi is int); object vf = JExtensions.SmartParse("123,1"); Assert.IsTrue(vf is double); vf = JExtensions.SmartParse("123.1"); Assert.IsTrue(vf is double); var vd = JExtensions.SmartParse("2012-05-01"); Assert.IsTrue(vd is DateTimeOffset); vd = JExtensions.SmartParse("01/05/2012"); Assert.IsTrue(vd is DateTimeOffset); // looks like a data but it is not correct so it will be parsed like a string vd = JExtensions.SmartParse("45/15/2012"); Assert.IsTrue(vd is string); var vb = JExtensions.SmartParse("true"); Assert.IsTrue(vb is bool); vb = JExtensions.SmartParse("false"); Assert.IsTrue(vb is bool); Assert.IsNull(JExtensions.SmartParse("null")); }
private static void ParseWhere(Node @where, OrQuery query, CollectionSchema schema) { var orNodes = where.Children.Where(c => c.Token == "or").ToList(); if (orNodes.Count != 1) { throw new NotSupportedException("Query too complex"); } var orNode = orNodes.Single(); var andNodes = orNode.Children.Where(c => c.Token == "and").ToList(); foreach (var andNode in andNodes) { var andQuery = new AndQuery(); foreach (var node in andNode.Children) { var operands = node.Children.Select(c => c.Token).ToList(); var op = ParseOperator(node.Token, operands.LastOrDefault()); if (op == QueryOperator.In || op == QueryOperator.NotIn) { var metadata = schema.KeyByName(operands[0]); if (metadata != null) { List <KeyValue> values = new List <KeyValue>(); foreach (var val in operands.Skip(1)) { object value = JExtensions.SmartParse(val); values.Add(new KeyValue(value, metadata)); } andQuery.Elements.Add(new AtomicQuery(metadata, values, op)); } else { throw new NotSupportedException($"Can not parse query after IN operator. {operands[0]} is a server-side value"); } } else if (op == QueryOperator.Contains || op == QueryOperator.NotContains) // for contains operator the collection property should be at the left side { var metadata = schema.KeyByName(operands[0]); object value = JExtensions.SmartParse(operands[1]); andQuery.Elements.Add(new AtomicQuery(metadata, new KeyValue(value, metadata), op)); } else if (op == QueryOperator.StrStartsWith || op == QueryOperator.StrEndsWith || op == QueryOperator.StrContains) // for string operators the property should be at the left side { var metadata = schema.KeyByName(operands[0]); object value = operands[1].Trim('%'); andQuery.Elements.Add(new AtomicQuery(metadata, new KeyValue(value, metadata), op)); } else if (operands.Count == 2)// binary operators { var metadata = schema.KeyByName(operands[0]); // by default property name first if (metadata != null) { object value = JExtensions.SmartParse(operands[1]); andQuery.Elements.Add(new AtomicQuery(metadata, new KeyValue(value, metadata), op)); } else // try value first { metadata = schema.KeyByName(operands[1]); if (metadata == null) { throw new NotSupportedException($"Can not parse query. Neither {operands[0]} nor {operands[1]} is a server-side value"); } object value = JExtensions.SmartParse(operands[0]);; andQuery.Elements.Add(new AtomicQuery(metadata, new KeyValue(value, metadata), Reverse(op))); } } } query.Elements.Add(andQuery); } }