Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datastore fixes #648

Merged
merged 6 commits into from
Feb 17, 2016
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.protobuf.InvalidProtocolBufferException;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -138,43 +139,120 @@ public B set(String name, String value) {
return self();
}

public B set(String name, String first, String second, String... others) {
List<StringValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (String other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, long value) {
properties.put(name, of(value));
return self();
}

public B set(String name, long first, long second, long... others) {
List<LongValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (long other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, double value) {
properties.put(name, of(value));
return self();
}

public B set(String name, double first, double second, double... others) {
List<DoubleValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (double other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, boolean value) {
properties.put(name, of(value));
return self();
}

public B set(String name, boolean first, boolean second, boolean... others) {
List<BooleanValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (boolean other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, DateTime value) {
properties.put(name, of(value));
return self();
}

public B set(String name, DateTime first, DateTime second, DateTime... others) {
List<DateTimeValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (DateTime other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, Key value) {
properties.put(name, of(value));
return self();
}

public B set(String name, Key first, Key second, Key... others) {
List<KeyValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (Key other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, FullEntity<?> value) {
properties.put(name, of(value));
return self();
}

public B set(String name, FullEntity<?> first, FullEntity<?> second, FullEntity<?>... others) {
List<EntityValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (FullEntity<?> other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B set(String name, List<? extends Value<?>> values) {
properties.put(name, of(values));
return self();
}

public B set(String name, Value<?> value, Value<?>... other) {
properties.put(name, of(value, other));
public B set(String name, Value<?> first, Value<?> second, Value<?>... other) {

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

properties.put(name, of(first, second, other));
return self();
}

Expand All @@ -183,6 +261,17 @@ public B set(String name, Blob value) {
return self();
}

public B set(String name, Blob first, Blob second, Blob... others) {

This comment was marked as spam.

List<BlobValue> values = new LinkedList<>();
values.add(of(first));
values.add(of(second));
for (Blob other : others) {
values.add(of(other));
}
properties.put(name, of(values));
return self();
}

public B setNull(String name) {
properties.put(name, of());
return self();
Expand Down Expand Up @@ -348,8 +437,8 @@ public <K extends IncompleteKey> FullEntity<K> getEntity(String name) {
* @throws ClassCastException if value is not a list of values
*/
@SuppressWarnings("unchecked")
public List<? extends Value<?>> getList(String name) {
return ((Value<List<? extends Value<?>>>) getValue(name)).get();
public <T extends Value<?>> List<T> getList(String name) {
return (List<T>) getValue(name).get();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ public String kind() {
return leaf().kind();
}

abstract BaseKey parent();

@Override
public int hashCode() {
return Objects.hash(projectId(), namespace(), path());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ static IncompleteKey fromPb(DatastoreV1.Key keyPb) {
return new IncompleteKey(projectId, namespace, path);
}

/**
* Returns the key's parent.
*/
@Override
public Key parent() {
List<PathElement> ancestors = ancestors();
if (!ancestors.isEmpty()) {

This comment was marked as spam.

PathElement parent = ancestors.get(ancestors.size() - 1);
Key.Builder keyBuilder;
if (parent.hasName()) {
keyBuilder = Key.builder(projectId(), parent.kind(), parent.name());
} else {
keyBuilder = Key.builder(projectId(), parent.kind(), parent.id());
}
return keyBuilder.ancestors(ancestors.subList(0, ancestors.size() - 1)).build();

This comment was marked as spam.

}
return null;
}

public static Builder builder(String projectId, String kind) {
return new Builder(projectId, kind);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ public Builder addValue(Value<?> value) {
return this;
}

public Builder addValue(Value<?> first, Value<?>... other) {
public Builder addValue(Value<?> first, Value<?> second, Value<?>... other) {
addValue(first);
addValue(second);
for (Value<?> value : other) {
addValue(value);
}
Expand Down Expand Up @@ -121,8 +122,8 @@ public ListValue(List<? extends Value<?>> values) {
this(builder().set(values));
}

public ListValue(Value<?> first, Value<?>... other) {
this(new Builder().addValue(first, other));
public ListValue(Value<?> first, Value<?> second, Value<?>... other) {
this(new Builder().addValue(first, second, other));
}

private ListValue(Builder builder) {
Expand All @@ -138,8 +139,8 @@ public static ListValue of(List<? extends Value<?>> values) {
return new ListValue(values);
}

public static ListValue of(Value<?> first, Value<?>... other) {
return new ListValue(first, other);
public static ListValue of(Value<?> first, Value<?> second, Value<?>... other) {

This comment was marked as spam.

return new ListValue(first, second, other);
}

public static Builder builder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.google.gcloud.datastore.testing;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Strings;
Expand Down Expand Up @@ -85,6 +86,7 @@ public class LocalGcdHelper {
private static final String GCLOUD = "gcloud";
private static final Path INSTALLED_GCD_PATH;
private static final String GCD_VERSION_PREFIX = "gcd-emulator ";
private static final double DEFAULT_CONSISTENCY = 0.9;

static {
INSTALLED_GCD_PATH = installedGcdPath();
Expand Down Expand Up @@ -398,9 +400,15 @@ public LocalGcdHelper(String projectId, int port) {
* All content is written to a temporary directory that will be deleted when
* {@link #stop()} is called or when the program terminates) to make sure that no left-over
* data from prior runs is used.
*
* @param consistency the fraction of job application attempts that will succeed, with 0.0
* resulting in no attempts succeeding, and 1.0 resulting in all attempts succeeding. Defaults
* to 0.9. Note that setting this to 1.0 may mask incorrect assumptions about the consistency
* of non-ancestor queries; non-ancestor queries are eventually consistent.
*/
public void start() throws IOException, InterruptedException {
public void start(double consistency) throws IOException, InterruptedException {
// send a quick request in case we have a hanging process from a previous run
checkArgument(consistency >= 0.0 && consistency <= 1.0, "Consistency must be between 0 and 1");
sendQuitRequest(port);
// Each run is associated with its own folder that is deleted once test completes.
gcdPath = Files.createTempDirectory("gcd");
Expand All @@ -415,7 +423,7 @@ public void start() throws IOException, InterruptedException {
} else {
gcdExecutablePath = INSTALLED_GCD_PATH;
}
startGcd(gcdExecutablePath);
startGcd(gcdExecutablePath, consistency);
}

private void downloadGcd() throws IOException {
Expand Down Expand Up @@ -453,7 +461,8 @@ private void downloadGcd() throws IOException {
}
}

private void startGcd(Path executablePath) throws IOException, InterruptedException {
private void startGcd(Path executablePath, double consistency)
throws IOException, InterruptedException {
// cleanup any possible data for the same project
File datasetFolder = new File(gcdPath.toFile(), projectId);
deleteRecurse(datasetFolder.toPath());
Expand Down Expand Up @@ -486,7 +495,8 @@ private void startGcd(Path executablePath) throws IOException, InterruptedExcept
startProcess =
CommandWrapper.create()
.command(gcdAbsolutePath.toString(), "start", "--testing", "--allow_remote_shutdown",
"--port=" + Integer.toString(port), projectId)
"--port=" + Integer.toString(port), "--consistency=" + Double.toString(consistency),
projectId)
.directory(gcdPath)
.start();
processReader = ProcessStreamReader.start(startProcess.getInputStream());
Expand Down Expand Up @@ -578,10 +588,10 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
});
}

public static LocalGcdHelper start(String projectId, int port)
public static LocalGcdHelper start(String projectId, int port, double consistency)
throws IOException, InterruptedException {
LocalGcdHelper helper = new LocalGcdHelper(projectId, port);
helper.start();
helper.start(consistency);
return helper;
}

Expand All @@ -590,10 +600,13 @@ public static void main(String... args) throws IOException, InterruptedException
String action = parsedArgs.get("action");
int port =
(parsedArgs.get("port") == null) ? DEFAULT_PORT : Integer.parseInt(parsedArgs.get("port"));
double consistency =

This comment was marked as spam.

parsedArgs.get("consistency") == null
? DEFAULT_CONSISTENCY : Double.parseDouble(parsedArgs.get("consistency"));
switch (action) {
case "START":
if (!isActive(DEFAULT_PROJECT_ID, port)) {
LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port);
LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port, consistency);
try (FileWriter writer = new FileWriter(".local_gcd_helper")) {
writer.write(helper.gcdPath.toAbsolutePath().toString() + System.lineSeparator());
writer.write(Integer.toString(port));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ public void setUp() {
builder.set("list1", NullValue.of(), StringValue.of("foo"));
builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2)));
builder.set("list3", Collections.singletonList(BooleanValue.of(true)));
builder.set(
"blobList", BLOB, Blob.copyFrom(new byte[] {3, 4}), Blob.copyFrom(new byte[] {5, 6}));
builder.set("booleanList", true, false, true);
builder.set("dateTimeList", DateTime.now(), DateTime.now(), DateTime.now());
builder.set("doubleList", 12.3, 4.56, .789);
builder.set("keyList", KEY, Key.builder("ds2", "k2", "n2").build(),
Key.builder("ds3", "k3", "n3").build());
builder.set("entityList", ENTITY, PARTIAL_ENTITY);
builder.set("stringList", "s1", "s2", "s3");
builder.set("longList", 1, 23, 456);
}

@Test
Expand Down Expand Up @@ -183,6 +193,17 @@ public void testGetList() throws Exception {
assertEquals(Boolean.TRUE, list.get(0).get());
entity = builder.set("list1", ListValue.of(list)).build();
assertEquals(list, entity.getList("list1"));
List<Value<?>> stringList = entity.getList("stringList");
assertEquals(
ImmutableList.of(StringValue.of("s1"), StringValue.of("s2"), StringValue.of("s3")),
stringList);
List<Value<Double>> doubleList = entity.getList("doubleList");
assertEquals(
ImmutableList.of(DoubleValue.of(12.3), DoubleValue.of(4.56), DoubleValue.of(.789)),
doubleList);
List<EntityValue> entityList = entity.getList("entityList");
assertEquals(
ImmutableList.of(EntityValue.of(ENTITY), EntityValue.of(PARTIAL_ENTITY)), entityList);
}

@Test
Expand All @@ -198,7 +219,9 @@ public void testGetBlob() throws Exception {
public void testNames() throws Exception {
Set<String> names = ImmutableSet.<String>builder()
.add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3")
.add("entity", "partialEntity", "null", "dateTime", "blob", "key")
.add("entity", "partialEntity", "null", "dateTime", "blob", "key", "blobList")
.add("booleanList", "dateTimeList", "doubleList", "keyList", "entityList", "stringList")
.add("longList")
.build();
BaseEntity<Key> entity = builder.build();
assertEquals(names, entity.names());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ protected BaseKey build() {
protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException {
return null;
}

@Override
protected BaseKey parent() {
return null;
}
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public class DatastoreTest {
@BeforeClass
public static void beforeClass() throws IOException, InterruptedException {
if (!LocalGcdHelper.isActive(PROJECT_ID, PORT)) {
gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT);
gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 1.0);
}
}

Expand Down
Loading