diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
new file mode 100644
index 000000000000..d64994e69c76
--- /dev/null
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.MoreObjects;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Google Cloud BigQuery Query Request. This class can be used to run a BigQuery SQL query and
+ * return results if the query completes within a specified timeout. The query results are saved to
+ * a temporary table that is deleted approximately 24 hours after the query is run. The query is run
+ * through a BigQuery Job whose identity can be accessed via {@link QueryResponse#jobId()}.
+ *
+ * @see Query
+ * @see Query Reference
+ */
+public class QueryRequest implements Serializable {
+
+ private static final long serialVersionUID = -8727328332415880852L;
+
+ private final String query;
+ private final Long maxResults;
+ private final DatasetId defaultDataset;
+ private final Long maxWaitTime;
+ private final Boolean dryRun;
+ private final Boolean useQueryCache;
+
+ public static final class Builder {
+
+ private String query;
+ private Long maxResults;
+ private DatasetId defaultDataset;
+ private Long maxWaitTime;
+ private Boolean dryRun;
+ private Boolean useQueryCache;
+
+ private Builder() {}
+
+ /**
+ * Sets the BigQuery query to be executed.
+ */
+ public Builder query(String query) {
+ this.query = checkNotNull(query);
+ return this;
+ }
+
+ /**
+ * Sets the maximum number of rows of data to return per page of results. Setting this flag to a
+ * small value such as 1000 and then paging through results might improve reliability when the
+ * query result set is large. In addition to this limit, responses are also limited to 10 MB.
+ * By default, there is no maximum row count, and only the byte limit applies.
+ */
+ public Builder maxResults(Long maxResults) {
+ this.maxResults = maxResults;
+ return this;
+ }
+
+ /**
+ * Sets the default dataset to assume for any unqualified table names in the query.
+ */
+ public Builder defaultDataset(DatasetId defaultDataset) {
+ this.defaultDataset = defaultDataset;
+ return this;
+ }
+
+ /**
+ * Sets how long to wait for the query to complete, in milliseconds, before the request times
+ * out and returns. Note that this is only a timeout for the request, not the query. If the
+ * query takes longer to run than the timeout value, the call returns without any results and
+ * with the {@link QueryResponse#jobComplete()} set to {@code false}. If not set, a wait time of
+ * 10000 milliseconds (10 seconds) is used.
+ */
+ public Builder maxWaitTime(Long maxWaitTime) {
+ this.maxWaitTime = maxWaitTime;
+ return this;
+ }
+
+ /**
+ * Sets whether the query has to be dry run or not. If set, the query is not executed. If the
+ * query is valid statistics are returned on how many bytes would be processed. If the query is
+ * invalid an error is returned. If not set the query is executed.
+ */
+ public Builder dryRun(Boolean dryRun) {
+ this.dryRun = dryRun;
+ return this;
+ }
+
+ /**
+ * Sets whether to look for the result in the query cache. The query cache is a best-effort
+ * cache that will be flushed whenever tables in the query are modified. If not specified the
+ * query cache is used.
+ *
+ * @see Query Caching
+ */
+ public Builder useQueryCache(Boolean useQueryCache) {
+ this.useQueryCache = useQueryCache;
+ return this;
+ }
+
+ public QueryRequest build() {
+ return new QueryRequest(this);
+ }
+ }
+
+ private QueryRequest(Builder builder) {
+ query = builder.query;
+ maxResults = builder.maxResults;
+ defaultDataset = builder.defaultDataset;
+ maxWaitTime = builder.maxWaitTime;
+ dryRun = builder.dryRun;
+ useQueryCache = builder.useQueryCache;
+ }
+
+ /**
+ * Sets the BigQuery query to be executed.
+ */
+ public String query() {
+ return query;
+ }
+
+ /**
+ * Returns the maximum number of rows of data to return per page of results.
+ */
+ public Long maxResults() {
+ return maxResults;
+ }
+
+ /**
+ * Returns the default dataset to assume for any unqualified table names in the query.
+ */
+ public DatasetId defaultDataset() {
+ return defaultDataset;
+ }
+
+ /**
+ * Returns how long to wait for the query to complete, in milliseconds, before the request times
+ * out and returns. Note that this is only a timeout for the request, not the query. If the
+ * query takes longer to run than the timeout value, the call returns without any results and
+ * with the {@link QueryResponse#jobComplete()} set to {@code false}. You can call
+ * {@link BigQuery#getQueryResults(JobId, BigQuery.QueryResultsOption...)} to wait for the query
+ * to complete and read the results. If not set, a wait time of 10000 milliseconds (10 seconds)
+ * is used.
+ */
+ public Long maxWaitTime() {
+ return maxWaitTime;
+ }
+
+ /**
+ * Returns whether the query has to be dry run or not. If set, the query is not executed. If the
+ * query is valid statistics are returned on how many bytes would be processed. If the query is
+ * invalid an error is returned. If not set the query is executed.
+ */
+ public Boolean dryRun() {
+ return dryRun;
+ }
+
+ /**
+ * Returns whether to look for the result in the query cache. The query cache is a best-effort
+ * cache that will be flushed whenever tables in the query are modified. If not specified the
+ * query cache is used.
+ *
+ * @see Query Caching
+ */
+ public Boolean useQueryCache() {
+ return useQueryCache;
+ }
+
+ /**
+ * Returns a builder for the {@code QueryRequest} object.
+ */
+ public Builder toBuilder() {
+ return new Builder()
+ .query(query)
+ .maxResults(maxResults)
+ .defaultDataset(defaultDataset)
+ .maxWaitTime(maxWaitTime)
+ .dryRun(dryRun)
+ .useQueryCache(useQueryCache);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("query", query)
+ .add("maxResults", maxResults)
+ .add("defaultDataset", defaultDataset)
+ .add("maxWaitTime", maxWaitTime)
+ .add("dryRun", dryRun)
+ .add("useQueryCache", useQueryCache)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(query, maxResults, defaultDataset, maxWaitTime, dryRun, useQueryCache);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof QueryRequest && Objects.equals(toPb(), ((QueryRequest) obj).toPb());
+ }
+
+ com.google.api.services.bigquery.model.QueryRequest toPb() {
+ com.google.api.services.bigquery.model.QueryRequest queryRequestPb =
+ new com.google.api.services.bigquery.model.QueryRequest().setQuery(query);
+ if (maxResults != null) {
+ queryRequestPb.setMaxResults(maxResults);
+ }
+ if (defaultDataset != null) {
+ queryRequestPb.setDefaultDataset(defaultDataset.toPb());
+ }
+ if (maxWaitTime != null) {
+ queryRequestPb.setTimeoutMs(maxWaitTime);
+ }
+ if (dryRun != null) {
+ queryRequestPb.setDryRun(dryRun);
+ }
+ if (useQueryCache != null) {
+ queryRequestPb.setUseQueryCache(useQueryCache);
+ }
+ return queryRequestPb;
+ }
+
+ /**
+ * Creates a builder for a {@code QueryRequest} given the BigQuery SQL query to be executed.
+ */
+ public static Builder builder(String query) {
+ return new Builder().query(query);
+ }
+
+ /**
+ * Creates a {@code QueryRequest} object given the BigQuery SQL query to be executed.
+ */
+ public static QueryRequest of(String query) {
+ return new Builder().query(query).build();
+ }
+
+ static QueryRequest fromPb(com.google.api.services.bigquery.model.QueryRequest queryRequestPb) {
+ Builder builder = builder(queryRequestPb.getQuery());
+ if (queryRequestPb.getMaxResults() != null) {
+ builder.maxResults(queryRequestPb.getMaxResults());
+ }
+ if (queryRequestPb.getDefaultDataset() != null) {
+ builder.defaultDataset(DatasetId.fromPb(queryRequestPb.getDefaultDataset()));
+ }
+ if (queryRequestPb.getTimeoutMs() != null) {
+ builder.maxWaitTime(queryRequestPb.getTimeoutMs());
+ }
+ if (queryRequestPb.getDryRun() != null) {
+ builder.dryRun(queryRequestPb.getDryRun());
+ }
+ if (queryRequestPb.getUseQueryCache() != null) {
+ builder.useQueryCache(queryRequestPb.getUseQueryCache());
+ }
+ return builder.build();
+ }
+}
diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java
new file mode 100644
index 000000000000..b7bd5dc0efd0
--- /dev/null
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Google Cloud BigQuery Query Response. This class contains the results of a Query Job or of a
+ * Query Request.
+ *
+ *
Example usage of a query response:
+ *
{@code
+ * QueryResponse response = bigquery.query(request);
+ * while (!response.jobComplete()) {
+ * response = bigquery.getQueryResults(response.jobId());
+ * Thread.sleep(1000);
+ * }
+ * List executionErrors = response.executionErrors();
+ * // look for errors in executionErrors
+ * QueryResult result = response.result();
+ * Iterator> rowIterator = result.iterateAll();
+ * while(rowIterator.hasNext()) {
+ * List row = rowIterator.next();
+ * // do something with row
+ * }
+ * }
+ *
+ * @see Get Query
+ * Results
+ * @see Query
+ */
+public class QueryResponse implements Serializable {
+
+ private static final long serialVersionUID = 3549226764825005655L;
+
+ private final QueryResult result;
+ private final String etag;
+ private final JobId jobId;
+ private final boolean jobComplete;
+ private final List executionErrors;
+
+ static final class Builder {
+
+ private QueryResult result;
+ private String etag;
+ private JobId jobId;
+ private boolean jobComplete;
+ private List executionErrors;
+
+ private Builder() {}
+
+ Builder result(QueryResult result) {
+ this.result = result;
+ return this;
+ }
+
+ Builder etag(String etag) {
+ this.etag = etag;
+ return this;
+ }
+
+ Builder jobId(JobId jobId) {
+ this.jobId = jobId;
+ return this;
+ }
+
+ Builder jobComplete(boolean jobComplete) {
+ this.jobComplete = jobComplete;
+ return this;
+ }
+
+ Builder executionErrors(List executionErrors) {
+ this.executionErrors = executionErrors;
+ return this;
+ }
+
+ QueryResponse build() {
+ return new QueryResponse(this);
+ }
+ }
+
+ private QueryResponse(Builder builder) {
+ this.result = builder.result;
+ this.etag = builder.etag;
+ this.jobId = builder.jobId;
+ this.jobComplete = builder.jobComplete;
+ this.executionErrors = builder.executionErrors != null ? builder.executionErrors
+ : ImmutableList.of();
+ }
+
+ /**
+ * Returns the result of the query. Returns {@code null} if {@link #jobComplete()} is {@code
+ * false}.
+ */
+ public QueryResult result() {
+ return result;
+ }
+
+ /**
+ * Returns the hash of the {@code QueryResponse} resource or {@code null} if not set.
+ */
+ public String etag() {
+ return etag;
+ }
+
+ /**
+ * Returns the identity of the BigQuery Job that was created to run the query. This field will be
+ * present even if the original request timed out.
+ */
+ public JobId jobId() {
+ return jobId;
+ }
+
+ /**
+ * Returns whether the job running the query has completed or not. If {@link #result()} is not
+ * {@code null}, this method will always return {@code true}. If this method returns {@code false}
+ * {@link #result()} returns {@code null}. This method can be used to check if query execution
+ * completed and results are available.
+ */
+ public boolean jobComplete() {
+ return jobComplete;
+ }
+
+ /**
+ * Returns whether errors and warnings occurred during the execution of the job. If this method
+ * returns {@code true} it does not necessarily mean that the job has completed or was
+ * unsuccessful.
+ */
+ public boolean hasErrors() {
+ return !executionErrors.isEmpty();
+ }
+
+ /**
+ * Returns errors and warnings encountered during the running of the job, if any. Errors here do
+ * not necessarily mean that the job has completed or was unsuccessful.
+ */
+ public List executionErrors() {
+ return executionErrors;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("result", result)
+ .add("etag", etag)
+ .add("jobId", jobId)
+ .add("jobComplete", jobComplete)
+ .add("executionErrors", executionErrors)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(jobId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ QueryResponse response = (QueryResponse) obj;
+ return jobComplete == response.jobComplete
+ && Objects.equals(etag, response.etag)
+ && Objects.equals(result, response.result)
+ && Objects.equals(jobId, response.jobId)
+ && Objects.equals(executionErrors, response.executionErrors);
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java
new file mode 100644
index 000000000000..692abab937a9
--- /dev/null
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import com.google.gcloud.PageImpl;
+
+import java.util.List;
+import java.util.Objects;
+
+public class QueryResult extends PageImpl> {
+
+ private static final long serialVersionUID = -4831062717210349818L;
+
+ private final boolean cacheHit;
+ private final Schema schema;
+ private final long totalRows;
+ private final long totalBytesProcessed;
+
+ interface QueryResultsPageFetcher extends PageImpl.NextPageFetcher> {
+ @Override
+ QueryResult nextPage();
+ }
+
+ static final class Builder {
+
+ private QueryResultsPageFetcher pageFetcher;
+ private String cursor;
+ private Iterable> results;
+ private boolean cacheHit;
+ private Schema schema;
+ private long totalRows;
+ private long totalBytesProcessed;
+
+ private Builder() {}
+
+ Builder cacheHit(boolean cacheHit) {
+ this.cacheHit = cacheHit;
+ return this;
+ }
+
+ Builder schema(Schema schema) {
+ this.schema = schema;
+ return this;
+ }
+
+ Builder totalBytesProcessed(long totalBytesProcessed) {
+ this.totalBytesProcessed = totalBytesProcessed;
+ return this;
+ }
+
+ Builder totalRows(long totalRows) {
+ this.totalRows = totalRows;
+ return this;
+ }
+
+ Builder pageFetcher(QueryResultsPageFetcher pageFetcher) {
+ this.pageFetcher = pageFetcher;
+ return this;
+ }
+
+ Builder cursor(String cursor) {
+ this.cursor = cursor;
+ return this;
+ }
+
+ Builder results(Iterable> results) {
+ this.results = results;
+ return this;
+ }
+
+ QueryResult build() {
+ return new QueryResult(this);
+ }
+ }
+
+ private QueryResult(Builder builder) {
+ super(builder.pageFetcher, builder.cursor, builder.results != null ? builder.results
+ : ImmutableList.>of());
+ this.cacheHit = builder.cacheHit;
+ this.schema = builder.schema;
+ this.totalBytesProcessed = builder.totalBytesProcessed;
+ this.totalRows = builder.totalRows;
+ }
+
+ /**
+ * Returns whether the query result was fetched from the query cache.
+ *
+ * @see Query Caching
+ */
+ public boolean cacheHit() {
+ return cacheHit;
+ }
+
+ /**
+ * Returns the schema of the results. This is present only when the query completes successfully.
+ */
+ public Schema schema() {
+ return schema;
+ }
+
+ /**
+ * Returns the total number of bytes processed for the query. If this query was a dry run, this is
+ * the number of bytes that would be processed if the query were run.
+ */
+ public long totalBytesProcessed() {
+ return totalBytesProcessed;
+ }
+
+ /**
+ * Returns the total number of rows in the complete query result set, which can be more than the
+ * number of rows in the first page of results returned by {@link #values()}. Returns {@code 0}
+ * if the query was a dry run.
+ */
+ public long totalRows() {
+ return totalRows;
+ }
+
+ @Override
+ public QueryResult nextPage() {
+ return (QueryResult) super.nextPage();
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("rows", values())
+ .add("cacheHit", cacheHit)
+ .add("schema", schema)
+ .add("totalBytesProcessed", totalBytesProcessed)
+ .add("totalRows", totalRows)
+ .add("cursor", nextPageCursor())
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), cacheHit, schema, totalBytesProcessed, totalRows);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ QueryResult response = (QueryResult) obj;
+ return Objects.equals(nextPageCursor(), response.nextPageCursor())
+ && Objects.equals(values(), response.values())
+ && Objects.equals(schema, response.schema)
+ && totalRows == response.totalRows
+ && totalBytesProcessed == response.totalBytesProcessed
+ && cacheHit == response.cacheHit;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java
new file mode 100644
index 000000000000..276e4f6792b3
--- /dev/null
+++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class QueryRequestTest {
+
+ private static final String QUERY = "BigQuery SQL";
+ private static final DatasetId DATASET_ID = DatasetId.of("project", "dataset");
+ private static final Boolean USE_QUERY_CACHE = true;
+ private static final Boolean DRY_RUN = false;
+ private static final Long MAX_RESULTS = 42L;
+ private static final Long MAX_WAIT_TIME = 42000L;
+ private static final QueryRequest QUERY_REQUEST = QueryRequest.builder(QUERY)
+ .useQueryCache(USE_QUERY_CACHE)
+ .defaultDataset(DATASET_ID)
+ .dryRun(DRY_RUN)
+ .maxResults(MAX_RESULTS)
+ .maxWaitTime(MAX_WAIT_TIME)
+ .build();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testToBuilder() {
+ compareQueryRequest(QUERY_REQUEST, QUERY_REQUEST.toBuilder().build());
+ QueryRequest queryRequest = QUERY_REQUEST.toBuilder()
+ .query("New BigQuery SQL")
+ .build();
+ assertEquals("New BigQuery SQL", queryRequest.query());
+ queryRequest = queryRequest.toBuilder().query(QUERY).build();
+ compareQueryRequest(QUERY_REQUEST, queryRequest);
+ }
+
+ @Test
+ public void testToBuilderIncomplete() {
+ QueryRequest queryRequest = QueryRequest.of(QUERY);
+ compareQueryRequest(queryRequest, queryRequest.toBuilder().build());
+ }
+
+ @Test
+ public void testBuilder() {
+ assertEquals(QUERY, QUERY_REQUEST.query());
+ assertEquals(USE_QUERY_CACHE, QUERY_REQUEST.useQueryCache());
+ assertEquals(DATASET_ID, QUERY_REQUEST.defaultDataset());
+ assertEquals(DRY_RUN, QUERY_REQUEST.dryRun());
+ assertEquals(MAX_RESULTS, QUERY_REQUEST.maxResults());
+ assertEquals(MAX_WAIT_TIME, QUERY_REQUEST.maxWaitTime());
+ thrown.expect(NullPointerException.class);
+ QueryRequest.builder(null);
+ }
+
+ @Test
+ public void testOf() {
+ QueryRequest request = QueryRequest.of(QUERY);
+ assertEquals(QUERY, request.query());
+ assertNull(request.useQueryCache());
+ assertNull(request.defaultDataset());
+ assertNull(request.dryRun());
+ assertNull(request.maxResults());
+ assertNull(request.maxWaitTime());
+ thrown.expect(NullPointerException.class);
+ QueryRequest.of(null);
+ }
+
+ @Test
+ public void testToPbAndFromPb() {
+ compareQueryRequest(QUERY_REQUEST, QueryRequest.fromPb(QUERY_REQUEST.toPb()));
+ QueryRequest queryRequest = QueryRequest.of(QUERY);
+ compareQueryRequest(queryRequest, QueryRequest.fromPb(queryRequest.toPb()));
+ }
+
+ private void compareQueryRequest(QueryRequest expected, QueryRequest value) {
+ assertEquals(expected, value);
+ assertEquals(expected.query(), value.query());
+ assertEquals(expected.useQueryCache(), value.useQueryCache());
+ assertEquals(expected.defaultDataset(), value.defaultDataset());
+ assertEquals(expected.dryRun(), value.dryRun());
+ assertEquals(expected.maxResults(), value.maxResults());
+ assertEquals(expected.maxWaitTime(), value.maxWaitTime());
+ }
+}
diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java
new file mode 100644
index 000000000000..3ecae9b76e18
--- /dev/null
+++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class QueryResponseTest {
+
+ private static final String ETAG = "etag";
+ private static final Field FIELD_SCHEMA1 =
+ Field.builder("StringField", Field.Type.string())
+ .mode(Field.Mode.NULLABLE)
+ .description("FieldDescription1")
+ .build();
+ private static final Schema SCHEMA = Schema.of(FIELD_SCHEMA1);
+ private static final JobId JOB_ID = JobId.of("project", "job");
+ private static final Long TOTAL_ROWS = 42L;
+ private static final QueryResult.QueryResultsPageFetcher FETCHER =
+ new QueryResult.QueryResultsPageFetcher() {
+ @Override
+ public QueryResult nextPage() {
+ return null;
+ }
+ };
+ private static final Long TOTAL_BYTES_PROCESSED = 4200L;
+ private static final Boolean JOB_COMPLETE = true;
+ private static final List ERRORS = ImmutableList.of(
+ new BigQueryError("reason1", "location1", "message1", "debugInfo1"),
+ new BigQueryError("reason2", "location2", "message2", "debugInfo2")
+ );
+ private static final Boolean CACHE_HIT = false;
+ private static final QueryResult QUERY_RESULT = QueryResult.builder()
+ .schema(SCHEMA)
+ .totalRows(TOTAL_ROWS)
+ .totalBytesProcessed(TOTAL_BYTES_PROCESSED)
+ .cursor("cursor")
+ .pageFetcher(FETCHER)
+ .results(ImmutableList.>of())
+ .cacheHit(CACHE_HIT)
+ .build();
+ private static final QueryResponse QUERY_RESPONSE = QueryResponse.builder()
+ .etag(ETAG)
+ .jobId(JOB_ID)
+ .jobComplete(JOB_COMPLETE)
+ .executionErrors(ERRORS)
+ .result(QUERY_RESULT)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(ETAG, QUERY_RESPONSE.etag());
+ assertEquals(QUERY_RESULT, QUERY_RESPONSE.result());
+ assertEquals(JOB_ID, QUERY_RESPONSE.jobId());
+ assertEquals(JOB_COMPLETE, QUERY_RESPONSE.jobComplete());
+ assertEquals(ERRORS, QUERY_RESPONSE.executionErrors());
+ assertTrue(QUERY_RESPONSE.hasErrors());
+ }
+
+ @Test
+ public void testBuilderIncomplete() {
+ QueryResponse queryResponse = QueryResponse.builder().jobComplete(false).build();
+ assertNull(queryResponse.etag());
+ assertNull(queryResponse.result());
+ assertNull(queryResponse.jobId());
+ assertFalse(queryResponse.jobComplete());
+ assertEquals(ImmutableList.of(), queryResponse.executionErrors());
+ assertFalse(queryResponse.hasErrors());
+ }
+
+ @Test
+ public void testEquals() {
+ compareQueryResponse(QUERY_RESPONSE, QUERY_RESPONSE);
+ }
+
+ private void compareQueryResponse(QueryResponse expected, QueryResponse value) {
+ assertEquals(expected, value);
+ assertEquals(expected.etag(), value.etag());
+ assertEquals(expected.result(), value.result());
+ assertEquals(expected.jobId(), value.jobId());
+ assertEquals(expected.jobComplete(), value.jobComplete());
+ assertEquals(expected.executionErrors(), value.executionErrors());
+ assertEquals(expected.hasErrors(), value.hasErrors());
+ }
+}
diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java
new file mode 100644
index 000000000000..db2432753b52
--- /dev/null
+++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * 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.google.gcloud.bigquery;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class QueryResultTest {
+
+ private static final String CURSOR = "cursor";
+ private static final Field FIELD_SCHEMA1 =
+ Field.builder("StringField", Field.Type.string())
+ .mode(Field.Mode.NULLABLE)
+ .description("FieldDescription1")
+ .build();
+ private static final Schema SCHEMA = Schema.of(FIELD_SCHEMA1);
+ private static final long TOTAL_ROWS = 42L;
+ private static final QueryResult.QueryResultsPageFetcher FETCHER =
+ new QueryResult.QueryResultsPageFetcher() {
+ @Override
+ public QueryResult nextPage() {
+ return null;
+ }
+ };
+ private static final long TOTAL_BYTES_PROCESSED = 4200L;
+ private static final boolean CACHE_HIT = false;
+ private static final QueryResult QUERY_RESULT = QueryResult.builder()
+ .schema(SCHEMA)
+ .totalRows(TOTAL_ROWS)
+ .totalBytesProcessed(TOTAL_BYTES_PROCESSED)
+ .cursor(CURSOR)
+ .pageFetcher(FETCHER)
+ .results(ImmutableList.>of())
+ .cacheHit(CACHE_HIT)
+ .build();
+ private static final QueryResult QUERY_RESULT_INCOMPLETE = QueryResult.builder()
+ .totalBytesProcessed(TOTAL_BYTES_PROCESSED)
+ .build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(SCHEMA, QUERY_RESULT.schema());
+ assertEquals(TOTAL_ROWS, QUERY_RESULT.totalRows());
+ assertEquals(TOTAL_BYTES_PROCESSED, QUERY_RESULT.totalBytesProcessed());
+ assertEquals(CACHE_HIT, QUERY_RESULT.cacheHit());
+ assertEquals(CURSOR, QUERY_RESULT.nextPageCursor());
+ assertEquals(null, QUERY_RESULT.nextPage());
+ assertEquals(null, QUERY_RESULT_INCOMPLETE.schema());
+ assertEquals(0L, QUERY_RESULT_INCOMPLETE.totalRows());
+ assertEquals(TOTAL_BYTES_PROCESSED, QUERY_RESULT_INCOMPLETE.totalBytesProcessed());
+ assertEquals(false, QUERY_RESULT_INCOMPLETE.cacheHit());
+ assertEquals(null, QUERY_RESULT_INCOMPLETE.nextPageCursor());
+ assertEquals(null, QUERY_RESULT_INCOMPLETE.nextPage());
+ }
+
+ @Test
+ public void testEquals() {
+ compareQueryResult(QUERY_RESULT, QUERY_RESULT);
+ compareQueryResult(QUERY_RESULT_INCOMPLETE, QUERY_RESULT_INCOMPLETE);
+ }
+
+ private void compareQueryResult(QueryResult expected, QueryResult value) {
+ assertEquals(expected, value);
+ assertEquals(expected.nextPage(), value.nextPage());
+ assertEquals(expected.nextPageCursor(), value.nextPageCursor());
+ assertEquals(expected.values(), value.values());
+ assertEquals(expected.schema(), value.schema());
+ assertEquals(expected.totalRows(), value.totalRows());
+ assertEquals(expected.totalBytesProcessed(), value.totalBytesProcessed());
+ assertEquals(expected.cacheHit(), value.cacheHit());
+ }
+}
diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java
index 67addce39d6d..3576769f4007 100644
--- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java
+++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java
@@ -186,6 +186,27 @@ public class SerializationTest {
private static final InsertAllResponse INSERT_ALL_RESPONSE = new InsertAllResponse(ERRORS_MAP);
private static final FieldValue FIELD_VALUE =
new FieldValue(FieldValue.Attribute.PRIMITIVE, "value");
+ private static final QueryRequest QUERY_REQUEST = QueryRequest.builder("query")
+ .useQueryCache(true)
+ .defaultDataset(DATASET_ID)
+ .dryRun(false)
+ .maxResults(42L)
+ .maxWaitTime(10L)
+ .build();
+ private static final QueryResult QUERY_RESULT = QueryResult.builder()
+ .schema(TABLE_SCHEMA)
+ .totalRows(1L)
+ .totalBytesProcessed(42L)
+ .cursor("cursor")
+ .pageFetcher(null)
+ .results(ImmutableList.>of())
+ .build();
+ private static final QueryResponse QUERY_RESPONSE = QueryResponse.builder()
+ .etag(ETAG)
+ .jobId(JOB_ID)
+ .jobComplete(true)
+ .result(QUERY_RESULT)
+ .build();
@Test
public void testServiceOptions() throws Exception {
@@ -212,7 +233,7 @@ public void testModelAndRequests() throws Exception {
TABLE_SCHEMA, TABLE_INFO, VIEW_INFO, EXTERNAL_TABLE_INFO, INLINE_FUNCTION, URI_FUNCTION,
JOB_STATISTICS, EXTRACT_STATISTICS, LOAD_STATISTICS, QUERY_STATISTICS, BIGQUERY_ERROR,
JOB_STATUS, JOB_ID, COPY_JOB, EXTRACT_JOB, LOAD_JOB, QUERY_JOB, INSERT_ALL_REQUEST,
- INSERT_ALL_RESPONSE, FIELD_VALUE};
+ INSERT_ALL_RESPONSE, FIELD_VALUE, QUERY_REQUEST, QUERY_RESPONSE};
for (Serializable obj : objects) {
Object copy = serializeAndDeserialize(obj);
assertEquals(obj, obj);