Skip to content

Commit e0a6fec

Browse files
committed
Remove JobInfo hierarchy, add JobConfiguration hierarchy
1 parent e11a5ae commit e0a6fec

30 files changed

Lines changed: 1738 additions & 1518 deletions

gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,9 @@ public static JobListOption startPageToken(String pageToken) {
371371
* is not provided all job's fields are returned. {@code JobOption.fields()} can be used to
372372
* specify only the fields of interest. {@link JobInfo#jobId()}, {@link JobStatus#state()},
373373
* {@link JobStatus#error()} as well as type-specific configuration (e.g.
374-
* {@link QueryJobInfo#query()} for Query Jobs) are always returned, even if not specified.
375-
* {@link JobField#SELF_LINK} and {@link JobField#ETAG} can not be selected when listing jobs.
374+
* {@link QueryJobConfiguration#query()} for Query Jobs) are always returned, even if not
375+
* specified. {@link JobField#SELF_LINK} and {@link JobField#ETAG} can not be selected when
376+
* listing jobs.
376377
*/
377378
public static JobListOption fields(JobField... fields) {
378379
String selector = JobField.selector(fields);
@@ -397,8 +398,8 @@ private JobOption(BigQueryRpc.Option option, Object value) {
397398
* Returns an option to specify the job's fields to be returned by the RPC call. If this option
398399
* is not provided all job's fields are returned. {@code JobOption.fields()} can be used to
399400
* specify only the fields of interest. {@link JobInfo#jobId()} as well as type-specific
400-
* configuration (e.g. {@link QueryJobInfo#query()} for Query Jobs) are always returned, even if
401-
* not specified.
401+
* configuration (e.g. {@link QueryJobConfiguration#query()} for Query Jobs) are always
402+
* returned, even if not specified.
402403
*/
403404
public static JobOption fields(JobField... fields) {
404405
return new JobOption(BigQueryRpc.Option.FIELDS, JobField.selector(fields));
@@ -470,7 +471,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) {
470471
*
471472
* @throws BigQueryException upon failure
472473
*/
473-
<T extends JobInfo> T create(T job, JobOption... options) throws BigQueryException;
474+
JobInfo create(JobInfo job, JobOption... options) throws BigQueryException;
474475

475476
/**
476477
* Returns the requested dataset or {@code null} if not found.
@@ -611,14 +612,14 @@ Page<List<FieldValue>> listTableData(TableId tableId, TableDataListOption... opt
611612
*
612613
* @throws BigQueryException upon failure
613614
*/
614-
<T extends JobInfo> T getJob(String jobId, JobOption... options) throws BigQueryException;
615+
JobInfo getJob(String jobId, JobOption... options) throws BigQueryException;
615616

616617
/**
617618
* Returns the requested job or {@code null} if not found.
618619
*
619620
* @throws BigQueryException upon failure
620621
*/
621-
<T extends JobInfo> T getJob(JobId jobId, JobOption... options) throws BigQueryException;
622+
JobInfo getJob(JobId jobId, JobOption... options) throws BigQueryException;
622623

623624
/**
624625
* Lists the jobs.

gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public Table call() {
191191
}
192192

193193
@Override
194-
public <T extends JobInfo> T create(T job, JobOption... options) throws BigQueryException {
194+
public JobInfo create(JobInfo job, JobOption... options) throws BigQueryException {
195195
final Job jobPb = setProjectId(job).toPb();
196196
final Map<BigQueryRpc.Option, ?> optionsMap = optionMap(options);
197197
try {
@@ -442,12 +442,12 @@ public List<FieldValue> apply(TableRow rowPb) {
442442
}
443443

444444
@Override
445-
public <T extends JobInfo> T getJob(String jobId, JobOption... options) throws BigQueryException {
445+
public JobInfo getJob(String jobId, JobOption... options) throws BigQueryException {
446446
return getJob(JobId.of(jobId), options);
447447
}
448448

449449
@Override
450-
public <T extends JobInfo> T getJob(final JobId jobId, JobOption... options)
450+
public JobInfo getJob(final JobId jobId, JobOption... options)
451451
throws BigQueryException {
452452
final Map<BigQueryRpc.Option, ?> optionsMap = optionMap(options);
453453
try {
@@ -457,7 +457,7 @@ public Job call() {
457457
return bigQueryRpc.getJob(jobId.job(), optionsMap);
458458
}
459459
}, options().retryParams(), EXCEPTION_HANDLER);
460-
return answer == null ? null : JobInfo.<T>fromPb(answer);
460+
return answer == null ? null : JobInfo.fromPb(answer);
461461
} catch (RetryHelper.RetryHelperException e) {
462462
throw BigQueryException.translateAndThrow(e);
463463
}
@@ -646,42 +646,48 @@ private TableId setProjectId(TableId table) {
646646
}
647647

648648
private JobInfo setProjectId(JobInfo job) {
649-
if (job instanceof CopyJobInfo) {
650-
CopyJobInfo copyJob = (CopyJobInfo) job;
651-
CopyJobInfo.Builder copyBuilder = copyJob.toBuilder();
652-
copyBuilder.destinationTable(setProjectId(copyJob.destinationTable()));
653-
copyBuilder.sourceTables(
654-
Lists.transform(copyJob.sourceTables(), new Function<TableId, TableId>() {
655-
@Override
656-
public TableId apply(TableId tableId) {
657-
return setProjectId(tableId);
658-
}
659-
}));
660-
return copyBuilder.build();
661-
}
662-
if (job instanceof QueryJobInfo) {
663-
QueryJobInfo queryJob = (QueryJobInfo) job;
664-
QueryJobInfo.Builder queryBuilder = queryJob.toBuilder();
665-
if (queryJob.destinationTable() != null) {
666-
queryBuilder.destinationTable(setProjectId(queryJob.destinationTable()));
667-
}
668-
if (queryJob.defaultDataset() != null) {
669-
queryBuilder.defaultDataset(setProjectId(queryJob.defaultDataset()));
670-
}
671-
return queryBuilder.build();
672-
}
673-
if (job instanceof ExtractJobInfo) {
674-
ExtractJobInfo extractJob = (ExtractJobInfo) job;
675-
ExtractJobInfo.Builder extractBuilder = extractJob.toBuilder();
676-
extractBuilder.sourceTable(setProjectId(extractJob.sourceTable()));
677-
return extractBuilder.build();
678-
}
679-
if (job instanceof LoadJobInfo) {
680-
LoadJobInfo loadJob = (LoadJobInfo) job;
681-
LoadJobInfo.Builder loadBuilder = loadJob.toBuilder();
682-
return loadBuilder.configuration(setProjectId(loadJob.configuration())).build();
683-
}
684-
return job;
649+
JobConfiguration configuration = job.configuration();
650+
JobInfo.Builder jobBuilder = job.toBuilder();
651+
switch (configuration.type()) {
652+
case COPY:
653+
CopyJobConfiguration copyConfiguration = (CopyJobConfiguration) configuration;
654+
CopyJobConfiguration.Builder copyBuilder = copyConfiguration.toBuilder();
655+
copyBuilder.sourceTables(
656+
Lists.transform(copyConfiguration.sourceTables(), new Function<TableId, TableId>() {
657+
@Override
658+
public TableId apply(TableId tableId) {
659+
return setProjectId(tableId);
660+
}
661+
}));
662+
copyBuilder.destinationTable(setProjectId(copyConfiguration.destinationTable()));
663+
jobBuilder.configuration(copyBuilder.build());
664+
break;
665+
case QUERY:
666+
QueryJobConfiguration queryConfiguration = (QueryJobConfiguration) configuration;
667+
QueryJobConfiguration.Builder queryBuilder = queryConfiguration.toBuilder();
668+
if (queryConfiguration.destinationTable() != null) {
669+
queryBuilder.destinationTable(setProjectId(queryConfiguration.destinationTable()));
670+
}
671+
if (queryConfiguration.defaultDataset() != null) {
672+
queryBuilder.defaultDataset(setProjectId(queryConfiguration.defaultDataset()));
673+
}
674+
jobBuilder.configuration(queryBuilder.build());
675+
break;
676+
case EXTRACT:
677+
ExtractJobConfiguration extractConfiguration = (ExtractJobConfiguration) configuration;
678+
ExtractJobConfiguration.Builder extractBuilder = extractConfiguration.toBuilder();
679+
extractBuilder.sourceTable(setProjectId(extractConfiguration.sourceTable()));
680+
jobBuilder.configuration(extractBuilder.build());
681+
break;
682+
case LOAD:
683+
LoadJobConfiguration loadConfiguration = (LoadJobConfiguration) configuration;
684+
jobBuilder.configuration((LoadJobConfiguration) setProjectId(loadConfiguration));
685+
break;
686+
default:
687+
// never reached
688+
throw new IllegalArgumentException("Job configuration is not supported");
689+
}
690+
return jobBuilder.build();
685691
}
686692

687693
private QueryRequest setProjectId(QueryRequest request) {
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
package com.google.gcloud.bigquery;
2+
3+
import static com.google.common.base.Preconditions.checkNotNull;
4+
5+
import com.google.api.services.bigquery.model.JobConfigurationTableCopy;
6+
import com.google.common.base.MoreObjects;
7+
import com.google.common.collect.ImmutableList;
8+
import com.google.common.collect.Lists;
9+
10+
import java.io.Serializable;
11+
import java.util.List;
12+
import java.util.Objects;
13+
14+
/**
15+
* Google BigQuery Copy Job configuration. A Copy Job copies an existing table to another new or
16+
* existing table.
17+
*/
18+
public final class CopyJobConfiguration implements JobConfiguration, Serializable {
19+
20+
private static final long serialVersionUID = 1140509641399762967L;
21+
22+
private final List<TableId> sourceTables;
23+
private final TableId destinationTable;
24+
private final JobInfo.CreateDisposition createDisposition;
25+
private final JobInfo.WriteDisposition writeDisposition;
26+
27+
public static final class Builder {
28+
29+
private List<TableId> sourceTables;
30+
private TableId destinationTable;
31+
private JobInfo.CreateDisposition createDisposition;
32+
private JobInfo.WriteDisposition writeDisposition;
33+
34+
private Builder() {}
35+
36+
private Builder(CopyJobConfiguration jobConfiguration) {
37+
this.sourceTables = jobConfiguration.sourceTables;
38+
this.destinationTable = jobConfiguration.destinationTable;
39+
this.createDisposition = jobConfiguration.createDisposition;
40+
this.writeDisposition = jobConfiguration.writeDisposition;
41+
}
42+
43+
private Builder(com.google.api.services.bigquery.model.JobConfiguration configurationPb) {
44+
JobConfigurationTableCopy copyConfigurationPb = configurationPb.getCopy();
45+
this.destinationTable = TableId.fromPb(copyConfigurationPb.getDestinationTable());
46+
if (copyConfigurationPb.getSourceTables() != null) {
47+
this.sourceTables =
48+
Lists.transform(copyConfigurationPb.getSourceTables(), TableId.FROM_PB_FUNCTION);
49+
} else {
50+
this.sourceTables = ImmutableList.of(TableId.fromPb(copyConfigurationPb.getSourceTable()));
51+
}
52+
if (copyConfigurationPb.getCreateDisposition() != null) {
53+
this.createDisposition =
54+
JobInfo.CreateDisposition.valueOf(copyConfigurationPb.getCreateDisposition());
55+
}
56+
if (copyConfigurationPb.getWriteDisposition() != null) {
57+
this.writeDisposition = JobInfo.WriteDisposition.valueOf(
58+
copyConfigurationPb.getWriteDisposition());
59+
}
60+
}
61+
62+
/**
63+
* Sets the source tables to copy.
64+
*/
65+
public Builder sourceTables(List<TableId> sourceTables) {
66+
this.sourceTables = sourceTables != null ? ImmutableList.copyOf(sourceTables) : null;
67+
return this;
68+
}
69+
70+
/**
71+
* Sets the destination table of the copy job.
72+
*/
73+
public Builder destinationTable(TableId destinationTable) {
74+
this.destinationTable = destinationTable;
75+
return this;
76+
}
77+
78+
/**
79+
* Sets whether the job is allowed to create new tables.
80+
*
81+
* @see <a href="https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.copy.createDisposition">
82+
* Create Disposition</a>
83+
*/
84+
public Builder createDisposition(JobInfo.CreateDisposition createDisposition) {
85+
this.createDisposition = createDisposition;
86+
return this;
87+
}
88+
89+
/**
90+
* Sets the action that should occur if the destination table already exists.
91+
*
92+
* @see <a href="https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.copy.writeDisposition">
93+
* Write Disposition</a>
94+
*/
95+
public Builder writeDisposition(JobInfo.WriteDisposition writeDisposition) {
96+
this.writeDisposition = writeDisposition;
97+
return this;
98+
}
99+
100+
public CopyJobConfiguration build() {
101+
return new CopyJobConfiguration(this);
102+
}
103+
}
104+
105+
private CopyJobConfiguration(Builder builder) {
106+
this.sourceTables = checkNotNull(builder.sourceTables);
107+
this.destinationTable = checkNotNull(builder.destinationTable);
108+
this.createDisposition = builder.createDisposition;
109+
this.writeDisposition = builder.writeDisposition;
110+
}
111+
112+
@Override
113+
public Type type() {
114+
return Type.COPY;
115+
}
116+
117+
/**
118+
* Returns the source tables to copy.
119+
*/
120+
public List<TableId> sourceTables() {
121+
return sourceTables;
122+
}
123+
124+
/**
125+
* Returns the destination table to load the data into.
126+
*/
127+
public TableId destinationTable() {
128+
return destinationTable;
129+
}
130+
131+
/**
132+
* Returns whether the job is allowed to create new tables.
133+
*
134+
* @see <a href="https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.copy.createDisposition">
135+
* Create Disposition</a>
136+
*/
137+
public JobInfo.CreateDisposition createDisposition() {
138+
return this.createDisposition;
139+
}
140+
141+
/**
142+
* Returns the action that should occur if the destination table already exists.
143+
*
144+
* @see <a href="https://cloud.google.com/bigquery/docs/reference/v2/jobs#configuration.copy.writeDisposition">
145+
* Write Disposition</a>
146+
*/
147+
public JobInfo.WriteDisposition writeDisposition() {
148+
return writeDisposition;
149+
}
150+
151+
public Builder toBuilder() {
152+
return new Builder(this);
153+
}
154+
155+
@Override
156+
public String toString() {
157+
return MoreObjects.toStringHelper(this)
158+
.add("sourceTables", sourceTables)
159+
.add("destinationTable", destinationTable)
160+
.add("createDisposition", createDisposition)
161+
.add("writeDisposition", writeDisposition)
162+
.toString();
163+
}
164+
165+
@Override
166+
public boolean equals(Object obj) {
167+
return obj instanceof CopyJobConfiguration
168+
&& Objects.equals(toPb(), ((CopyJobConfiguration) obj).toPb());
169+
}
170+
171+
@Override
172+
public int hashCode() {
173+
return Objects.hash(sourceTables, destinationTable, createDisposition, writeDisposition);
174+
}
175+
176+
com.google.api.services.bigquery.model.JobConfiguration toPb() {
177+
JobConfigurationTableCopy configurationPb = new JobConfigurationTableCopy();
178+
configurationPb.setDestinationTable(destinationTable.toPb());
179+
if (sourceTables.size() == 1) {
180+
configurationPb.setSourceTable(sourceTables.get(0).toPb());
181+
} else {
182+
configurationPb.setSourceTables(Lists.transform(sourceTables, TableId.TO_PB_FUNCTION));
183+
}
184+
if (createDisposition != null) {
185+
configurationPb.setCreateDisposition(createDisposition.toString());
186+
}
187+
if (writeDisposition != null) {
188+
configurationPb.setWriteDisposition(writeDisposition.toString());
189+
}
190+
return new com.google.api.services.bigquery.model.JobConfiguration().setCopy(configurationPb);
191+
}
192+
193+
/**
194+
* Creates a builder for a BigQuery Copy Job configuration given destination and source table.
195+
*/
196+
public static Builder builder(TableId destinationTable, TableId sourceTable) {
197+
return builder(destinationTable, ImmutableList.of(checkNotNull(sourceTable)));
198+
}
199+
200+
/**
201+
* Creates a builder for a BigQuery Copy Job configuration given destination and source tables.
202+
*/
203+
public static Builder builder(TableId destinationTable, List<TableId> sourceTables) {
204+
return new Builder().destinationTable(destinationTable).sourceTables(sourceTables);
205+
}
206+
207+
/**
208+
* Returns a BigQuery Copy Job configuration for the given destination and source table.
209+
*/
210+
public static CopyJobConfiguration of(TableId destinationTable, TableId sourceTable) {
211+
return builder(destinationTable, sourceTable).build();
212+
}
213+
214+
/**
215+
* Returns a BigQuery Copy Job configuration for the given destination and source tables.
216+
*/
217+
public static CopyJobConfiguration of(TableId destinationTable, List<TableId> sourceTables) {
218+
return builder(destinationTable, sourceTables).build();
219+
}
220+
221+
static CopyJobConfiguration fromPb(
222+
com.google.api.services.bigquery.model.JobConfiguration jobPb) {
223+
return new Builder(jobPb).build();
224+
}
225+
}

0 commit comments

Comments
 (0)