/// <summary> /// Execute a query and return its results. /// </summary> /// <typeparam name="T"> /// The type of element returned by the query. /// </typeparam> /// <param name="query"> /// The query to evaluate and get the results for. /// </param> /// <returns> /// Results of the query. /// </returns> internal async Task <IEnumerable <T> > Execute <T>(IMobileServiceTableQuery <T> query) { // Compile the query from the underlying IQueryable's expression // tree MobileServiceTableQueryDescription compiledQuery = this.Compile(query); // Send the query string odata = compiledQuery.ToODataString(); QueryResult result = await this.Execute <T>(query, odata); return(new QueryResultEnumerable <T>( result.TotalCount, result.NextLink, query.Table.MobileServiceClient.Serializer.Deserialize(result.Values, compiledQuery.ProjectionArgumentType).Select( value => { // Apply the projection to the instance transforming it // as desired foreach (Delegate projection in compiledQuery.Projections) { value = projection.DynamicInvoke(value); } return (T)value; }))); }
public Task<JToken> ReadAsync(MobileServiceTableQueryDescription query) { if (query.TableName == MobileServiceLocalSystemTables.OperationQueue || query.TableName == MobileServiceLocalSystemTables.SyncErrors) { MockTable table = GetTable(query.TableName); IEnumerable<JObject> items = table.Values; if (query.TableName == MobileServiceLocalSystemTables.OperationQueue) { string odata = query.ToODataString(); if (odata.Contains("$orderby=sequence desc")) // the query to take total count and max sequence { items = items.OrderBy(o => o.Value<long>("sequence")); } else if (odata.StartsWith("$filter=((tableKind eq ") && odata.Contains("(sequence gt ")) { var sequenceCompareNode = ((BinaryOperatorNode)query.Filter).RightOperand as BinaryOperatorNode; items = items.Where(o => o.Value<long>("sequence") > (long)((ConstantNode)sequenceCompareNode.RightOperand).Value); items = items.OrderBy(o => o.Value<long>("sequence")); } else if (odata.Contains("(sequence gt ")) // the query to get next operation { items = items.Where(o => o.Value<long>("sequence") > (long)((ConstantNode)((BinaryOperatorNode)query.Filter).RightOperand).Value); items = items.OrderBy(o => o.Value<long>("sequence")); } else if (odata.Contains(") and (itemId eq '")) // the query to retrive operation by item id { string targetTable = ((ConstantNode)((BinaryOperatorNode)((BinaryOperatorNode)query.Filter).LeftOperand).RightOperand).Value.ToString(); string targetId = ((ConstantNode)((BinaryOperatorNode)((BinaryOperatorNode)query.Filter).RightOperand).RightOperand).Value.ToString(); items = items.Where(o => o.Value<string>("itemId") == targetId && o.Value<string>("tableName") == targetTable); } else if (odata.Contains("$filter=(tableName eq '")) { items = items.Where(o => o.Value<string>("tableName") == ((ConstantNode)((BinaryOperatorNode)query.Filter).RightOperand).Value.ToString()); } } if (query.IncludeTotalCount) { return Task.FromResult<JToken>(new JObject() { { "count", items.Count() }, { "results", new JArray(items) } }); } return Task.FromResult<JToken>(new JArray(items)); } this.ReadQueries.Add(query); JToken response; if (ReadAsyncFunc != null) { response = ReadAsyncFunc(query); } else { response = JToken.Parse(ReadResponses.Dequeue()); } return Task.FromResult(response); }
public override async Task<JToken> ReadAsync(MobileServiceTableQueryDescription query) { // first lookup in local store JToken result = await this.store.ReadAsync(query); JArray items = GetItems(result); // if local store does not have results if ((items == null || items.Count == 0) && !IsSystemTable(query.TableName)) { // then lookup the server result = await this.client.GetTable(query.TableName).ReadAsync(query.ToODataString()); items = GetItems(result); // insert the results in the local store await this.store.UpsertAsync(query.TableName, items.Cast<JObject>(), fromServer: true); } return result; }
internal string ToODataString <T>(IMobileServiceTableQuery <T> query) { MobileServiceTableQueryDescription description = this.Compile(query); return(description.ToODataString()); }
public void ToODataString_EscapesThe_Uri() { //updatedat gt datetimeoffset'2014-04-04T07:00:00.0000000+00:00' var datetime1 = new ConstantNode(new DateTimeOffset(2014, 4, 4, 7, 0, 0, TimeSpan.FromHours(0))); var updatedAt = new MemberAccessNode(null, "updatedat"); var gt1 = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, updatedAt, datetime1); // updatedat gt datetime'2014-04-04T07:0:0.000Z' var datetime2 = new ConstantNode(new DateTime(2014, 4, 4, 7, 0, 0, DateTimeKind.Utc)); var someDate = new MemberAccessNode(null, "someDate"); var gt2 = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, someDate, datetime2); // startswith(text,'this&''%%=,?#') var text = new MemberAccessNode(null, "text"); var value = new ConstantNode("this&'%%=,?#"); var startswith = new FunctionCallNode("startswith", new QueryNode[] { text, value }); //updatedat gt datetimeoffset'2014-04-04T07:00:00.0000000+00:00' and startswith(text,'this&''%%=,?#') var and2 = new BinaryOperatorNode(BinaryOperatorKind.And, gt2, startswith); var and1 = new BinaryOperatorNode(BinaryOperatorKind.And, gt1, and2); var desc = new MobileServiceTableQueryDescription("someTable") { Filter = and1 }; Assert.AreEqual(desc.ToODataString(), EscapedODataString); }