Skip to content

Commit d8b1814

Browse files
committed
Merge pull request #516 from mziccard/bigquery-functional-classes
Add functional classes for BigQuery datasets jobs and tables
2 parents 64114c1 + d58930e commit d8b1814

File tree

10 files changed

+1666
-27
lines changed

10 files changed

+1666
-27
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
/*
2+
* Copyright 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.gcloud.bigquery;
18+
19+
import static com.google.common.base.Preconditions.checkArgument;
20+
import static com.google.common.base.Preconditions.checkNotNull;
21+
22+
import com.google.common.base.Function;
23+
import com.google.common.collect.Iterators;
24+
import com.google.gcloud.Page;
25+
import com.google.gcloud.PageImpl;
26+
27+
import java.io.IOException;
28+
import java.io.ObjectInputStream;
29+
import java.io.Serializable;
30+
import java.util.Iterator;
31+
import java.util.List;
32+
import java.util.Objects;
33+
34+
/**
35+
* A Google BigQuery Dataset.
36+
*
37+
* <p>Objects of this class are immutable. Operations that modify the dataset like {@link #update}
38+
* return a new object. To get a {@code Dataset} object with the most recent information use
39+
* {@link #reload}.
40+
* </p>
41+
*/
42+
public final class Dataset {
43+
44+
private final BigQuery bigquery;
45+
private final DatasetInfo info;
46+
47+
private static class TablePageFetcher implements PageImpl.NextPageFetcher<Table> {
48+
49+
private static final long serialVersionUID = 6906197848579250598L;
50+
51+
private final BigQueryOptions options;
52+
private final Page<BaseTableInfo> infoPage;
53+
54+
TablePageFetcher(BigQueryOptions options, Page<BaseTableInfo> infoPage) {
55+
this.options = options;
56+
this.infoPage = infoPage;
57+
}
58+
59+
@Override
60+
public Page<Table> nextPage() {
61+
Page<BaseTableInfo> nextInfoPage = infoPage.nextPage();
62+
return new PageImpl<>(new TablePageFetcher(options, nextInfoPage),
63+
nextInfoPage.nextPageCursor(), new LazyTableIterable(options, nextInfoPage.values()));
64+
}
65+
}
66+
67+
private static class LazyTableIterable implements Iterable<Table>, Serializable {
68+
69+
private static final long serialVersionUID = 3312744215731674032L;
70+
71+
private final BigQueryOptions options;
72+
private Iterable<BaseTableInfo> infoIterable;
73+
private transient BigQuery bigquery;
74+
75+
public LazyTableIterable(BigQueryOptions options, Iterable<BaseTableInfo> infoIterable) {
76+
this.options = options;
77+
this.infoIterable = infoIterable;
78+
this.bigquery = options.service();
79+
}
80+
81+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
82+
in.defaultReadObject();
83+
this.bigquery = options.service();
84+
}
85+
86+
@Override
87+
public Iterator<Table> iterator() {
88+
return Iterators.transform(infoIterable.iterator(), new Function<BaseTableInfo, Table>() {
89+
@Override
90+
public Table apply(BaseTableInfo tableInfo) {
91+
return new Table(bigquery, tableInfo);
92+
}
93+
});
94+
}
95+
96+
@Override
97+
public int hashCode() {
98+
return Objects.hash(options, infoIterable);
99+
}
100+
101+
@Override
102+
public boolean equals(Object obj) {
103+
if (!(obj instanceof LazyTableIterable)) {
104+
return false;
105+
}
106+
LazyTableIterable other = (LazyTableIterable) obj;
107+
return Objects.equals(options, other.options)
108+
&& Objects.equals(infoIterable, other.infoIterable);
109+
}
110+
}
111+
112+
/**
113+
* Constructs a {@code Dataset} object for the provided {@code DatasetInfo}. The BigQuery service
114+
* is used to issue requests.
115+
*
116+
* @param bigquery the BigQuery service used for issuing requests
117+
* @param info dataset's info
118+
*/
119+
public Dataset(BigQuery bigquery, DatasetInfo info) {
120+
this.bigquery = checkNotNull(bigquery);
121+
this.info = checkNotNull(info);
122+
}
123+
124+
/**
125+
* Creates a {@code Dataset} object for the provided dataset's user-defined id. Performs an RPC
126+
* call to get the latest dataset information.
127+
*
128+
* @param bigquery the BigQuery service used for issuing requests
129+
* @param dataset dataset's user-defined id
130+
* @param options dataset options
131+
* @return the {@code Dataset} object or {@code null} if not found
132+
* @throws BigQueryException upon failure
133+
*/
134+
public static Dataset load(BigQuery bigquery, String dataset, BigQuery.DatasetOption... options) {
135+
DatasetInfo info = bigquery.getDataset(dataset, options);
136+
return info != null ? new Dataset(bigquery, info) : null;
137+
}
138+
139+
/**
140+
* Returns the dataset's information.
141+
*/
142+
public DatasetInfo info() {
143+
return info;
144+
}
145+
146+
/**
147+
* Checks if this dataset exists.
148+
*
149+
* @return {@code true} if this dataset exists, {@code false} otherwise
150+
* @throws BigQueryException upon failure
151+
*/
152+
public boolean exists() {
153+
return bigquery.getDataset(info.datasetId(), BigQuery.DatasetOption.fields()) != null;
154+
}
155+
156+
/**
157+
* Fetches current dataset's latest information. Returns {@code null} if the dataset does not
158+
* exist.
159+
*
160+
* @param options dataset options
161+
* @return a {@code Dataset} object with latest information or {@code null} if not found
162+
* @throws BigQueryException upon failure
163+
*/
164+
public Dataset reload(BigQuery.DatasetOption... options) {
165+
return Dataset.load(bigquery, info.datasetId().dataset(), options);
166+
}
167+
168+
/**
169+
* Updates the dataset's information. Dataset's user-defined id cannot be changed. A new
170+
* {@code Dataset} object is returned.
171+
*
172+
* @param datasetInfo new dataset's information. User-defined id must match the one of the current
173+
* dataset
174+
* @param options dataset options
175+
* @return a {@code Dataset} object with updated information
176+
* @throws BigQueryException upon failure
177+
*/
178+
public Dataset update(DatasetInfo datasetInfo, BigQuery.DatasetOption... options) {
179+
checkArgument(Objects.equals(datasetInfo.datasetId().dataset(),
180+
info.datasetId().dataset()), "Dataset's user-defined ids must match");
181+
return new Dataset(bigquery, bigquery.update(datasetInfo, options));
182+
}
183+
184+
/**
185+
* Deletes this dataset.
186+
*
187+
* @return {@code true} if dataset was deleted, {@code false} if it was not found.
188+
* @throws BigQueryException upon failure
189+
*/
190+
public boolean delete() {
191+
return bigquery.delete(info.datasetId());
192+
}
193+
194+
/**
195+
* Returns the paginated list of tables in this dataset.
196+
*
197+
* @param options options for listing tables
198+
* @throws BigQueryException upon failure
199+
*/
200+
public Page<Table> list(BigQuery.TableListOption... options) {
201+
Page<BaseTableInfo> infoPage = bigquery.listTables(info.datasetId(), options);
202+
BigQueryOptions bigqueryOptions = bigquery.options();
203+
return new PageImpl<>(new TablePageFetcher(bigqueryOptions, infoPage),
204+
infoPage.nextPageCursor(), new LazyTableIterable(bigqueryOptions, infoPage.values()));
205+
}
206+
207+
/**
208+
* Returns the requested table in this dataset or {@code null} if not found.
209+
*
210+
* @param table user-defined id of the requested table
211+
* @param options table options
212+
* @throws BigQueryException upon failure
213+
*/
214+
public Table get(String table, BigQuery.TableOption... options) {
215+
BaseTableInfo tableInfo =
216+
bigquery.getTable(TableId.of(info.datasetId().dataset(), table), options);
217+
return tableInfo != null ? new Table(bigquery, tableInfo) : null;
218+
}
219+
220+
/**
221+
* Creates a new simple table in this dataset.
222+
*
223+
* @param table the table's user-defined id
224+
* @param schema the table's schema
225+
* @param options options for table creation
226+
* @return a {@code Table} object for the created table
227+
* @throws BigQueryException upon failure
228+
*/
229+
public Table create(String table, Schema schema, BigQuery.TableOption... options) {
230+
BaseTableInfo tableInfo = TableInfo.of(TableId.of(info.datasetId().dataset(), table), schema);
231+
return new Table(bigquery, bigquery.create(tableInfo, options));
232+
}
233+
234+
/**
235+
* Creates a new view table in this dataset.
236+
*
237+
* @param table the table's user-defined id
238+
* @param query the query used to generate the table
239+
* @param functions user-defined functions that can be used by the query
240+
* @param options options for table creation
241+
* @return a {@code Table} object for the created table
242+
* @throws BigQueryException upon failure
243+
*/
244+
public Table create(String table, String query, List<UserDefinedFunction> functions,
245+
BigQuery.TableOption... options) {
246+
BaseTableInfo tableInfo =
247+
ViewInfo.of(TableId.of(info.datasetId().dataset(), table), query, functions);
248+
return new Table(bigquery, bigquery.create(tableInfo, options));
249+
}
250+
251+
/**
252+
* Creates a new view table in this dataset.
253+
*
254+
* @param table the table's user-defined id
255+
* @param query the query used to generate the table
256+
* @param options options for table creation
257+
* @return a {@code Table} object for the created table
258+
* @throws BigQueryException upon failure
259+
*/
260+
public Table create(String table, String query, BigQuery.TableOption... options) {
261+
BaseTableInfo tableInfo = ViewInfo.of(TableId.of(info.datasetId().dataset(), table), query);
262+
return new Table(bigquery, bigquery.create(tableInfo, options));
263+
}
264+
265+
/**
266+
* Creates a new external table in this dataset.
267+
*
268+
* @param table the table's user-defined id
269+
* @param configuration data format, location and other properties of an external table
270+
* @param options options for table creation
271+
* @return a {@code Table} object for the created table
272+
* @throws BigQueryException upon failure
273+
*/
274+
public Table create(String table, ExternalDataConfiguration configuration,
275+
BigQuery.TableOption... options) {
276+
BaseTableInfo tableInfo =
277+
ExternalTableInfo.of(TableId.of(info.datasetId().dataset(), table), configuration);
278+
return new Table(bigquery, bigquery.create(tableInfo, options));
279+
}
280+
281+
/**
282+
* Returns the dataset's {@code BigQuery} object used to issue requests.
283+
*/
284+
public BigQuery bigquery() {
285+
return bigquery;
286+
}
287+
}

0 commit comments

Comments
 (0)