Skip to content

Commit 088ed29

Browse files
authored
---
yaml --- r: 8363 b: refs/heads/snehashah-snippets c: cec93a5 h: refs/heads/master i: 8361: 7b17bdc 8359: e146344
1 parent 728ef2a commit 088ed29

8 files changed

Lines changed: 465 additions & 31 deletions

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ refs/tags/v0.18.0: 9d193c4c4b9d1c6f21515dd8e50836b9194ec9bb
5656
refs/tags/v0.19.0: e67b56e4d8dad5f9a7b38c9b2107c23c828f2ed5
5757
refs/tags/v0.20.0: 839f7fb7156535146aa1cb2c5aadd8d375d854e8
5858
refs/tags/v0.20.1: 370471f437f1f4f68a11e068df5cd6bf39edb1fa
59-
refs/heads/snehashah-snippets: 5a75fc0140ee8b5db599a09beddac00f437c50a6
59+
refs/heads/snehashah-snippets: cec93a50abb6ebe241c9d61aee8d8835cbcf7d24
6060
refs/tags/v0.20.2: 5a53aa06f268b74dc192204f4f83e1a04d40f65d
6161
refs/tags/v0.20.3: 269025fdc14af0b68df214a4518be5379b2fe569
6262
refs/tags/v0.21.0: f88b200e00e41ba6262ee88a92abba38b1e2417e

branches/snehashah-snippets/google-cloud-spanner/src/main/java/com/google/cloud/spanner/ResultSets.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public boolean next() throws SpannerException {
6464
@Override
6565
public Struct getCurrentRowAsStruct() {
6666
Preconditions.checkState(!closed, "ResultSet is closed");
67+
Preconditions.checkState(index >= 0, "Must be preceded by a next() call");
6768
Preconditions.checkElementIndex(index, rows.size(), "All rows have been yielded");
6869
return rows.get(index);
6970
}

branches/snehashah-snippets/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerImpl.java

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ class SpannerImpl extends BaseService<SpannerOptions> implements Spanner {
122122
@GuardedBy("this")
123123
private final Map<DatabaseId, DatabaseClientImpl> dbClients = new HashMap<>();
124124

125-
private final DatabaseAdminClient dbAdminClient = new DatabaseAdminClientImpl();
126-
private final InstanceAdminClient instanceClient = new InstanceAdminClientImpl(dbAdminClient);
125+
private final DatabaseAdminClient dbAdminClient;
126+
private final InstanceAdminClient instanceClient;
127127

128128
@GuardedBy("this")
129129
private boolean spannerIsClosed = false;
@@ -132,6 +132,8 @@ class SpannerImpl extends BaseService<SpannerOptions> implements Spanner {
132132
super(options);
133133
this.rpc = rpc;
134134
this.defaultPrefetchChunks = defaultPrefetchChunks;
135+
this.dbAdminClient = new DatabaseAdminClientImpl(options.getProjectId(), rpc);
136+
this.instanceClient = new InstanceAdminClientImpl(options.getProjectId(), rpc, dbAdminClient);
135137
}
136138

137139
SpannerImpl(SpannerOptions options) {
@@ -205,7 +207,8 @@ static <T> T runWithRetries(Callable<T> callable) {
205207
logger.log(Level.FINE, "Retryable exception, will sleep and retry", e);
206208
backoffSleep(context, backOff);
207209
} catch (Exception e) {
208-
throw Throwables.propagate(e);
210+
Throwables.throwIfUnchecked(e);
211+
throw newSpannerException(ErrorCode.INTERNAL, "Unexpected exception thrown", e);
209212
}
210213
}
211214
}
@@ -323,19 +326,7 @@ Object value() {
323326
return ImmutableMap.copyOf(tmp);
324327
}
325328

326-
private String getProjectId() {
327-
return getOptions().getProjectId();
328-
}
329-
330-
private String getInstanceName(String instanceId) {
331-
return new InstanceId(getProjectId(), instanceId).getName();
332-
}
333-
334-
private String getDatabaseName(String instanceId, String databaseId) {
335-
return new DatabaseId(new InstanceId(getProjectId(), instanceId), databaseId).getName();
336-
}
337-
338-
private <T extends Message> T unpack(Any response, Class<T> clazz) throws SpannerException {
329+
private static <T extends Message> T unpack(Any response, Class<T> clazz) throws SpannerException {
339330
try {
340331
return response.unpack(clazz);
341332
} catch (InvalidProtocolBufferException e) {
@@ -344,7 +335,7 @@ private <T extends Message> T unpack(Any response, Class<T> clazz) throws Spanne
344335
}
345336
}
346337

347-
private abstract class PageFetcher<S, T> implements NextPageFetcher<S> {
338+
private static abstract class PageFetcher<S, T> implements NextPageFetcher<S> {
348339
private String nextPageToken;
349340

350341
@Override
@@ -370,12 +361,21 @@ public Paginated<T> call() {
370361
abstract S fromProto(T proto);
371362
}
372363

373-
private String randomOperationId() {
364+
private static String randomOperationId() {
374365
UUID uuid = UUID.randomUUID();
375366
return ("r" + uuid.toString()).replace("-", "_");
376367
}
377368

378-
class DatabaseAdminClientImpl implements DatabaseAdminClient {
369+
static class DatabaseAdminClientImpl implements DatabaseAdminClient {
370+
371+
private final String projectId;
372+
private final SpannerRpc rpc;
373+
374+
DatabaseAdminClientImpl(String projectId, SpannerRpc rpc) {
375+
this.projectId = projectId;
376+
this.rpc = rpc;
377+
}
378+
379379
@Override
380380
public Operation<Database, CreateDatabaseMetadata> createDatabase(
381381
String instanceId, String databaseId, Iterable<String> statements) throws SpannerException {
@@ -436,7 +436,7 @@ public Operation<Void, UpdateDatabaseDdlMetadata> call() {
436436
String opName =
437437
OP_NAME_TEMPLATE.instantiate(
438438
"project",
439-
getProjectId(),
439+
projectId,
440440
"instance",
441441
instanceId,
442442
"database",
@@ -519,18 +519,30 @@ public Database fromProto(com.google.spanner.admin.database.v1.Database proto) {
519519
}
520520
return pageFetcher.getNextPage();
521521
}
522+
523+
private String getInstanceName(String instanceId) {
524+
return new InstanceId(projectId, instanceId).getName();
525+
}
526+
527+
private String getDatabaseName(String instanceId, String databaseId) {
528+
return new DatabaseId(new InstanceId(projectId, instanceId), databaseId).getName();
529+
}
522530
}
523531

524-
class InstanceAdminClientImpl implements InstanceAdminClient {
532+
static class InstanceAdminClientImpl implements InstanceAdminClient {
525533
final DatabaseAdminClient dbClient;
534+
final String projectId;
535+
final SpannerRpc rpc;
526536

527-
InstanceAdminClientImpl(DatabaseAdminClient dbClient) {
537+
InstanceAdminClientImpl(String projectId, SpannerRpc rpc, DatabaseAdminClient dbClient) {
538+
this.projectId = projectId;
539+
this.rpc = rpc;
528540
this.dbClient = dbClient;
529541
}
530542

531543
@Override
532544
public InstanceConfig getInstanceConfig(String configId) throws SpannerException {
533-
final String instanceConfigName = new InstanceConfigId(getProjectId(), configId).getName();
545+
final String instanceConfigName = new InstanceConfigId(projectId, configId).getName();
534546
return runWithRetries(
535547
new Callable<InstanceConfig>() {
536548
@Override
@@ -570,7 +582,7 @@ public InstanceConfig fromProto(
570582
@Override
571583
public Operation<Instance, CreateInstanceMetadata> createInstance(InstanceInfo instance)
572584
throws SpannerException {
573-
String projectName = PROJECT_NAME_TEMPLATE.instantiate("project", getProjectId());
585+
String projectName = PROJECT_NAME_TEMPLATE.instantiate("project", projectId);
574586
com.google.longrunning.Operation op =
575587
rpc.createInstance(projectName, instance.getId().getInstance(), instance.toProto());
576588
return Operation.create(
@@ -594,7 +606,7 @@ public CreateInstanceMetadata parseMetadata(Any metadata) {
594606

595607
@Override
596608
public Instance getInstance(String instanceId) throws SpannerException {
597-
final String instanceName = new InstanceId(getProjectId(), instanceId).getName();
609+
final String instanceName = new InstanceId(projectId, instanceId).getName();
598610
return runWithRetries(
599611
new Callable<Instance>() {
600612
@Override
@@ -635,7 +647,7 @@ public void deleteInstance(final String instanceId) throws SpannerException {
635647
new Callable<Void>() {
636648
@Override
637649
public Void call() {
638-
rpc.deleteInstance(new InstanceId(getProjectId(), instanceId).getName());
650+
rpc.deleteInstance(new InstanceId(projectId, instanceId).getName());
639651
return null;
640652
}
641653
});
@@ -2006,7 +2018,6 @@ protected long[] getLongArrayInternal(int columnIndex) {
20062018
}
20072019

20082020
@Override
2009-
@SuppressWarnings("unchecked") // We know ARRAY<INT64> produces an Int64Array.
20102021
protected Int64Array getLongListInternal(int columnIndex) {
20112022
return (Int64Array) rowData.get(columnIndex);
20122023
}
@@ -2017,7 +2028,6 @@ protected double[] getDoubleArrayInternal(int columnIndex) {
20172028
}
20182029

20192030
@Override
2020-
@SuppressWarnings("unchecked") // We know ARRAY<FLOAT64> produces a Float64Array.
20212031
protected Float64Array getDoubleListInternal(int columnIndex) {
20222032
return (Float64Array) rowData.get(columnIndex);
20232033
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright 2017 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.cloud.spanner;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
import static org.mockito.Mockito.verify;
21+
import static org.mockito.Mockito.when;
22+
import static org.mockito.MockitoAnnotations.initMocks;
23+
24+
import com.google.cloud.spanner.spi.v1.SpannerRpc;
25+
import com.google.cloud.spanner.spi.v1.SpannerRpc.Paginated;
26+
import com.google.common.collect.ImmutableList;
27+
import com.google.common.collect.Lists;
28+
import com.google.protobuf.Any;
29+
import com.google.protobuf.Message;
30+
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
31+
import com.google.spanner.admin.database.v1.Database;
32+
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
33+
import java.util.Collections;
34+
import java.util.List;
35+
import org.junit.Before;
36+
import org.junit.Test;
37+
import org.junit.runner.RunWith;
38+
import org.junit.runners.JUnit4;
39+
import org.mockito.Mock;
40+
41+
/** Unit tests for {@link com.google.cloud.spanner.SpannerImpl.DatabaseAdminClientImpl}. */
42+
@RunWith(JUnit4.class)
43+
public class DatabaseAdminClientImplTest {
44+
private static final String PROJECT_ID = "my-project";
45+
private static final String INSTANCE_ID = "my-instance";
46+
private static final String INSTANCE_NAME = "projects/my-project/instances/my-instance";
47+
private static final String DB_ID = "my-db";
48+
private static final String DB_NAME = "projects/my-project/instances/my-instance/databases/my-db";
49+
private static final String DB_NAME2 =
50+
"projects/my-project/instances/my-instance/databases/my-db2";
51+
52+
@Mock SpannerRpc rpc;
53+
SpannerImpl.DatabaseAdminClientImpl client;
54+
55+
@Before
56+
public void setUp() {
57+
initMocks(this);
58+
client = new SpannerImpl.DatabaseAdminClientImpl(PROJECT_ID, rpc);
59+
}
60+
61+
private Database getDatabaseProto() {
62+
return Database.newBuilder().setName(DB_NAME).setState(Database.State.READY).build();
63+
}
64+
65+
private Database getAnotherDatabaseProto() {
66+
return Database.newBuilder().setName(DB_NAME2).setState(Database.State.READY).build();
67+
}
68+
69+
static Any toAny(Message message) {
70+
return Any.newBuilder()
71+
.setTypeUrl("type.googleapis.com/" + message.getDescriptorForType().getFullName())
72+
.setValue(message.toByteString())
73+
.build();
74+
}
75+
76+
@Test
77+
public void getDatabase() {
78+
when(rpc.getDatabase(DB_NAME)).thenReturn(getDatabaseProto());
79+
com.google.cloud.spanner.Database db = client.getDatabase(INSTANCE_ID, DB_ID);
80+
assertThat(db.getId().getName()).isEqualTo(DB_NAME);
81+
assertThat(db.getState()).isEqualTo(DatabaseInfo.State.READY);
82+
}
83+
84+
@Test
85+
public void createDatabase() {
86+
when(rpc.createDatabase(
87+
INSTANCE_NAME, "CREATE DATABASE `" + DB_ID + "`", Collections.<String>emptyList()))
88+
.thenReturn(
89+
com.google.longrunning.Operation.newBuilder()
90+
.setDone(true)
91+
.setName("my-op")
92+
.setResponse(toAny(getDatabaseProto()))
93+
.build());
94+
Operation<com.google.cloud.spanner.Database, CreateDatabaseMetadata> op =
95+
client.createDatabase(INSTANCE_ID, DB_ID, Collections.<String>emptyList());
96+
assertThat(op.isDone()).isTrue();
97+
assertThat(op.getResult().getId().getName()).isEqualTo(DB_NAME);
98+
}
99+
100+
@Test
101+
public void updateDatabaseDdl() {
102+
String opName = DB_NAME + "/operations/myop";
103+
String opId = "myop";
104+
List<String> ddl = ImmutableList.of();
105+
when(rpc.updateDatabaseDdl(DB_NAME, ddl, opId))
106+
.thenReturn(
107+
com.google.longrunning.Operation.newBuilder().setDone(true).setName(opName).build());
108+
Operation<Void, UpdateDatabaseDdlMetadata> op =
109+
client.updateDatabaseDdl(INSTANCE_ID, DB_ID, ddl, opId);
110+
assertThat(op.isDone());
111+
assertThat(op.getName()).isEqualTo(opName);
112+
}
113+
114+
@Test
115+
public void updateDatabaseDdlOpAlreadyExists() {
116+
String opName = DB_NAME + "/operations/myop";
117+
String opId = "myop";
118+
List<String> ddl = ImmutableList.of();
119+
when(rpc.updateDatabaseDdl(DB_NAME, ddl, opId))
120+
.thenThrow(SpannerExceptionFactory.newSpannerException(ErrorCode.ALREADY_EXISTS, ""));
121+
Operation<Void, UpdateDatabaseDdlMetadata> op =
122+
client.updateDatabaseDdl(INSTANCE_ID, DB_ID, ddl, opId);
123+
assertThat(op.getName()).isEqualTo(opName);
124+
}
125+
126+
@Test
127+
public void dropDatabase() {
128+
client.dropDatabase(INSTANCE_ID, DB_ID);
129+
verify(rpc).dropDatabase(DB_NAME);
130+
}
131+
132+
@Test
133+
public void getDatabaseDdl() {
134+
List<String> ddl = ImmutableList.of("CREATE TABLE mytable()");
135+
when(rpc.getDatabaseDdl(DB_NAME)).thenReturn(ddl);
136+
assertThat(client.getDatabaseDdl(INSTANCE_ID, DB_ID)).isEqualTo(ddl);
137+
}
138+
139+
@Test
140+
public void listDatabases() {
141+
String pageToken = "token";
142+
when(rpc.listDatabases(INSTANCE_NAME, 1, null))
143+
.thenReturn(new Paginated<>(ImmutableList.<Database>of(getDatabaseProto()), pageToken));
144+
when(rpc.listDatabases(INSTANCE_NAME, 1, pageToken))
145+
.thenReturn(new Paginated<>(ImmutableList.<Database>of(getAnotherDatabaseProto()), ""));
146+
List<com.google.cloud.spanner.Database> dbs =
147+
Lists.newArrayList(client.listDatabases(INSTANCE_ID, Options.pageSize(1)).iterateAll());
148+
assertThat(dbs.get(0).getId().getName()).isEqualTo(DB_NAME);
149+
assertThat(dbs.get(1).getId().getName()).isEqualTo(DB_NAME2);
150+
assertThat(dbs.size()).isEqualTo(2);
151+
}
152+
}

0 commit comments

Comments
 (0)