Skip to content

Commit

Permalink
Add QueryResult class and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Dec 14, 2015
1 parent 9756dff commit ea54699
Show file tree
Hide file tree
Showing 5 changed files with 318 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package com.google.gcloud.bigquery;

import com.google.common.base.MoreObjects;
import com.google.gcloud.Page;

import java.io.Serializable;
import java.util.List;
Expand All @@ -35,7 +34,12 @@
* Thread.sleep(1000);
* }
* List<BigQueryError> executionErrors = response.executionErrors();
* Page<List<FieldValue>> rows = response.rows();
* QueryResult result = response.result();
* Iterator<List<FieldValue>> rowIterator = result.iterateAll();
* while(rowIterator.hasNext()) {
* List<FieldValue> row = rowIterator.next();
* // do something with row
* }
* }</pre>
*
* @see <a href="https://cloud.google.com/bigquery/docs/reference/v2/jobs/getQueryResults">Get Query
Expand All @@ -46,37 +50,29 @@ public class QueryResponse implements Serializable {

private static final long serialVersionUID = 3549226764825005655L;

private final QueryResult result;
private final String etag;
private final Schema schema;
private final JobId job;
private final Long totalRows;
private final Page<List<FieldValue>> rows;
private final Long totalBytesProcessed;
private final boolean jobComplete;
private final List<BigQueryError> executionErrors;
private final Boolean cacheHit;

static final class Builder {

private QueryResult result;
private String etag;
private Schema schema;
private JobId job;
private Long totalRows;
private Page<List<FieldValue>> rows;
private Long totalBytesProcessed;
private boolean jobComplete;
private List<BigQueryError> executionErrors;
private Boolean cacheHit;

private Builder() {}

Builder etag(String etag) {
this.etag = etag;
Builder result(QueryResult result) {
this.result = result;
return this;
}

Builder schema(Schema schema) {
this.schema = schema;
Builder etag(String etag) {
this.etag = etag;
return this;
}

Expand All @@ -85,21 +81,6 @@ Builder job(JobId job) {
return this;
}

Builder totalRows(Long totalRows) {
this.totalRows = totalRows;
return this;
}

Builder rows(Page<List<FieldValue>> rows) {
this.rows = rows;
return this;
}

Builder totalBytesProcessed(Long totalBytesProcessed) {
this.totalBytesProcessed = totalBytesProcessed;
return this;
}

Builder jobComplete(boolean jobComplete) {
this.jobComplete = jobComplete;
return this;
Expand All @@ -110,41 +91,32 @@ Builder executionErrors(List<BigQueryError> executionErrors) {
return this;
}

Builder cacheHit(Boolean cacheHit) {
this.cacheHit = cacheHit;
return this;
}

QueryResponse build() {
return new QueryResponse(this);
}
}

private QueryResponse(Builder builder) {
this.result = builder.result;
this.etag = builder.etag;
this.schema = builder.schema;
this.job = builder.job;
this.totalRows = builder.totalRows;
this.rows = builder.rows;
this.totalBytesProcessed = builder.totalBytesProcessed;
this.jobComplete = builder.jobComplete;
this.executionErrors = builder.executionErrors;
this.cacheHit = builder.cacheHit;
}

/**
* Returns the hash of the {@code QueryResponse} resource or {@code null} if not set.
* Returns the result of the query. Returns {@code null} if {@link #jobComplete()} is {@code
* false}.
*/
public String etag() {
return etag;
public QueryResult result() {
return result;
}

/**
* Returns the schema of the results if the query completed successfully. Returns {@code null}
* otherwise.
* Returns the hash of the {@code QueryResponse} resource or {@code null} if not set.
*/
public Schema schema() {
return schema;
public String etag() {
return etag;
}

/**
Expand All @@ -156,36 +128,10 @@ public JobId job() {
}

/**
* 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 #rows()}. Returns {@code null}
* if the query did not complete successfully.
*/
public Long totalRows() {
return totalRows;
}

/**
* Returns the query result as a paginated list of rows, if the query completed successfully.
* Returns {@code null} otherwise.
*/
public Page<List<FieldValue>> rows() {
return rows;
}

/**
* 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. Returns {@code null}
* if the query did not complete.
*/
public Long totalBytesProcessed() {
return totalBytesProcessed;
}

/**
* Returns whether the job running the query has completed or not. If {@link #rows()} and
* {@link #totalRows()} are not {@code null}, this method will always return {@code true}. If this
* method returns {@code false} {@link #totalRows()} and {@link #rows()} return {@code null}. This
* method can be used to check if query execution completed and results are available.
* 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;
Expand All @@ -199,25 +145,14 @@ public List<BigQueryError> executionErrors() {
return executionErrors;
}

/**
* Returns whether the query result was fetched from the query cache.
*
* @see <a href="https://cloud.google.com/bigquery/querying-data#querycaching">Query Caching</a>
*/
public Boolean cacheHit() {
return cacheHit;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("result", result)
.add("etag", etag)
.add("job", job)
.add("jobComplete", jobComplete)
.add("totalRows", totalRows)
.add("schema", schema)
.add("totalBytesProcessed", totalBytesProcessed)
.add("executionErrors", executionErrors)
.add("cacheHit", cacheHit)
.toString();
}

Expand All @@ -236,13 +171,10 @@ public boolean equals(Object obj) {
}
QueryResponse response = (QueryResponse) obj;
return jobComplete == response.jobComplete
&& Objects.equals(schema, response.schema)
&& Objects.equals(etag, response.etag)
&& Objects.equals(result, response.result)
&& Objects.equals(job, response.job)
&& Objects.equals(totalRows, response.totalRows)
&& Objects.equals(rows, response.rows)
&& Objects.equals(totalBytesProcessed, response.totalBytesProcessed)
&& Objects.equals(executionErrors, response.executionErrors)
&& Objects.equals(cacheHit, response.cacheHit);
&& Objects.equals(executionErrors, response.executionErrors);
}

static Builder builder() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* 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<List<FieldValue>> {

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<List<FieldValue>> {
@Override
QueryResult nextPage();
}

static final class Builder {

private NextPageFetcher<List<FieldValue>> pageFetcher;
private String cursor;
private Iterable<List<FieldValue>> 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(NextPageFetcher<List<FieldValue>> pageFetcher) {
this.pageFetcher = pageFetcher;
return this;
};

Builder cursor(String cursor) {
this.cursor = cursor;
return this;
};

Builder results(Iterable<List<FieldValue>> 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.<List<FieldValue>>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 <a href="https://cloud.google.com/bigquery/querying-data#querycaching">Query Caching</a>
*/
public boolean cacheHit() {
return cacheHit;
}

/**
* Returns the schema of the results.
*/
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 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)
&& Objects.equals(totalRows, response.totalRows)
&& Objects.equals(totalBytesProcessed, response.totalBytesProcessed)
&& Objects.equals(cacheHit, response.cacheHit);
}

static Builder builder() {
return new Builder();
}
}
Loading

0 comments on commit ea54699

Please sign in to comment.