/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.azure.storage.table;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.ResponseReceivedEvent;
import com.microsoft.azure.storage.ResultSegment;
import com.microsoft.azure.storage.StorageEvent;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.TestRunners.CloudTests;
import com.microsoft.azure.storage.TestRunners.DevFabricTests;
import com.microsoft.azure.storage.TestRunners.DevStoreTests;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.table.TableQuery.QueryComparisons;
import com.microsoft.azure.storage.table.TableTestHelper.Class1;
import com.microsoft.azure.storage.table.TableTestHelper.ComplexEntity;
import com.microsoft.azure.storage.table.TableTestHelper.EmptyClass;
import static org.junit.Assert.*;
/**
* Table Query Tests
*/
@Category({ DevFabricTests.class, DevStoreTests.class, CloudTests.class })
public class TableQueryTests {
private static CloudTable table;
@BeforeClass
public static void setup() throws URISyntaxException, StorageException {
table = TableTestHelper.getRandomTableReference();
table.createIfNotExists();
// Insert 500 entities in Batches to query
for (int i = 0; i < 5; i++) {
TableBatchOperation batch = new TableBatchOperation();
for (int j = 0; j < 100; j++) {
Class1 ent = TableTestHelper.generateRandomEntity("javatables_batch_" + Integer.toString(i));
ent.setRowKey(String.format("%06d", j));
batch.insert(ent);
}
table.execute(batch);
}
}
@AfterClass
public static void teardown() throws StorageException {
table.deleteIfExists();
}
@Test
public void testQueryWithNullClassType() {
try {
TableQuery.from(null);
}
catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), String.format(SR.ARGUMENT_NULL_OR_EMPTY, "class type"));
}
}
@Test
public void testQueryWithInvalidTakeCount() {
try {
TableQuery.from(TableServiceEntity.class).take(0);
}
catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Take count must be positive and greater than 0.");
}
try {
TableQuery.from(TableServiceEntity.class).take(-1);
}
catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Take count must be positive and greater than 0.");
}
}
@Test
public void testTableWithSelectOnMissingFields() throws StorageException {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableWithSelectOnMissingFields(options);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableWithSelectOnMissingFields(options);
}
private void testTableWithSelectOnMissingFields(TableRequestOptions options) throws StorageException {
TableQuery<DynamicTableEntity> projectionQuery = TableQuery.from(DynamicTableEntity.class).where(
"(PartitionKey eq 'javatables_batch_0') and (RowKey eq '000000')");
// A exists, F does not
projectionQuery.select(new String[]{"A", "F"});
ResultSegment<DynamicTableEntity> seg = table.executeSegmented(projectionQuery, null, options, null);
assertEquals(1, seg.getResults().size());
DynamicTableEntity ent = seg.getResults().get(0);
assertEquals("foo_A", ent.getProperties().get("A").getValueAsString());
assertEquals(null, ent.getProperties().get("F").getValueAsString());
assertEquals(EdmType.STRING, ent.getProperties().get("F").getEdmType());
}
@Test
public void testTableQueryProjectionWithNull() throws URISyntaxException, StorageException {
CloudTable table = TableTestHelper.getRandomTableReference();
try {
// Create a new table so we don't pollute the main query table
table.createIfNotExists();
// Insert an entity which is missing String and IntegerPrimitive
DynamicTableEntity entity = new DynamicTableEntity(UUID.randomUUID().toString(), UUID.randomUUID()
.toString());
table.execute(TableOperation.insert(entity));
testTableQueryProjectionWithSpecialCases(table);
}
finally {
table.deleteIfExists();
}
}
@Test
public void testTableQueryProjectionWithIncorrectTypes() throws URISyntaxException, StorageException {
CloudTable table = TableTestHelper.getRandomTableReference();
try {
// Create a new table so we don't pollute the main query table
table.createIfNotExists();
// Insert an entity with String as an int, and IntegerPrimitive as a bool
DynamicTableEntity entity = new DynamicTableEntity(UUID.randomUUID().toString(), UUID.randomUUID()
.toString());
entity.getProperties().put("String", new EntityProperty(1234));
entity.getProperties().put("IntegerPrimitive", new EntityProperty(true));
table.execute(TableOperation.insert(entity));
testTableQueryProjectionWithSpecialCases(table);
}
finally {
table.deleteIfExists();
}
}
private void testTableQueryProjectionWithSpecialCases(CloudTable table) {
table.getServiceClient().getDefaultRequestOptions().setTablePayloadFormat(TablePayloadFormat.Json);
// Query on String and IntegerPrimitive
TableQuery<ComplexEntity> query = TableQuery.from(ComplexEntity.class).select(
new String[] { "String", "IntegerPrimitive"});
Iterable<ComplexEntity> iterable = table.execute(query);
List<ComplexEntity> entities = new ArrayList<ComplexEntity>();
for (ComplexEntity entity : iterable) {
entities.add(entity);
}
// Verify A has a set value and B and E have class defaults
assertEquals(1, entities.size());
ComplexEntity entity = entities.get(0);
assertNull(entity.getString());
assertEquals(-1, entity.getIntegerPrimitive());
}
@Test
public void testTableQueryWithSpecialChars() throws StorageException, URISyntaxException {
CloudTable table = TableTestHelper.getRandomTableReference();
try {
table.createIfNotExists();
testTableQueryWithSpecialChars('\'', table);
testTableQueryWithSpecialChars('=', table);
testTableQueryWithSpecialChars('_', table);
testTableQueryWithSpecialChars(' ', table);
testTableQueryWithSpecialChars('界', table);
}
finally {
table.deleteIfExists();
}
}
private void testTableQueryWithSpecialChars(char charToTest, CloudTable table)
throws StorageException, URISyntaxException {
String partitionKey = "partition" + charToTest + "key";
String rowKey = "row" + charToTest + "key";
EmptyClass ref = new EmptyClass();
ref.setPartitionKey(partitionKey);
ref.setRowKey(rowKey);
table.execute(TableOperation.insert(ref));
String condition = TableQuery.generateFilterCondition(TableConstants.PARTITION_KEY, QueryComparisons.EQUAL, partitionKey);
ResultSegment<EmptyClass> seg = table.executeSegmented(TableQuery.from(EmptyClass.class).where(condition), null);
assertEquals(1, seg.getLength());
assertEquals(partitionKey, seg.getResults().get(0).getPartitionKey());
}
@Test
public void testTableInvalidQuery() throws StorageException {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.Json);
TableQuery<Class1> query = TableQuery.from(Class1.class).where(
String.format("(PartitionKey ) and (RowKey ge '%s')", "000050"));
try {
table.executeSegmented(query, null, options, null);
fail();
}
catch (TableServiceException ex) {
assertEquals(ex.getMessage(), "Bad Request");
assertTrue(ex.getExtendedErrorInformation().getErrorMessage()
.startsWith("A binary operator with incompatible types was detected. Found operand types 'Edm.String' and 'Edm.Boolean' for operator kind 'And'."));
assertEquals(ex.getExtendedErrorInformation().getErrorCode(), "InvalidInput");
}
}
@Test
public void testQueryOnSupportedTypes() throws StorageException, InterruptedException {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testQueryOnSupportedTypes(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testQueryOnSupportedTypes(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testQueryOnSupportedTypes(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testQueryOnSupportedTypes(options, true);
}
private void testQueryOnSupportedTypes(TableRequestOptions options, boolean usePropertyResolver)
throws StorageException, InterruptedException {
// Setup
TableBatchOperation batch = new TableBatchOperation();
String pk = UUID.randomUUID().toString();
long maxInt = Integer.MAX_VALUE; // used to ensure the test sends longs that cannot be interpreted as ints
ComplexEntity middleRef = null;
for (int j = 0; j < 100; j++) {
ComplexEntity ent = new ComplexEntity();
ent.setPartitionKey(pk);
ent.setRowKey(String.format("%04d", j));
ent.setBinary(new Byte[] { 0x01, 0x02, (byte) j });
ent.setBinaryPrimitive(new byte[] { 0x01, 0x02, (byte) j });
ent.setBool(j % 2 == 0 ? true : false);
ent.setBoolPrimitive(j % 2 == 0 ? true : false);
ent.setDateTime(new Date());
ent.setDouble(j + ((double) j) / 100);
ent.setDoublePrimitive(j + ((double) j) / 100);
ent.setInt32(j);
ent.setInt64(j + maxInt);
ent.setIntegerPrimitive(j);
ent.setLongPrimitive(j + maxInt);
ent.setGuid(UUID.randomUUID());
ent.setString(String.format("%04d", j));
// Add delay to make times unique
Thread.sleep(50);
batch.insert(ent);
if (j == 50) {
middleRef = ent;
}
}
if (usePropertyResolver) {
options.setPropertyResolver(middleRef);
}
table.execute(batch, options, null);
try {
// 1. Filter on String
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("String", QueryComparisons.GREATER_THAN_OR_EQUAL, "0050"), 50,
options, usePropertyResolver);
// 2. Filter on UUID
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Guid", QueryComparisons.EQUAL, middleRef.getGuid()), 1,
options, usePropertyResolver);
// 3. Filter on Long
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Int64", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getInt64()), 50, options, usePropertyResolver);
executeQueryAndAssertResults(TableQuery.generateFilterCondition("LongPrimitive",
QueryComparisons.GREATER_THAN_OR_EQUAL, middleRef.getInt64()), 50, options, usePropertyResolver);
// 4. Filter on Double
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Double", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getDouble()), 50, options, usePropertyResolver);
executeQueryAndAssertResults(TableQuery.generateFilterCondition("DoublePrimitive",
QueryComparisons.GREATER_THAN_OR_EQUAL, middleRef.getDouble()), 50, options, usePropertyResolver);
// 5. Filter on Integer
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Int32", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getInt32()), 50, options, usePropertyResolver);
executeQueryAndAssertResults(TableQuery.generateFilterCondition("IntegerPrimitive",
QueryComparisons.GREATER_THAN_OR_EQUAL, middleRef.getInt32()), 50, options, usePropertyResolver);
// 6. Filter on Date
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("DateTime", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getDateTime()), 50, options, usePropertyResolver);
// 7. Filter on Boolean
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Bool", QueryComparisons.EQUAL, middleRef.getBool()), 50,
options, usePropertyResolver);
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("BoolPrimitive", QueryComparisons.EQUAL, middleRef.getBool()),
50, options, usePropertyResolver);
// 8. Filter on Binary
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Binary", QueryComparisons.EQUAL, middleRef.getBinary()), 1,
options, usePropertyResolver);
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("BinaryPrimitive", QueryComparisons.EQUAL,
middleRef.getBinaryPrimitive()), 1, options, usePropertyResolver);
// 9. Filter on Binary GTE
executeQueryAndAssertResults(
TableQuery.generateFilterCondition("Binary", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getBinary()), 50, options, usePropertyResolver);
executeQueryAndAssertResults(TableQuery.generateFilterCondition("BinaryPrimitive",
QueryComparisons.GREATER_THAN_OR_EQUAL, middleRef.getBinaryPrimitive()), 50, options,
usePropertyResolver);
// 10. Complex Filter on Binary GTE
executeQueryAndAssertResults(TableQuery.combineFilters(
TableQuery.generateFilterCondition(TableConstants.PARTITION_KEY, QueryComparisons.EQUAL,
middleRef.getPartitionKey()),
TableQuery.Operators.AND,
TableQuery.generateFilterCondition("Binary", QueryComparisons.GREATER_THAN_OR_EQUAL,
middleRef.getBinary())), 50, options, usePropertyResolver);
executeQueryAndAssertResults(TableQuery.generateFilterCondition("BinaryPrimitive",
QueryComparisons.GREATER_THAN_OR_EQUAL, middleRef.getBinaryPrimitive()), 50, options,
usePropertyResolver);
}
finally {
// cleanup
TableBatchOperation delBatch = new TableBatchOperation();
TableQuery<ComplexEntity> query = TableQuery.from(ComplexEntity.class).where(
String.format("PartitionKey eq '%s'", pk));
for (ComplexEntity e : table.execute(query, options, null)) {
delBatch.delete(e);
}
table.execute(delBatch, options, null);
}
}
private void executeQueryAndAssertResults(String filter, int expectedResults, TableRequestOptions options,
boolean usePropertyResolver) {
// instantiate class to use property resolver
ComplexEntity ent = new ComplexEntity();
if (usePropertyResolver) {
options.setPropertyResolver(ent);
}
int count = 0;
TableQuery<ComplexEntity> query = TableQuery.from(ComplexEntity.class).where(filter);
for (@SuppressWarnings("unused")
ComplexEntity e : table.execute(query, options, null)) {
count++;
}
assertEquals(expectedResults, count);
}
@Test
public void testTableQueryIterateTwice() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryIterateTwice(options);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryIterateTwice(options);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryIterateTwice(options);
}
private void testTableQueryIterateTwice(TableRequestOptions options) {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
final Iterable<DynamicTableEntity> result = table.execute(TableQuery.from(DynamicTableEntity.class).take(50),
options, null);
ArrayList<DynamicTableEntity> firstIteration = new ArrayList<DynamicTableEntity>();
ArrayList<DynamicTableEntity> secondIteration = new ArrayList<DynamicTableEntity>();
// Validate results
for (DynamicTableEntity ent : result) {
assertEquals(ent.getProperties().size(), 4);
assertEquals(ent.getProperties().get("A").getValueAsString(), randEnt.getA());
assertEquals(ent.getProperties().get("B").getValueAsString(), randEnt.getB());
assertEquals(ent.getProperties().get("C").getValueAsString(), randEnt.getC());
assertTrue(Arrays.equals(ent.getProperties().get("D").getValueAsByteArray(), randEnt.getD()));
firstIteration.add(ent);
}
// Validate results
for (DynamicTableEntity ent : result) {
assertEquals(ent.getProperties().size(), 4);
assertEquals(ent.getProperties().get("A").getValueAsString(), randEnt.getA());
assertEquals(ent.getProperties().get("B").getValueAsString(), randEnt.getB());
assertEquals(ent.getProperties().get("C").getValueAsString(), randEnt.getC());
assertTrue(Arrays.equals(ent.getProperties().get("D").getValueAsByteArray(), randEnt.getD()));
secondIteration.add(ent);
}
assertEquals(firstIteration.size(), secondIteration.size());
for (int m = 0; m < firstIteration.size(); m++) {
assertEquals(firstIteration.get(m).getPartitionKey(), secondIteration.get(m).getPartitionKey());
assertEquals(firstIteration.get(m).getRowKey(), secondIteration.get(m).getRowKey());
assertEquals(firstIteration.get(m).getProperties().size(), secondIteration.get(m).getProperties().size());
assertEquals(firstIteration.get(m).getProperties().get("A").getValueAsString(), secondIteration.get(m)
.getProperties().get("A").getValueAsString());
assertEquals(firstIteration.get(m).getProperties().get("B").getValueAsString(), secondIteration.get(m)
.getProperties().get("B").getValueAsString());
assertEquals(firstIteration.get(m).getProperties().get("C").getValueAsString(), secondIteration.get(m)
.getProperties().get("C").getValueAsString());
assertTrue(Arrays.equals(firstIteration.get(m).getProperties().get("D").getValueAsByteArray(),
secondIteration.get(m).getProperties().get("D").getValueAsByteArray()));
}
}
@Test
public void testTableQueryWithDynamicEntity() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithDynamicEntity(options);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithDynamicEntity(options);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithDynamicEntity(options);
}
private void testTableQueryWithDynamicEntity(TableRequestOptions options) {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
final Iterable<DynamicTableEntity> result = table.execute(TableQuery.from(DynamicTableEntity.class), options,
null);
// Validate results
for (DynamicTableEntity ent : result) {
assertEquals(ent.getProperties().size(), 4);
assertEquals(ent.getProperties().get("A").getValueAsString(), randEnt.getA());
assertEquals(ent.getProperties().get("B").getValueAsString(), randEnt.getB());
assertEquals(ent.getProperties().get("C").getValueAsString(), randEnt.getC());
assertTrue(Arrays.equals(ent.getProperties().get("D").getValueAsByteArray(), randEnt.getD()));
}
}
@Test
public void testTableQueryWithProjection() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithProjection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithProjection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithProjection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithProjection(options, true);
}
private void testTableQueryWithProjection(TableRequestOptions options, boolean usePropertyResolver) {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
final Iterable<Class1> result = table.execute(TableQuery.from(Class1.class).select(new String[] { "A", "C" }),
options, null);
// Validate results
for (Class1 ent : result) {
// Validate core properties were sent.
assertNotNull(ent.getPartitionKey());
assertNotNull(ent.getRowKey());
assertNotNull(ent.getTimestamp());
// Validate correct column returned.
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), null);
assertEquals(ent.getC(), randEnt.getC());
assertEquals(ent.getD(), null);
}
}
@Test
public void testSelectOnlySendsReservedColumnsOnce() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testSelectOnlySendsReservedColumnsOnce(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testSelectOnlySendsReservedColumnsOnce(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testSelectOnlySendsReservedColumnsOnce(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testSelectOnlySendsReservedColumnsOnce(options, true);
}
private void testSelectOnlySendsReservedColumnsOnce(TableRequestOptions options, boolean usePropertyResolver) {
// Create entity to use property resolver
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
OperationContext opContext = new OperationContext();
opContext.getResponseReceivedEventHandler().addListener(new StorageEvent<ResponseReceivedEvent>() {
@Override
public void eventOccurred(ResponseReceivedEvent eventArg) {
HttpURLConnection conn = (HttpURLConnection) eventArg.getConnectionObject();
String urlString = conn.getURL().toString();
assertEquals(urlString.indexOf("PartitionKey"), urlString.lastIndexOf("PartitionKey"));
assertEquals(urlString.indexOf("RowKey"), urlString.lastIndexOf("RowKey"));
assertEquals(urlString.indexOf("Timestamp"), urlString.lastIndexOf("Timestamp"));
}
});
final Iterable<Class1> result = table.execute(
TableQuery.from(Class1.class).select(new String[] { "PartitionKey", "RowKey", "Timestamp" }), options,
opContext);
// Validate results
for (Class1 ent : result) {
assertEquals(ent.getA(), null);
assertEquals(ent.getB(), null);
assertEquals(ent.getC(), null);
assertEquals(ent.getD(), null);
}
}
@Test
public void testTableQueryWithReflection() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithReflection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithReflection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithReflection(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithReflection(options, true);
}
private void testTableQueryWithReflection(TableRequestOptions options, boolean usePropertyResolver) {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
final Iterable<Class1> result = table.execute(TableQuery.from(Class1.class), options, null);
// Validate results
for (Class1 ent : result) {
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), randEnt.getB());
assertEquals(ent.getC(), randEnt.getC());
assertTrue(Arrays.equals(ent.getD(), randEnt.getD()));
}
}
@Test
public void testTableQueryWithEntityResolver() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithEntityResolver(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithEntityResolver(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithEntityResolver(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithEntityResolver(options, true);
}
private void testTableQueryWithEntityResolver(TableRequestOptions options, boolean usePropertyResolver) {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
final Iterable<Class1> result = table.execute(TableQuery.from(TableServiceEntity.class),
new EntityResolver<Class1>() {
@Override
public Class1 resolve(String partitionKey, String rowKey, Date timeStamp,
HashMap<String, EntityProperty> properties, String etag) {
assertEquals(properties.size(), 4);
Class1 ref = new Class1();
ref.setA(properties.get("A").getValueAsString());
ref.setB(properties.get("B").getValueAsString());
ref.setC(properties.get("C").getValueAsString());
ref.setD(properties.get("D").getValueAsByteArray());
return ref;
}
}, options, null);
// Validate results
for (Class1 ent : result) {
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), randEnt.getB());
assertEquals(ent.getC(), randEnt.getC());
assertTrue(Arrays.equals(ent.getD(), randEnt.getD()));
}
}
@Test
public void testTableQueryWithTake() throws StorageException {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithTake(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithTake(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithTake(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithTake(options, true);
}
private void testTableQueryWithTake(TableRequestOptions options, boolean usePropertyResolver)
throws StorageException {
// Create entity to check against
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
final ResultSegment<Class1> result = table.executeSegmented(
TableQuery.from(Class1.class).select(new String[] { "A", "C" }).take(25), null, options, null);
int count = 0;
// Validate results
for (Class1 ent : result.getResults()) {
count++;
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), null);
assertEquals(ent.getC(), randEnt.getC());
assertEquals(ent.getD(), null);
}
assertEquals(count, 25);
}
@Test
public void testTableQueryWithFilter() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithFilter(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithFilter(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithFilter(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithFilter(options, true);
}
private void testTableQueryWithFilter(TableRequestOptions options, boolean usePropertyResolver) {
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
TableQuery<Class1> query = TableQuery.from(Class1.class).where(
String.format("(PartitionKey eq '%s') and (RowKey ge '%s')", "javatables_batch_1", "000050"));
int count = 0;
for (Class1 ent : table.execute(query, options, null)) {
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), randEnt.getB());
assertEquals(ent.getC(), randEnt.getC());
assertEquals(ent.getPartitionKey(), "javatables_batch_1");
assertEquals(ent.getRowKey(), String.format("%06d", count + 50));
count++;
}
assertEquals(count, 50);
}
@Test
public void testTableQueryWithContinuation() {
TableRequestOptions options = new TableRequestOptions();
options.setTablePayloadFormat(TablePayloadFormat.JsonFullMetadata);
testTableQueryWithContinuation(options, false);
options.setTablePayloadFormat(TablePayloadFormat.Json);
testTableQueryWithContinuation(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithContinuation(options, false);
options.setTablePayloadFormat(TablePayloadFormat.JsonNoMetadata);
testTableQueryWithContinuation(options, true);
}
private void testTableQueryWithContinuation(TableRequestOptions options, boolean usePropertyResolver) {
Class1 randEnt = TableTestHelper.generateRandomEntity(null);
if (usePropertyResolver) {
options.setPropertyResolver(randEnt);
}
TableQuery<Class1> query = TableQuery.from(Class1.class)
.where(String.format("(PartitionKey ge '%s') and (RowKey ge '%s')", "javatables_batch_1", "000050"))
.take(25);
// take will cause the query to return 25 at a time
int count = 0;
int pk = 1;
for (Class1 ent : table.execute(query, options, null)) {
assertEquals(ent.getA(), randEnt.getA());
assertEquals(ent.getB(), randEnt.getB());
assertEquals(ent.getC(), randEnt.getC());
assertEquals(ent.getPartitionKey(), "javatables_batch_" + Integer.toString(pk));
assertEquals(ent.getRowKey(), String.format("%06d", count % 50 + 50));
count++;
if (count % 50 == 0) {
pk++;
}
}
assertEquals(count, 200);
}
}