internal static HttpWebRequest BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int? timeout, bool useVersionHeader, OperationContext ctx, TablePayloadFormat payloadFormat) { HttpWebRequest msg = BuildRequestCore(uri, builder, "GET", timeout, useVersionHeader, ctx); SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); return msg; }
private async Task DoTableQueryWithInvalidQueryAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery query = new TableQuery().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); OperationContext opContext = new OperationContext(); try { #if !FACADE_NETCORE await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); #else await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, (pk, rk, tse, prop, etag) => new BaseEntity(pk, rk), null, null, opContext); #endif Assert.Fail(); } catch (Exception) { TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "A binary operator with incompatible types was detected. Found operand types 'Edm.String' and 'Edm.Boolean' for operator kind 'And'."); } }
private void DoListTablesSegmentedMaxResultsSync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.DefaultRequestOptions.PayloadFormat = format; TableResultSegment segment = null; List <CloudTable> totalResults = new List <CloudTable>(); int segCount = 0; do { segment = tableClient.ListTablesSegmented(string.Empty, 10, segment != null ? segment.ContinuationToken : null, null, null); totalResults.AddRange(segment); segCount++; }while (segment.ContinuationToken != null); Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); Assert.IsTrue(segCount >= totalResults.Count / 10); }
private void DoCloudTableExistsSync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.DefaultRequestOptions.PayloadFormat = format; string tableName = GenerateRandomTableName(); CloudTable tableRef = tableClient.GetTableReference(tableName); try { Assert.IsFalse(tableRef.Exists()); tableRef.Create(); Assert.IsTrue(tableRef.Exists()); tableRef.Delete(); Assert.IsFalse(tableRef.Exists()); } finally { tableRef.DeleteIfExists(); } }
internal static StorageRequestMessage BuildStorageRequestMessageForTableOperation(Uri uri, TableOperation operation, ICanonicalizer canonicalizer, StorageCredentials cred, OperationContext ctx, TableRequestOptions options) { HttpMethod httpMethod = RESTCommandGeneratorUtils.ExtractHttpMethod(operation); StorageRequestMessage storageRequestMessage = new StorageRequestMessage(httpMethod, uri, canonicalizer, cred, cred.AccountName); storageRequestMessage.Headers.AcceptCharset.ParseAdd("UTF-8"); storageRequestMessage.Headers.Add("MaxDataServiceVersion", "3.0;NetFx"); TablePayloadFormat value = options.PayloadFormat.Value; Logger.LogInformational(ctx, "Setting payload format for the request to '{0}'.", value); SetAcceptHeaderValueForStorageRequestMessage(storageRequestMessage, value); storageRequestMessage.Headers.Add("DataServiceVersion", "3.0;"); if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { storageRequestMessage.Headers.Add("X-HTTP-Method", "MERGE"); } if ((operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) && operation.ETag != null) { storageRequestMessage.Headers.TryAddWithoutValidation("If-Match", operation.ETag); } if (operation.OperationType == TableOperationType.Insert) { storageRequestMessage.Headers.Add("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace) { MultiBufferMemoryStream multiBufferMemoryStream = new MultiBufferMemoryStream(); using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(multiBufferMemoryStream)))) { WriteEntityContent(operation, ctx, options, jsonWriter); } multiBufferMemoryStream.Seek(0L, SeekOrigin.Begin); storageRequestMessage.Content = new StreamContent(multiBufferMemoryStream); } if (httpMethod != HttpMethod.Head && httpMethod != HttpMethod.Get && storageRequestMessage.Content != null) { storageRequestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } return(storageRequestMessage); }
private async Task DoTableGenericQueryWithContinuationAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; OperationContext opContext = new OperationContext(); #if !FACADE_NETCORE TableQuery <BaseEntity> query = new TableQuery <BaseEntity>(); TableQuerySegment <BaseEntity> seg = await currentTable.ExecuteQuerySegmentedAsync(query, fullResolver, null, null, opContext); #else TableQuery query = new TableQuery(); TableQuerySegment <BaseEntity> seg = await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, resolver, null, null, opContext); #endif int count = 0; foreach (BaseEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); count++; } // Second segment Assert.IsNotNull(seg.ContinuationToken); #if !FACADE_NETCORE seg = await currentTable.ExecuteQuerySegmentedAsync(query, fullResolver, seg.ContinuationToken, null, opContext); #else seg = await currentTable.ExecuteQuerySegmentedAsync <BaseEntity>(query, resolver, seg.ContinuationToken, null, opContext); #endif foreach (BaseEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); count++; } Assert.AreEqual(1500, count); TestHelper.AssertNAttempts(opContext, 2); }
private void DoSingleEntityReplace(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); SetPayloadFormatOnDataServiceContext(queryContext, format, tableClient); // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString()); baseEntity.Randomize(); ctx.AddObject(currentTable.Name, baseEntity); ctx.SaveChangesWithRetries(); string etag = ctx.Entities.First().ETag; ctx.Detach(baseEntity); MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); replaceEntity.Randomize(); ctx.AttachTo(currentTable.Name, replaceEntity, etag); ctx.UpdateObject(replaceEntity); ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); // Retrieve Entity UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery <UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(null, retrievedEntity.A); Assert.AreEqual(null, retrievedEntity.B); Assert.AreEqual(null, retrievedEntity.C); Assert.AreEqual(replaceEntity.D, retrievedEntity.D); Assert.AreEqual(replaceEntity.E, retrievedEntity.E); Assert.AreEqual(replaceEntity.F, retrievedEntity.F); }
private void DoSingleEntityInsert(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); // Insert Entity ComplexEntity insertEntity = new ComplexEntity("insert test", "foo" + format.ToString()); ctx.AddObject(currentTable.Name, insertEntity); ctx.SaveChangesWithRetries(); // Retrieve Entity ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name) where ent.PartitionKey == insertEntity.PartitionKey && ent.RowKey == insertEntity.RowKey select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); ComplexEntity.AssertEquality(insertEntity, retrievedEntity); }
private async Task DoTableQueryWithContinuationAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery query = new TableQuery(); OperationContext opContext = new OperationContext(); #if !FACADE_NETCORE TableQuerySegment seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); #else TableQuerySegment <DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync <DynamicTableEntity>(query, (pk, rk, tse, prop, etag) => new DynamicTableEntity(pk, rk, etag, prop), null, null, opContext); #endif int count = 0; foreach (DynamicTableEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); Assert.AreEqual(ent.Properties.Count, 4); count++; } // Second segment Assert.IsNotNull(seg.ContinuationToken); #if !FACADE_NETCORE seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); #else seg = await currentTable.ExecuteQuerySegmentedAsync <DynamicTableEntity>(query, (pk, rk, tse, prop, etag) => new DynamicTableEntity(pk, rk, etag, prop), seg.ContinuationToken, null, opContext); #endif foreach (DynamicTableEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); Assert.AreEqual(ent.Properties.Count, 4); count++; } Assert.AreEqual(1500, count); TestHelper.AssertNAttempts(opContext, 2); }
private void DoTableGenericQueryProjection(TablePayloadFormat format) { tableClient.PayloadFormat = format; TableQuery <BaseEntity> query = new TableQuery <BaseEntity>().Select(new List <string>() { "A", "C" }); foreach (BaseEntity ent in ExecuteQuery(currentTable, query)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 0); } }
private void DoSingleEntityDelete(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); // Insert Entity ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); ctx.AddObject(currentTable.Name, insertEntity); ctx.SaveChangesWithRetries(); // Retrieve Entity ComplexEntity retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name) where ent.PartitionKey == insertEntity.PartitionKey && ent.RowKey == insertEntity.RowKey select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); ctx.DeleteObject(retrievedEntity); ctx.SaveChangesWithRetries(); try { // Retrieve Entity retrievedEntity = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name) where ent.PartitionKey == insertEntity.PartitionKey && ent.RowKey == insertEntity.RowKey select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); Assert.Fail(); } catch (StorageException ex) { Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.NotFound); } }
private async Task DoTableQueryEmptyValueAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; CloudTable table = tableClient.GetTableReference(GenerateRandomTableName()); await table.CreateAsync(); // Setup string pk = Guid.NewGuid().ToString(); DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey"); dynEnt.Properties.Add("A", new EntityProperty(string.Empty)); await table.ExecuteAsync(TableOperation.Insert(dynEnt)); // 1. Filter on String List <DynamicTableEntity> results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); Assert.AreEqual(1, results.Count); List <BaseEntity> pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery <BaseEntity>().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); Assert.AreEqual(1, pocoresults.Count); }
private async Task DoCloudTableExistsAsync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; string tableName = GenerateRandomTableName(); CloudTable tableRef = tableClient.GetTableReference(tableName); try { Assert.IsFalse(await tableRef.ExistsAsync()); await tableRef.CreateAsync(); Assert.IsTrue(await tableRef.ExistsAsync()); await tableRef.DeleteAsync(); Assert.IsFalse(await tableRef.ExistsAsync()); } finally { tableRef.DeleteIfExistsAsync().Wait(); } }
private void DoTableGenericWithResolver(TablePayloadFormat format) { tableClient.PayloadFormat = format; TableQuery <TableEntity> query = new TableQuery <TableEntity>().Select(new List <string>() { "A", "C", "E" }); TableRequestOptions options = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue) }; foreach (string ent in ExecuteQuery(currentTable, query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, options)) { Assert.AreEqual(ent, "ac" + 1234); } foreach (BaseEntity ent in ExecuteQuery(currentTable, query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag }, options)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.IsNotNull(ent.ETag); Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 1234); } }
private void DoBatchInsert(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); // Insert Entities SortedDictionary <string, ComplexEntity> entities = new SortedDictionary <string, ComplexEntity>(); for (int i = 0; i < 100; i++) { ComplexEntity insertEntity = new ComplexEntity("insert test" + format.ToString(), "foo" + format.ToString() + i); entities.Add(insertEntity.RowKey, insertEntity); ctx.AddObject(currentTable.Name, insertEntity); } DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode); // Retrieve Entities List <ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery <ComplexEntity>(currentTable.Name) where ent.PartitionKey == entities.First().Value.PartitionKey select ent).AsTableServiceQuery(ctx).Execute().ToList(); Assert.AreEqual(entities.Count, retrievedEntities.Count); foreach (ComplexEntity retrievedEntity in retrievedEntities) { ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity); entities.Remove(retrievedEntity.RowKey); } Assert.AreEqual(0, entities.Count); }
private void DoListTablesSegmentedWithPrefixSync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; TableResultSegment segment = null; List <CloudTable> totalResults = new List <CloudTable>(); int segCount = 0; do { segment = tableClient.ListTablesSegmented(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null); totalResults.AddRange(segment); segCount++; }while (segment.ContinuationToken != null); Assert.AreEqual(totalResults.Count, 20); foreach (CloudTable tbl in totalResults) { Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); } }
private void DoSingleEntityInsertEntityOver1MB(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); // Insert Entity ComplexEntity insertEntity = new ComplexEntity("insert test", "foo"); insertEntity.Binary = new byte[1024 * 1024]; ctx.AddObject(currentTable.Name, insertEntity); OperationContext opContext = new OperationContext(); try { ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); Assert.Fail(); } catch (StorageException) { TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); } }
private async Task DoTableQueryEmptyValueAsync(TablePayloadFormat format) { CloudTableClient client = GenerateCloudTableClient(); client.DefaultRequestOptions.PayloadFormat = format; CloudTable table = client.GetTableReference(GenerateRandomTableName()); await table.CreateAsync(); // Setup string pk = Guid.NewGuid().ToString(); DynamicTableEntity dynEnt = new DynamicTableEntity(pk, "rowkey"); dynEnt.Properties.Add("A", new EntityProperty(string.Empty)); await table.ExecuteAsync(TableOperation.Insert(dynEnt)); // 1. Filter on String List<DynamicTableEntity> results = (await table.ExecuteQuerySegmentedAsync(new TableQuery().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); Assert.AreEqual(1, results.Count); List<BaseEntity> pocoresults = (await table.ExecuteQuerySegmentedAsync(new TableQuery<BaseEntity>().Where(TableQuery.GenerateFilterCondition("A", QueryComparisons.Equal, string.Empty)), null)).ToList(); Assert.AreEqual(1, pocoresults.Count); }
internal static StorageRequestMessage BuildRequestForTableBatchOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials) { StorageRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx, canonicalizer, credentials); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); MultiBufferMemoryStream batchContentStream = new MultiBufferMemoryStream(client.BufferManager); string batchID = Guid.NewGuid().ToString(); string changesetID = Guid.NewGuid().ToString(); using (StreamWriter contentWriter = new StreamWriter(new NonCloseableStream(batchContentStream))) { msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue); string batchSeparator = Constants.BatchSeparator + batchID; string changesetSeparator = Constants.ChangesetSeparator + changesetID; string acceptHeader = "Accept: "; switch (payloadFormat) { case TablePayloadFormat.Json: acceptHeader = acceptHeader + Constants.JsonLightAcceptHeaderValue; break; case TablePayloadFormat.JsonFullMetadata: acceptHeader = acceptHeader + Constants.JsonFullMetadataAcceptHeaderValue; break; case TablePayloadFormat.JsonNoMetadata: acceptHeader = acceptHeader + Constants.JsonNoMetadataAcceptHeaderValue; break; } contentWriter.WriteLine(batchSeparator); bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; // Query operations should not be inside changeset in payload if (!isQuery) { // Start Operation contentWriter.WriteLine(Constants.ChangesetBoundaryMarker + changesetID); contentWriter.WriteLine(); } foreach (TableOperation operation in batch) { string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method; if (!isQuery) { contentWriter.WriteLine(changesetSeparator); } contentWriter.WriteLine(Constants.ContentTypeApplicationHttp); contentWriter.WriteLine(Constants.ContentTransferEncodingBinary); contentWriter.WriteLine(); string tableURI = Uri.EscapeUriString(operation.GenerateRequestURI(uri, tableName).ToString()); // "EscapeUriString" is almost exactly what we need, except that it contains special logic for // the percent sign, which results in an off-by-one error in the number of times "%" is encoded. // This corrects for that. tableURI = tableURI.Replace(@"%25", @"%"); contentWriter.WriteLine(httpMethod + " " + tableURI + " " + Constants.HTTP1_1); contentWriter.WriteLine(acceptHeader); contentWriter.WriteLine(Constants.ContentTypeApplicationJson); if (operation.OperationType == TableOperationType.Insert) { contentWriter.WriteLine(Constants.HeaderConstants.Prefer + @": " + (operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent)); } contentWriter.WriteLine(Constants.HeaderConstants.DataServiceVersion + ": " + Constants.HeaderConstants.DataServiceVersionValue); // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { contentWriter.WriteLine(Constants.HeaderConstants.IfMatch + @": " + operation.ETag); } contentWriter.WriteLine(); if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) { using (JsonTextWriter jsonWriter = new JsonTextWriter(contentWriter)) { jsonWriter.CloseOutput = false; WriteEntityContent(operation, ctx, jsonWriter); } contentWriter.WriteLine(); } } if (!isQuery) { contentWriter.WriteLine(changesetSeparator + "--"); } contentWriter.WriteLine(batchSeparator + "--"); } batchContentStream.Seek(0, SeekOrigin.Begin); msg.Content = new StreamContent(batchContentStream); msg.Content.Headers.ContentLength = batchContentStream.Length; msg.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(Constants.BatchBoundaryMarker + batchID);//new System.Net.Http.Headers.MediaTypeHeaderValue(Constants.BatchBoundaryMarker + batchID); return(msg); }
private static void SetAcceptHeaderForHttpWebRequest(StorageRequestMessage msg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.JsonFullMetadata) { msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue); } else if (payloadFormat == TablePayloadFormat.Json) { msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue); } else if (payloadFormat == TablePayloadFormat.JsonNoMetadata) { msg.Headers.Add(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue); } }
private void DoListTablesWithPrefixExtended(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; int NumTables = 50; int TableNameLength = 8; int NumQueries = 100; string alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; string numerics = "0123456789"; string legalChars = alpha + numerics; string queryString = string.Empty; List <CloudTable> tableList = new List <CloudTable>(); List <CloudTable> localTestCreatedTableList = new List <CloudTable>(); Random rand = new Random(); try { #region Generate Tables // Generate Tables in Storage // This will generate all caps Tables, i.e. AAAAAAAA, BBBBBBBB.... for (int h = 26; h < alpha.Length; h++) { string tString = string.Empty; for (int i = 0; i < TableNameLength; i++) { tString += alpha[h]; } CloudTable table = tableClient.GetTableReference(tString); if (table.CreateIfNotExists()) { tableList.Add(table); localTestCreatedTableList.Add(table); } } // Generate some random tables of TableNameLength, table must start with a letter for (int m = 0; m < NumTables; m++) { string tableName = GenerateRandomStringFromCharset(1, alpha, rand).ToLower() + GenerateRandomStringFromCharset(TableNameLength - 1, legalChars, rand).ToLower(); CloudTable table = tableClient.GetTableReference(tableName); if (table.CreateIfNotExists()) { tableList.Add(table); localTestCreatedTableList.Add(table); } } #endregion #region Generate Query Strings to cover all boundary conditions List <string> queryStrings = new List <string>() { String.Empty, "aa", "zz", "az", "Az", "Aa", "zZ", "AA", "ZZ", "AZ", "z9", "a9", "aaa" }; for (int k = 0; k < legalChars.Length; k++) { queryStrings.Add(legalChars[k].ToString()); } for (int n = 0; n <= NumQueries; n++) { queryStrings.Add(GenerateRandomStringFromCharset((n % TableNameLength) + 1, legalChars, rand)); } #endregion #region Merge Created Tables With Pre-existing ones int totalTables = 0; foreach (CloudTable listedTable in tableClient.ListTables()) { totalTables++; if (tableList.Where((tbl) => tbl.Uri == listedTable.Uri).FirstOrDefault() != null) { continue; } tableList.Add(listedTable); } Assert.AreEqual(tableList.Count, totalTables); #endregion List <CloudTable> serviceResult = null; List <CloudTable> LINQResult = null; try { foreach (string queryValue in queryStrings) { queryString = queryValue; serviceResult = tableClient.ListTables(queryString).OrderBy((table) => table.Name).ToList(); LINQResult = tableList.Where((table) => table.Name.ToLower().StartsWith(queryString.ToLower())).OrderBy((table) => table.Name).ToList(); Assert.AreEqual(serviceResult.Count(), LINQResult.Count()); for (int listDex = 0; listDex < serviceResult.Count(); listDex++) { Assert.AreEqual(serviceResult[listDex].Name, LINQResult[listDex].Name); } } } catch (Exception) { // On exception log table names for repro this.testContextInstance.WriteLine("Exception in ListTablesWithPrefix, Dumping Tables for repro. QueryString = {0}\r\n", queryString); foreach (CloudTable table in tableList) { this.testContextInstance.WriteLine(table.Name); } this.testContextInstance.WriteLine("Linq results ======================="); foreach (CloudTable table in LINQResult) { this.testContextInstance.WriteLine(table.Name); } this.testContextInstance.WriteLine("Service results ======================="); foreach (CloudTable table in serviceResult) { this.testContextInstance.WriteLine(table.Name); } throw; } } finally { // Cleanup foreach (CloudTable table in localTestCreatedTableList) { // Dont delete Class level tables if (createdTables.Where((tbl) => tbl.Uri == table.Uri).FirstOrDefault() != null) { continue; } // Delete other tables table.DeleteIfExists(); } } }
private static void SetAcceptAndContentTypeForODataBatchMessage(ODataBatchOperationRequestMessage mimePartMsg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.AtomAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue); } else if (payloadFormat == TablePayloadFormat.JsonFullMetadata) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } else if (payloadFormat == TablePayloadFormat.Json) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } else { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } }
private static void SetContentTypeForHttpWebRequest(HttpWebRequest msg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { msg.ContentType = Constants.AtomContentTypeHeaderValue; } else { msg.ContentType = Constants.JsonContentTypeHeaderValue; } }
private void DoCloudTableDeleteIfExistsSync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; string tableName = GenerateRandomTableName(); CloudTable tableRef = tableClient.GetTableReference(tableName); try { Assert.IsFalse(tableRef.Exists()); Assert.IsFalse(tableRef.DeleteIfExists()); tableRef.Create(); Assert.IsTrue(tableRef.Exists()); Assert.IsTrue(tableRef.DeleteIfExists()); Assert.IsFalse(tableRef.DeleteIfExists()); } finally { tableRef.DeleteIfExists(); } }
private static void SetAcceptAndContentTypeForODataBatchMessage(ODataBatchOperationRequestMessage mimePartMsg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.AtomAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue); } else if (payloadFormat == TablePayloadFormat.JsonFullMetadata) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonFullMetadataAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } else if (payloadFormat == TablePayloadFormat.Json) { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonLightAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } else { mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadAcceptHeader, Constants.JsonNoMetadataAcceptHeaderValue); mimePartMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } }
internal static Tuple <HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int?timeout, string tableName, TableBatchOperation batch, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName) { HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, "POST", timeout, useVersionHeader, ctx); TablePayloadFormat payloadFormat = options.PayloadFormat.Value; Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); // Start Batch ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; // Query operations should not be inside changeset in payload if (!isQuery) { // Start Operation batchWriter.WriteStartChangeset(); batchWriter.Flush(); } foreach (TableOperation operation in batch) { string httpMethod = operation.HttpMethod; if (operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge) { options.AssertNoEncryptionPolicyOrStrictMode(); httpMethod = "MERGE"; } ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName)); SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat); // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { mimePartMsg.SetHeader("If-Match", operation.Entity.ETag); } // Prefer header if (operation.OperationType == TableOperationType.Insert) { mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) { using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(accountName))) { // Write entity ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter, options); } } } if (!isQuery) { // End Operation batchWriter.WriteEndChangeset(); } // End Batch batchWriter.WriteEndBatch(); batchWriter.Flush(); return(new Tuple <HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream())); }
public static void SetPayloadFormatOnDataServiceContext(TableServiceContext ctx, TablePayloadFormat format, CloudTableClient tableClient) { #pragma warning disable 0618 if (format == TablePayloadFormat.AtomPub) #pragma warning restore 0618 { ctx.Format.UseAtom(); } else { ctx.Format.UseJson(new TableStorageModel(tableClient.Credentials.AccountName)); } }
private void DoBatchInsert(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); // Insert Entities SortedDictionary<string, ComplexEntity> entities = new SortedDictionary<string, ComplexEntity>(); for (int i = 0; i < 100; i++) { ComplexEntity insertEntity = new ComplexEntity("insert test" + format.ToString(), "foo" + format.ToString() + i); entities.Add(insertEntity.RowKey, insertEntity); ctx.AddObject(currentTable.Name, insertEntity); } DataServiceResponse response = ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); Assert.AreEqual((int)HttpStatusCode.Accepted, response.BatchStatusCode); // Retrieve Entities List<ComplexEntity> retrievedEntities = (from ent in ctx.CreateQuery<ComplexEntity>(currentTable.Name) where ent.PartitionKey == entities.First().Value.PartitionKey select ent).AsTableServiceQuery(ctx).Execute().ToList(); Assert.AreEqual(entities.Count, retrievedEntities.Count); foreach (ComplexEntity retrievedEntity in retrievedEntities) { ComplexEntity.AssertEquality(entities[retrievedEntity.RowKey], retrievedEntity); entities.Remove(retrievedEntity.RowKey); } Assert.AreEqual(0, entities.Count); }
internal static StorageRequestMessage BuildRequestForTableOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, TableOperation operation, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials) { StorageRequestMessage msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, content, ctx, canonicalizer, credentials); // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET")) { SetContentTypeForHttpWebRequest(msg); } if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { // post tunnelling msg.Headers.Add("X-HTTP-Method", "MERGE"); } // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { msg.Headers.Add("If-Match", operation.Entity.ETag); } // Prefer header if (operation.OperationType == TableOperationType.Insert) { msg.Headers.Add("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace) { // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, (int)Constants.KB); if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET")) { adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } cmd.StreamToDispose = adapterMsg.GetStream(); ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings, new TableStorageModel(client.AccountName)); ODataWriter writer = odataWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer); return(adapterMsg.GetPopulatedMessage()); } return(msg); }
internal static StorageRequestMessage BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int?timeout, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials) { StorageRequestMessage msg = BuildRequestCore(uri, builder, HttpMethod.Get, timeout, content, ctx, canonicalizer, credentials); // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); return(msg); }
private void DoTableQueryWithInvalidTakeCount(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; try { TableQuery query = new TableQuery().Take(0); Assert.Fail(); } catch (ArgumentException ex) { Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); } catch (Exception) { Assert.Fail(); } try { TableQuery query = new TableQuery().Take(-1); Assert.Fail(); } catch (ArgumentException ex) { Assert.AreEqual(ex.Message, "Take count must be positive and greater than 0."); } catch (Exception) { Assert.Fail(); } }
internal static Tuple <HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int?timeout, TableOperation operation, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName) { HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, useVersionHeader, ctx); TablePayloadFormat payloadFormat = options.PayloadFormat.Value; // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET") { SetContentTypeForHttpWebRequest(msg, payloadFormat); } if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { options.AssertNoEncryptionPolicyOrStrictMode(); // post tunnelling msg.Headers.Add("X-HTTP-Method", "MERGE"); } // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { if (operation.Entity.ETag != null) { msg.Headers.Add("If-Match", operation.Entity.ETag); } } // Prefer header if (operation.OperationType == TableOperationType.Insert) { msg.Headers.Add("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace) { // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager); if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET") { SetContentTypeForAdapterMessage(adapterMsg, payloadFormat); } ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings, new TableStorageModel(accountName)); ODataWriter writer = odataWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, writer, options); return(new Tuple <HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream())); } return(new Tuple <HttpWebRequest, Stream>(msg, null)); }
private void DoCloudTableDeleteWhenNotExistSync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; string tableName = GenerateRandomTableName(); CloudTable tableRef = tableClient.GetTableReference(tableName); OperationContext ctx = new OperationContext(); try { Assert.IsFalse(tableRef.Exists()); // This should throw with no retries tableRef.Delete(null, ctx); Assert.Fail(); } catch (StorageException ex) { Assert.AreEqual(ex.RequestInformation.HttpStatusCode, 404); Assert.AreEqual(ex.RequestInformation.ExtendedErrorInformation.ErrorCode, "ResourceNotFound"); TestHelper.AssertNAttempts(ctx, 1); } finally { tableRef.DeleteIfExists(); } }
private void DoTableGenericQueryWithSpecificOnSupportedTypes(TablePayloadFormat format) { CloudTableClient client = GenerateCloudTableClient(); CloudTable table = client.GetTableReference(GenerateRandomTableName()); table.Create(); client.DefaultRequestOptions.PayloadFormat = format; try { // Setup TableBatchOperation batch = new TableBatchOperation(); string pk = Guid.NewGuid().ToString(); ComplexEntity middleRef = null; for (int m = 0; m < 100; m++) { ComplexEntity complexEntity = new ComplexEntity(pk, string.Format("{0:0000}", m)); complexEntity.String = string.Format("{0:0000}", m); complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; complexEntity.Bool = m % 2 == 0 ? true : false; complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; complexEntity.Double = m + ((double)m / 100); complexEntity.DoublePrimitive = m + ((double)m / 100); complexEntity.Int32 = m; complexEntity.IntegerPrimitive = m; complexEntity.Int64 = (long)int.MaxValue + m; complexEntity.LongPrimitive = (long)int.MaxValue + m; complexEntity.Guid = Guid.NewGuid(); batch.Insert(complexEntity); if (m == 50) { middleRef = complexEntity; } // Add delay to make times unique Thread.Sleep(100); } table.ExecuteBatch(batch); // 1. Filter on String ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); // 2. Filter on Guid ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Guid), 1); // 3. Filter on Long ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.LongPrimitive), 50); // 4. Filter on Double ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, middleRef.Double), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.DoublePrimitive), 50); // 5. Filter on Integer ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, middleRef.Int32), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.IntegerPrimitive), 50); // 6. Filter on Date ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, middleRef.DateTimeOffset), 50); // 7. Filter on Boolean ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Bool), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.BoolPrimitive), 50); // 8. Filter on Binary ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Binary), 1); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, middleRef.BinaryPrimitive), 1); // 9. Filter on Binary GTE ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, middleRef.Binary), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); // 10. Complex Filter on Binary GTE ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, middleRef.PartitionKey), TableOperators.And, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, middleRef.Binary)), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.BinaryPrimitive), 50); } finally { table.DeleteIfExists(); } }
private static void SetAcceptHeaderForHttpWebRequest(HttpWebRequest msg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { msg.Accept = Constants.AtomAcceptHeaderValue; } else if (payloadFormat == TablePayloadFormat.JsonFullMetadata) { msg.Accept = Constants.JsonFullMetadataAcceptHeaderValue; } else if (payloadFormat == TablePayloadFormat.Json) { msg.Accept = Constants.JsonLightAcceptHeaderValue; } else if (payloadFormat == TablePayloadFormat.JsonNoMetadata) { msg.Accept = Constants.JsonNoMetadataAcceptHeaderValue; } }
internal static StorageRequestMessage BuildRequestForTableOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, TableOperation operation, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials) { StorageRequestMessage msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, content, ctx, canonicalizer, credentials); // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue); if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { // post tunnelling msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE"); } // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { msg.Headers.Add(Constants.HeaderConstants.IfMatch, operation.ETag); } // Prefer header if (operation.OperationType == TableOperationType.Insert) { msg.Headers.Add(Constants.HeaderConstants.Prefer, operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace) { MultiBufferMemoryStream ms = new MultiBufferMemoryStream(client.BufferManager); using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(ms)))) { WriteEntityContent(operation, ctx, jsonWriter); } ms.Seek(0, SeekOrigin.Begin); msg.Content = new StreamContent(ms); msg.Content.Headers.ContentLength = ms.Length; if (!operation.HttpMethod.Equals("HEAD") && !operation.HttpMethod.Equals("GET")) { SetContentTypeForHttpWebRequest(msg); } return(msg); } return(msg); }
private static void SetContentTypeForAdapterMessage(HttpWebRequestAdapterMessage adapterMsg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue); } else { adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } }
private void DoTableGenericQueryEnumerateTwice(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<BaseEntity> query = new TableQuery<BaseEntity>(); OperationContext opContext = new OperationContext(); IEnumerable<BaseEntity> enumerable = currentTable.ExecuteQuery(query); List<BaseEntity> firstIteration = new List<BaseEntity>(); List<BaseEntity> secondIteration = new List<BaseEntity>(); foreach (BaseEntity ent in enumerable) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); firstIteration.Add(ent); } foreach (BaseEntity ent in enumerable) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); secondIteration.Add(ent); } Assert.AreEqual(firstIteration.Count, secondIteration.Count); for (int m = 0; m < firstIteration.Count; m++) { Assert.AreEqual(firstIteration[m].PartitionKey, secondIteration[m].PartitionKey); Assert.AreEqual(firstIteration[m].RowKey, secondIteration[m].RowKey); Assert.AreEqual(firstIteration[m].Timestamp, secondIteration[m].Timestamp); Assert.AreEqual(firstIteration[m].ETag, secondIteration[m].ETag); firstIteration[m].Validate(); } }
internal static Tuple <HttpWebRequest, Stream> BuildRequestForTableOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int?timeout, TableOperation operation, bool useVersionHeader, OperationContext ctx, TableRequestOptions options) { HttpWebRequest msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, useVersionHeader, ctx); TablePayloadFormat payloadFormat = options.PayloadFormat.Value; // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); msg.Headers.Add(Constants.HeaderConstants.DataServiceVersion, Constants.HeaderConstants.DataServiceVersionValue); if (operation.HttpMethod != "HEAD" && operation.HttpMethod != "GET") { msg.ContentType = Constants.JsonContentTypeHeaderValue; } if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { // Client-side encryption is not supported on merge requests. // This is because we maintain the list of encrypted properties as a property on the entity, and we can't update this // properly for merge operations. options.AssertNoEncryptionPolicyOrStrictMode(); // post tunnelling msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE"); } if (operation.OperationType == TableOperationType.RotateEncryptionKey) { // post tunnelling msg.Headers.Add(Constants.HeaderConstants.PostTunnelling, "MERGE"); } // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.RotateEncryptionKey) { if (operation.ETag != null) { msg.Headers.Add(Constants.HeaderConstants.IfMatch, operation.ETag); } } // Prefer header if (operation.OperationType == TableOperationType.Insert) { msg.Headers.Add(Constants.HeaderConstants.Prefer, operation.EchoContent ? Constants.HeaderConstants.PreferReturnContent : Constants.HeaderConstants.PreferReturnNoContent); } if (operation.OperationType == TableOperationType.Insert || operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.InsertOrReplace || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.RotateEncryptionKey) { MultiBufferMemoryStream ms = new MultiBufferMemoryStream(bufferManager); using (JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(new NonCloseableStream(ms)))) { WriteEntityContent(operation, ctx, options, jsonWriter); } ms.Seek(0, SeekOrigin.Begin); msg.ContentLength = ms.Length; return(new Tuple <HttpWebRequest, Stream>(msg, ms)); } return(new Tuple <HttpWebRequest, Stream>(msg, null)); }
public void DoTableGenericQueryProjectionWithSpecialCases(CloudTable table, TablePayloadFormat format, bool disableCompiledSerializers) { table.ServiceClient.DefaultRequestOptions.PayloadFormat = format; BaseEntity.DisableCompiledSerializers = disableCompiledSerializers; // Query on A, B, and E TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Select(new List<string>() { "A", "B", "E" }); IEnumerable<BaseEntity> entities = table.ExecuteQuery(query, null); // Verify A has a set value and B and E have type defaults Assert.AreEqual(1, entities.Count()); BaseEntity entity = entities.First(); Assert.AreEqual("a", entity.A); Assert.IsNull(entity.B); Assert.AreEqual(0, entity.E); }
private async Task DoListTablesSegmentedBasicAsync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; TableResultSegment segment = null; List<CloudTable> totalResults = new List<CloudTable>(); do { segment = await tableClient.ListTablesSegmentedAsync(segment != null ? segment.ContinuationToken : null, CancellationToken.None); totalResults.AddRange(segment); } while (segment.ContinuationToken != null); // Assert.AreEqual(totalResults.Count, tableClient.ListTables().Count()); }
internal static StorageRequestMessage BuildRequestForTableBatchOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials) { StorageRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx, canonicalizer, credentials); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { CheckCharacters = false, // sets this flag on the XmlWriter for ATOM Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry }; HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, 64 * (int)Constants.KB); cmd.StreamToDispose = adapterMsg.GetStream(); // Start Batch ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings); ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter(); batchWriter.WriteStartBatch(); bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve; // Query operations should not be inside changeset in payload if (!isQuery) { // Start Operation batchWriter.WriteStartChangeset(); batchWriter.Flush(); } foreach (TableOperation operation in batch) { string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method; ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName)); SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat); // etag if (operation.OperationType == TableOperationType.Delete || operation.OperationType == TableOperationType.Replace || operation.OperationType == TableOperationType.Merge) { mimePartMsg.SetHeader("If-Match", operation.Entity.ETag); } // Prefer header if (operation.OperationType == TableOperationType.Insert) { mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content"); } if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve) { using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(client.AccountName))) { // Write entity ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter(); WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter); } } } if (!isQuery) { // End Operation batchWriter.WriteEndChangeset(); } // End Batch batchWriter.WriteEndBatch(); batchWriter.Flush(); return(adapterMsg.GetPopulatedMessage()); }
private static void SetContentTypeForAdapterMessage(HttpWebRequestAdapterMessage adapterMsg, TablePayloadFormat payloadFormat) { if (payloadFormat == TablePayloadFormat.AtomPub) { adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.AtomContentTypeHeaderValue); } else { adapterMsg.SetHeader(Constants.HeaderConstants.PayloadContentTypeHeader, Constants.JsonContentTypeHeaderValue); } }
private async Task DoListTablesSegmentedWithPrefixAsync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); tableClient.PayloadFormat = format; TableResultSegment segment = null; List<CloudTable> totalResults = new List<CloudTable>(); int segCount = 0; do { segment = await tableClient.ListTablesSegmentedAsync(prefixTablesPrefix, null, segment != null ? segment.ContinuationToken : null, null, null); totalResults.AddRange(segment); segCount++; } while (segment.ContinuationToken != null); Assert.AreEqual(totalResults.Count, 20); foreach (CloudTable tbl in totalResults) { Assert.IsTrue(tbl.Name.StartsWith(prefixTablesPrefix)); } }
internal static HttpWebRequest BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int?timeout, bool useVersionHeader, OperationContext ctx, TablePayloadFormat payloadFormat) { HttpWebRequest msg = BuildRequestCore(uri, builder, "GET", timeout, useVersionHeader, ctx); // Set Accept and Content-Type based on the payload format. SetAcceptHeaderForHttpWebRequest(msg, payloadFormat); Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat); return(msg); }
private void DoTableQueryGenericWithTakeCount(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // No continuation TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Take(100); OperationContext opContext = new OperationContext(); IEnumerable<BaseEntity> enumerable = currentTable.ExecuteQuery(query, null, opContext); Assert.AreEqual(query.TakeCount, enumerable.Count()); TestHelper.AssertNAttempts(opContext, 1); // With continuations query.TakeCount = 1200; opContext = new OperationContext(); enumerable = currentTable.ExecuteQuery(query, null, opContext); Assert.AreEqual(query.TakeCount, enumerable.Count()); TestHelper.AssertNAttempts(opContext, 2); foreach (BaseEntity entity in enumerable) { entity.Validate(); } }
private void DoTableQuerySegmentedResolverWithDynamic(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableRequestOptions options = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue) }; TableQuery query = new TableQuery().Select(new List<string>() { "A", "C", "E" }); TableContinuationToken token = null; List<string> list = new List<string>(); do { TableQuerySegment<string> segment = currentTable.ExecuteQuerySegmented<string>(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, token, options, null); list.AddRange(segment.Results); token = segment.ContinuationToken; } while (token != null); foreach (string ent in list) { Assert.AreEqual(ent, "ac" + 1234); } List<BaseEntity> list1 = new List<BaseEntity>(); do { TableQuerySegment<BaseEntity> segment = currentTable.ExecuteQuerySegmented<BaseEntity>(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag }, token, options, null); list1.AddRange(segment.Results); token = segment.ContinuationToken; } while (token != null); foreach (BaseEntity ent in list1) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.IsNotNull(ent.ETag); Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 1234); } }
private void DoTableGenericQueryWithInternalType(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<InternalEntity> query = new TableQuery<InternalEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); TableQuerySegment<InternalEntity> seg = currentTable.ExecuteQuerySegmented(query, null); foreach (InternalEntity ent in seg) { Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); ent.Validate(); } }
private void DoTableGenericQueryComplexWithoutPropertyResolverSync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; CloudTable currentTestTable = tableClient.GetTableReference("tbl" + Guid.NewGuid().ToString("N")); try { currentTestTable.CreateIfNotExists(); ComplexEntity ent = new ComplexEntity("tables_batch_1", Guid.NewGuid().ToString()); currentTestTable.Execute(TableOperation.Insert(ent)); TableQuery<ComplexEntity> query = new TableQuery<ComplexEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); TableQuerySegment<ComplexEntity> seg = currentTestTable.ExecuteQuerySegmented(query, null); foreach (ComplexEntity retrievedEnt in seg) { Assert.AreEqual(retrievedEnt.PartitionKey, "tables_batch_1"); ComplexEntity.AssertEquality(ent, retrievedEnt); } } finally { currentTestTable.DeleteIfExists(); } }
private void DoTableGenericQueryWithContinuationSync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<BaseEntity> query = new TableQuery<BaseEntity>(); OperationContext opContext = new OperationContext(); TableQuerySegment<BaseEntity> seg = currentTable.ExecuteQuerySegmented(query, null, null, opContext); int count = 0; foreach (BaseEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); count++; } // Second segment Assert.IsNotNull(seg.ContinuationToken); seg = currentTable.ExecuteQuerySegmented(query, seg.ContinuationToken, null, opContext); foreach (BaseEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); ent.Validate(); count++; } Assert.AreEqual(1500, count); TestHelper.AssertNAttempts(opContext, 2); }
private void DoTableQueryGenericWithTakeCountAndResolver(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; // No continuation TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Take(100); OperationContext opContext = new OperationContext(); IEnumerable<string> enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); Assert.AreEqual(query.TakeCount, enumerable.Count()); TestHelper.AssertNAttempts(opContext, 1); // With continuations query.TakeCount = 1200; opContext = new OperationContext(); enumerable = currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => pk + rk, null, opContext); Assert.AreEqual(query.TakeCount, enumerable.Count()); TestHelper.AssertNAttempts(opContext, 2); }
private async Task DoTableQueryBasicAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery query = new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "tables_batch_1")); TableQuerySegment<DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync(query, null); foreach (DynamicTableEntity ent in seg) { Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); Assert.AreEqual(ent.Properties.Count, 4); } }
private void DoTableGenericQueryWithInvalidQuery(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<ComplexEntity> query = new TableQuery<ComplexEntity>().Where(string.Format("(PartitionKey ) and (RowKey ge '{1}')", "tables_batch_1", "000050")); OperationContext opContext = new OperationContext(); try { currentTable.ExecuteQuerySegmented(query, null, null, opContext); Assert.Fail(); } catch (StorageException) { TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "InvalidInput" }, "One of the request inputs is not valid."); } }
private async Task DoTableQueryWithContinuationAsync(TablePayloadFormat format) { TableQuery query = new TableQuery(); tableClient.DefaultRequestOptions.PayloadFormat = format; OperationContext opContext = new OperationContext(); TableQuerySegment<DynamicTableEntity> seg = await currentTable.ExecuteQuerySegmentedAsync(query, null, null, opContext); int count = 0; foreach (DynamicTableEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); Assert.AreEqual(ent.Properties.Count, 4); count++; } // Second segment Assert.IsNotNull(seg.ContinuationToken); seg = await currentTable.ExecuteQuerySegmentedAsync(query, seg.ContinuationToken, null, opContext); foreach (DynamicTableEntity ent in seg) { Assert.IsTrue(ent.PartitionKey.StartsWith("tables_batch")); Assert.AreEqual(ent.Properties.Count, 4); count++; } Assert.AreEqual(1500, count); TestHelper.AssertNAttempts(opContext, 2); }
private void DoTableGenericQueryWithFilter(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); OperationContext opContext = new OperationContext(); int count = 0; foreach (BaseEntity ent in currentTable.ExecuteQuery(query)) { Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); ent.Validate(); count++; } Assert.AreEqual(count, 50); }
private void DoTableQueryWithFilterAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery query = new TableQuery().Where(string.Format("(PartitionKey eq '{0}') and (RowKey ge '{1}')", "tables_batch_1", "0050")); OperationContext opContext = new OperationContext(); int count = 0; foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) { Assert.AreEqual(ent.Properties["foo"].StringValue, "bar"); Assert.AreEqual(ent.PartitionKey, "tables_batch_1"); Assert.AreEqual(ent.RowKey, string.Format("{0:0000}", count + 50)); count++; } Assert.AreEqual(count, 50); }
private void DoTableGenericQueryProjectionSpecifyingSystemProperties(TablePayloadFormat format, bool projectSystemProperties) { tableClient.DefaultRequestOptions.PayloadFormat = format; tableClient.DefaultRequestOptions.ProjectSystemProperties = projectSystemProperties; TableQuery<BaseEntity> query = new TableQuery<BaseEntity>().Select(new List<string>() { "A", "C", TableConstants.PartitionKey, TableConstants.Timestamp }); foreach (BaseEntity ent in currentTable.ExecuteQuery(query)) { Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 0); Assert.AreNotEqual(default(string), ent.PartitionKey); Assert.AreNotEqual(default(DateTimeOffset), ent.Timestamp); if (tableClient.DefaultRequestOptions.ProjectSystemProperties.HasValue) { Assert.AreNotEqual(tableClient.DefaultRequestOptions.ProjectSystemProperties.Value, ent.RowKey == default(string), "Missing expected " + TableConstants.RowKey); } } }
private void DoTableQueryProjectionAsync(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery query = new TableQuery().Select(new List<string>() { "a", "c" }); foreach (DynamicTableEntity ent in ExecuteQuery(currentTable, query)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.AreEqual(ent.Properties["a"].StringValue, "a"); Assert.IsFalse(ent.Properties.ContainsKey("b")); Assert.AreEqual(ent.Properties["c"].StringValue, "c"); Assert.IsFalse(ent.Properties.ContainsKey("d")); } }
private void DoTableGenericWithResolver(TablePayloadFormat format) { tableClient.DefaultRequestOptions.PayloadFormat = format; TableQuery<TableEntity> query = new TableQuery<TableEntity>().Select(new List<string>() { "A", "C", "E" }); query.TakeCount = 1000; TableRequestOptions options = new TableRequestOptions() { PropertyResolver = (pk, rk, propName, propValue) => BaseEntity.BaseEntityPropertyResolver(pk, rk, propName, propValue) }; foreach (string ent in currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => prop["A"].StringValue + prop["C"].StringValue + prop["E"].Int32Value, options, null)) { Assert.AreEqual(ent, "ac" + 1234); } foreach (BaseEntity ent in currentTable.ExecuteQuery(query, (pk, rk, ts, prop, etag) => new BaseEntity() { PartitionKey = pk, RowKey = rk, Timestamp = ts, A = prop["A"].StringValue, C = prop["C"].StringValue, E = prop["E"].Int32Value.Value, ETag = etag }, options, null)) { Assert.IsNotNull(ent.PartitionKey); Assert.IsNotNull(ent.RowKey); Assert.IsNotNull(ent.Timestamp); Assert.IsNotNull(ent.ETag); Assert.AreEqual(ent.A, "a"); Assert.IsNull(ent.B); Assert.AreEqual(ent.C, "c"); Assert.IsNull(ent.D); Assert.AreEqual(ent.E, 1234); } Assert.AreEqual(1000, query.TakeCount); }
private async Task DoTableRegionalQueryOnSupportedTypesAsync(TablePayloadFormat format) { CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); CloudTableClient client = GenerateCloudTableClient(); client.DefaultRequestOptions.PayloadFormat = format; CloudTable table = client.GetTableReference(GenerateRandomTableName()); await table.CreateAsync(); try { // Setup TableBatchOperation batch = new TableBatchOperation(); string pk = Guid.NewGuid().ToString(); DynamicTableEntity middleRef = null; for (int m = 0; m < 100; m++) { ComplexEntity complexEntity = new ComplexEntity(); complexEntity.String = string.Format("{0:0000}", m); complexEntity.Binary = new byte[] { 0x01, 0x02, (byte)m }; complexEntity.BinaryPrimitive = new byte[] { 0x01, 0x02, (byte)m }; complexEntity.Bool = m % 2 == 0 ? true : false; complexEntity.BoolPrimitive = m % 2 == 0 ? true : false; complexEntity.Double = m + ((double)m / 100); complexEntity.DoublePrimitive = m + ((double)m / 100); complexEntity.Int32 = m; complexEntity.IntegerPrimitive = m; complexEntity.Int64 = (long)int.MaxValue + m; complexEntity.LongPrimitive = (long)int.MaxValue + m; complexEntity.Guid = Guid.NewGuid(); DynamicTableEntity dynEnt = new DynamicTableEntity(pk, string.Format("{0:0000}", m)); dynEnt.Properties = complexEntity.WriteEntity(null); batch.Insert(dynEnt); if (m == 50) { middleRef = dynEnt; } // Add delay to make times unique await Task.Delay(100); } await table.ExecuteBatchAsync(batch); // 1. Filter on String ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterCondition("String", QueryComparisons.GreaterThanOrEqual, "0050"), 50); // 2. Filter on Guid ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForGuid("Guid", QueryComparisons.Equal, middleRef.Properties["Guid"].GuidValue.Value), 1); // 3. Filter on Long ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("Int64", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForLong("LongPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["LongPrimitive"].Int64Value.Value), 50); // 4. Filter on Double ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("Double", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["Double"].DoubleValue.Value), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDouble("DoublePrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DoublePrimitive"].DoubleValue.Value), 50); // 5. Filter on Integer ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("Int32", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["Int32"].Int32Value.Value), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForInt("IntegerPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["IntegerPrimitive"].Int32Value.Value), 50); // 6. Filter on Date ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForDate("DateTimeOffset", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["DateTimeOffset"].DateTimeOffsetValue.Value), 50); // 7. Filter on Boolean ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBool("Bool", QueryComparisons.Equal, middleRef.Properties["Bool"].BooleanValue.Value), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBool("BoolPrimitive", QueryComparisons.Equal, middleRef.Properties["BoolPrimitive"].BooleanValue.Value), 50); // 8. Filter on Binary ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.Equal, middleRef.Properties["Binary"].BinaryValue), 1); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.Equal, middleRef.Properties["BinaryPrimitive"].BinaryValue), 1); // 9. Filter on Binary GTE ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["Binary"].BinaryValue), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); // 10. Complex Filter on Binary GTE ExecuteQueryAndAssertResults(table, TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, middleRef.PartitionKey), TableOperators.And, TableQuery.GenerateFilterConditionForBinary("Binary", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["Binary"].BinaryValue)), 50); ExecuteQueryAndAssertResults(table, TableQuery.GenerateFilterConditionForBinary("BinaryPrimitive", QueryComparisons.GreaterThanOrEqual, middleRef.Properties["BinaryPrimitive"].BinaryValue), 50); } finally { Thread.CurrentThread.CurrentCulture = currentCulture; table.DeleteIfExistsAsync().Wait(); } }