Skip to content

Commit dcd3663

Browse files
author
Praful Makani
authored
feat: add support connection properties for job and query (#320)
1 parent 3dade31 commit dcd3663

File tree

5 files changed

+283
-2
lines changed

5 files changed

+283
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2020 Google LLC
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.cloud.bigquery;
18+
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
21+
import com.google.common.base.Function;
22+
import com.google.common.base.MoreObjects;
23+
import com.google.common.base.Objects;
24+
25+
public final class ConnectionProperty {
26+
27+
static final Function<
28+
com.google.api.services.bigquery.model.ConnectionProperty, ConnectionProperty>
29+
FROM_PB_FUNCTION =
30+
new Function<
31+
com.google.api.services.bigquery.model.ConnectionProperty, ConnectionProperty>() {
32+
@Override
33+
public ConnectionProperty apply(
34+
com.google.api.services.bigquery.model.ConnectionProperty connectionProperty) {
35+
return ConnectionProperty.fromPb(connectionProperty);
36+
}
37+
};
38+
static final Function<
39+
ConnectionProperty, com.google.api.services.bigquery.model.ConnectionProperty>
40+
TO_PB_FUNCTION =
41+
new Function<
42+
ConnectionProperty, com.google.api.services.bigquery.model.ConnectionProperty>() {
43+
@Override
44+
public com.google.api.services.bigquery.model.ConnectionProperty apply(
45+
ConnectionProperty connectionProperty) {
46+
return connectionProperty.toPb();
47+
}
48+
};
49+
50+
private final String key;
51+
private final String value;
52+
53+
/** A builder for {@code ConnectionProperty} objects. */
54+
public static final class Builder {
55+
private String key;
56+
private String value;
57+
58+
private Builder() {};
59+
60+
private Builder(ConnectionProperty properties) {
61+
this.key = properties.key;
62+
this.value = properties.value;
63+
}
64+
65+
/** [Required] Name of the connection property to set. */
66+
public Builder setKey(String key) {
67+
this.key = key;
68+
return this;
69+
}
70+
71+
/** [Required] Value of the connection property. */
72+
public Builder setValue(String value) {
73+
this.value = value;
74+
return this;
75+
}
76+
77+
/** Creates a {@code ConnectionProperty} object. */
78+
public ConnectionProperty build() {
79+
return new ConnectionProperty(this);
80+
}
81+
}
82+
83+
private ConnectionProperty(Builder builder) {
84+
this.key = checkNotNull(builder.key, "Required key is null or empty");
85+
this.value = checkNotNull(builder.value, "Required value is null or empty");
86+
}
87+
88+
/** Return the key of property. */
89+
public String getKey() {
90+
return key;
91+
}
92+
93+
/** Return the value of property. */
94+
public String getValue() {
95+
return value;
96+
}
97+
98+
/** Return a connection property for the given key and value. */
99+
public static ConnectionProperty of(String key, String value) {
100+
return newBuilder().setKey(key).setValue(value).build();
101+
}
102+
103+
/** Returns a builder for the {@code ConnectionProperty} object. */
104+
public static Builder newBuilder() {
105+
return new Builder();
106+
}
107+
108+
/** Returns a builder for the {@code ConnectionProperty} object. */
109+
public Builder toBuilder() {
110+
return new Builder(this);
111+
}
112+
113+
@Override
114+
public String toString() {
115+
return MoreObjects.toStringHelper(this).add("key", key).add("value", value).toString();
116+
}
117+
118+
@Override
119+
public int hashCode() {
120+
return Objects.hashCode(key, value);
121+
}
122+
123+
@Override
124+
public boolean equals(Object obj) {
125+
return obj == this
126+
|| obj != null
127+
&& obj.getClass().equals(ConnectionProperty.class)
128+
&& java.util.Objects.equals(toPb(), ((ConnectionProperty) obj).toPb());
129+
}
130+
131+
com.google.api.services.bigquery.model.ConnectionProperty toPb() {
132+
com.google.api.services.bigquery.model.ConnectionProperty properties =
133+
new com.google.api.services.bigquery.model.ConnectionProperty();
134+
properties.setKey(key);
135+
properties.setValue(value);
136+
return properties;
137+
}
138+
139+
static ConnectionProperty fromPb(
140+
com.google.api.services.bigquery.model.ConnectionProperty properties) {
141+
Builder builder = newBuilder();
142+
builder.setKey(properties.getKey());
143+
builder.setValue(properties.getValue());
144+
return builder.build();
145+
}
146+
}

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java

+38-2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public final class QueryJobConfiguration extends JobConfiguration {
6868
private final Long jobTimeoutMs;
6969
private final Map<String, String> labels;
7070
private final RangePartitioning rangePartitioning;
71+
private final List<ConnectionProperty> connectionProperties;
7172

7273
/**
7374
* Priority levels for a query. If not specified the priority is assumed to be {@link
@@ -116,6 +117,7 @@ public static final class Builder
116117
private Long jobTimeoutMs;
117118
private Map<String, String> labels;
118119
private RangePartitioning rangePartitioning;
120+
private List<ConnectionProperty> connectionProperties;
119121

120122
private Builder() {
121123
super(Type.QUERY);
@@ -147,6 +149,7 @@ private Builder(QueryJobConfiguration jobConfiguration) {
147149
this.jobTimeoutMs = jobConfiguration.jobTimeoutMs;
148150
this.labels = jobConfiguration.labels;
149151
this.rangePartitioning = jobConfiguration.rangePartitioning;
152+
this.connectionProperties = jobConfiguration.connectionProperties;
150153
}
151154

152155
private Builder(com.google.api.services.bigquery.model.JobConfiguration configurationPb) {
@@ -240,6 +243,12 @@ private Builder(com.google.api.services.bigquery.model.JobConfiguration configur
240243
this.rangePartitioning =
241244
RangePartitioning.fromPb(queryConfigurationPb.getRangePartitioning());
242245
}
246+
if (queryConfigurationPb.getConnectionProperties() != null) {
247+
this.connectionProperties =
248+
Lists.transform(
249+
queryConfigurationPb.getConnectionProperties(),
250+
ConnectionProperty.FROM_PB_FUNCTION);
251+
}
243252
}
244253

245254
/** Sets the BigQuery SQL query to execute. */
@@ -579,6 +588,21 @@ public Builder setRangePartitioning(RangePartitioning rangePartitioning) {
579588
return this;
580589
}
581590

591+
/**
592+
* A connection-level property to customize query behavior. Under JDBC, these correspond
593+
* directly to connection properties passed to the DriverManager. Under ODBC, these correspond
594+
* to properties in the connection string. Currently, the only supported connection property is
595+
* "time_zone", whose value represents the default timezone used to run the query. Additional
596+
* properties are allowed, but ignored. Specifying multiple connection properties with the same
597+
* key is an error.
598+
*
599+
* @param connectionProperties connectionProperties or {@code null} for none
600+
*/
601+
public Builder setConnectionProperties(List<ConnectionProperty> connectionProperties) {
602+
this.connectionProperties = ImmutableList.copyOf(connectionProperties);
603+
return this;
604+
}
605+
582606
public QueryJobConfiguration build() {
583607
return new QueryJobConfiguration(this);
584608
}
@@ -619,6 +643,7 @@ private QueryJobConfiguration(Builder builder) {
619643
this.jobTimeoutMs = builder.jobTimeoutMs;
620644
this.labels = builder.labels;
621645
this.rangePartitioning = builder.rangePartitioning;
646+
this.connectionProperties = builder.connectionProperties;
622647
}
623648

624649
/**
@@ -803,6 +828,11 @@ public RangePartitioning getRangePartitioning() {
803828
return rangePartitioning;
804829
}
805830

831+
/** Returns the connection properties for connection string with this job */
832+
public List<ConnectionProperty> getConnectionProperties() {
833+
return connectionProperties;
834+
}
835+
806836
@Override
807837
public Builder toBuilder() {
808838
return new Builder(this);
@@ -834,7 +864,8 @@ ToStringHelper toStringHelper() {
834864
.add("clustering", clustering)
835865
.add("jobTimeoutMs", jobTimeoutMs)
836866
.add("labels", labels)
837-
.add("rangePartitioning", rangePartitioning);
867+
.add("rangePartitioning", rangePartitioning)
868+
.add("connectionProperties", connectionProperties);
838869
}
839870

840871
@Override
@@ -869,7 +900,8 @@ public int hashCode() {
869900
clustering,
870901
jobTimeoutMs,
871902
labels,
872-
rangePartitioning);
903+
rangePartitioning,
904+
connectionProperties);
873905
}
874906

875907
@Override
@@ -968,6 +1000,10 @@ com.google.api.services.bigquery.model.JobConfiguration toPb() {
9681000
if (rangePartitioning != null) {
9691001
queryConfigurationPb.setRangePartitioning(rangePartitioning.toPb());
9701002
}
1003+
if (connectionProperties != null) {
1004+
queryConfigurationPb.setConnectionProperties(
1005+
Lists.transform(connectionProperties, ConnectionProperty.TO_PB_FUNCTION));
1006+
}
9711007
configurationPb.setQuery(queryConfigurationPb);
9721008
return configurationPb;
9731009
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2020 Google LLC
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.cloud.bigquery;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import org.junit.Test;
22+
23+
public class ConnectionPropertyTest {
24+
25+
private static final String KEY = "time_zone";
26+
private static final String VALUE = "US/Eastern";
27+
private static final ConnectionProperty CONNECTION_PROPERTY =
28+
ConnectionProperty.newBuilder().setKey(KEY).setValue(VALUE).build();
29+
30+
@Test
31+
public void testToBuilder() {
32+
compareConnectionProperty(CONNECTION_PROPERTY, CONNECTION_PROPERTY.toBuilder().build());
33+
ConnectionProperty property = CONNECTION_PROPERTY.toBuilder().setKey("time-zone").build();
34+
assertThat(property.getKey()).isEqualTo("time-zone");
35+
property = CONNECTION_PROPERTY.toBuilder().setKey(KEY).build();
36+
compareConnectionProperty(CONNECTION_PROPERTY, property);
37+
}
38+
39+
@Test
40+
public void testToBuilderIncomplete() {
41+
ConnectionProperty connectionProperty = ConnectionProperty.of(KEY, VALUE);
42+
compareConnectionProperty(connectionProperty, connectionProperty.toBuilder().build());
43+
}
44+
45+
@Test
46+
public void testBuilder() {
47+
assertThat(CONNECTION_PROPERTY.getKey()).isEqualTo(KEY);
48+
assertThat(CONNECTION_PROPERTY.getValue()).isEqualTo(VALUE);
49+
}
50+
51+
@Test
52+
public void testToAndFromPb() {
53+
compareConnectionProperty(
54+
CONNECTION_PROPERTY, ConnectionProperty.fromPb(CONNECTION_PROPERTY.toPb()));
55+
}
56+
57+
private void compareConnectionProperty(ConnectionProperty expected, ConnectionProperty value) {
58+
assertThat(value).isEqualTo(expected);
59+
assertThat(value.getKey()).isEqualTo(expected.getKey());
60+
assertThat(value.getValue()).isEqualTo(expected.getValue());
61+
assertThat(value.toString()).isEqualTo(expected.toString());
62+
assertThat(value.hashCode()).isEqualTo(expected.hashCode());
63+
}
64+
}

google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public class QueryJobConfigurationTest {
3838
private static final DatasetId DATASET_ID = DatasetId.of("dataset");
3939
private static final TableId TABLE_ID = TableId.of("dataset", "table");
4040
private static final List<String> SOURCE_URIS = ImmutableList.of("uri1", "uri2");
41+
private static final String KEY = "time_zone";
42+
private static final String VALUE = "US/Eastern";
43+
private static final ConnectionProperty CONNECTION_PROPERTY =
44+
ConnectionProperty.newBuilder().setKey(KEY).setValue(VALUE).build();
45+
private static final List<ConnectionProperty> CONNECTION_PROPERTIES =
46+
ImmutableList.of(CONNECTION_PROPERTY);
4147
private static final Field FIELD_SCHEMA1 =
4248
Field.newBuilder("StringField", LegacySQLTypeName.STRING)
4349
.setMode(Field.Mode.NULLABLE)
@@ -112,6 +118,7 @@ public class QueryJobConfigurationTest {
112118
.setJobTimeoutMs(TIMEOUT)
113119
.setLabels(LABELS)
114120
.setRangePartitioning(RANGE_PARTITIONING)
121+
.setConnectionProperties(CONNECTION_PROPERTIES)
115122
.build();
116123

117124
@Test
@@ -146,6 +153,7 @@ public void testToPbAndFromPb() {
146153
assertNotNull(QUERY_JOB_CONFIGURATION.getJobTimeoutMs());
147154
assertNotNull(QUERY_JOB_CONFIGURATION.getLabels());
148155
assertNotNull(QUERY_JOB_CONFIGURATION.getRangePartitioning());
156+
assertNotNull(QUERY_JOB_CONFIGURATION.getConnectionProperties());
149157
compareQueryJobConfiguration(
150158
QUERY_JOB_CONFIGURATION, QueryJobConfiguration.fromPb(QUERY_JOB_CONFIGURATION.toPb()));
151159
QueryJobConfiguration job = QueryJobConfiguration.of(QUERY);
@@ -204,5 +212,6 @@ private void compareQueryJobConfiguration(
204212
assertEquals(expected.getJobTimeoutMs(), value.getJobTimeoutMs());
205213
assertEquals(expected.getLabels(), value.getLabels());
206214
assertEquals(expected.getRangePartitioning(), value.getRangePartitioning());
215+
assertEquals(expected.getConnectionProperties(), value.getConnectionProperties());
207216
}
208217
}

0 commit comments

Comments
 (0)