public StringValue(String value) { this(newBuilder(value)); }
@Override public Builder newBuilder(String value) { return StringValue.newBuilder(value); }
@SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { StringValue.Builder builder = StringValue.newBuilder(CONTENT); StringValue value = builder.setMeaning(1).setExcludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); assertEquals(1, value.getMeaning()); assertTrue(value.excludeFromIndexes()); } }
@Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) .clear() .setNull("bla") .set("list3", StringValue.of("bla"), StringValue.newBuilder("bla").build()) .build(); transaction.update(entity2); transaction.delete(KEY1); transaction.rollback(); transaction.rollback(); // should be safe to repeat rollback calls try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException ex) { // expected to fail } verifyNotUsable(transaction); List<Entity> list = datastore.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); assertEquals(3, list.size()); }
@Test public void testNewTransactionRollback() { Transaction transaction = DATASTORE.newTransaction(); transaction.add(ENTITY3); Entity entity2 = Entity.newBuilder(ENTITY2) .clear() .setNull("bla") .set("list3", StringValue.of("bla"), StringValue.newBuilder("bla").build()) .build(); transaction.update(entity2); transaction.delete(KEY1); transaction.rollback(); transaction.rollback(); // should be safe to repeat rollback calls try { transaction.commit(); fail("Expecting a failure"); } catch (DatastoreException expected) { assertEquals("FAILED_PRECONDITION", expected.getReason()); } List<Entity> list = DATASTORE.fetch(KEY1, KEY2, KEY3); assertEquals(ENTITY1, list.get(0)); assertEquals(ENTITY2, list.get(1)); assertNull(list.get(2)); assertEquals(3, list.size()); }
@Override public Value<FullEntity<?>> saveSafe(final P pojo, final boolean index, final SaveContext ctx, final Path path) throws SkipException { // check if we need to redirect to a different translator if (pojo.getClass() != declaredClass) { // Sometimes generics are more of a hindrance than a help @SuppressWarnings("unchecked") final ClassTranslator<P> translator = (ClassTranslator<P>)byClass.get(pojo.getClass()); if (translator == null) throw new IllegalStateException("Class '" + pojo.getClass() + "' is not a registered @Subclass"); else return translator.save(pojo, index, ctx, path); } else { // This is a normal save final FullEntity.Builder<IncompleteKey> into = FullEntity.newBuilder(); populator.save(pojo, index, ctx, path, into); if (discriminator != null) { into.set(DISCRIMINATOR_PROPERTY, StringValue.newBuilder(discriminator).setExcludeFromIndexes(true).build()); if (!indexedDiscriminators.isEmpty()) into.set(DISCRIMINATOR_INDEX_PROPERTY, ListValue.of(indexedDiscriminators)); } // The question of whether to index this is weird. In order for subthings to be indexed, the entity needs // to be indexed. But then lists with index-heterogeous values (say, nulls) get reordered (!) // by the datastore. So we always index EntityValues and force all the list translators homogenize their lists. // Gross but seems to be the only way. return EntityValue.of(into.build()); } }
@Override public P loadSafe(final Value<FullEntity<?>> container, final LoadContext ctx, final Path path) throws SkipException { // check if we need to redirect to a different translator final String containerDiscriminator = container.get().contains(DISCRIMINATOR_PROPERTY) ? container.get().getString(DISCRIMINATOR_PROPERTY) : null; // wow no Optional or nullable get if (!Objects.equals(discriminator, containerDiscriminator)) { final ClassTranslator<? extends P> translator = byDiscriminator.get(containerDiscriminator); if (translator == null) { throw new IllegalStateException("Datastore object has discriminator value '" + containerDiscriminator + "' but no relevant @Subclass is registered"); } else { // This fixes alsoLoad names in discriminators by changing the discriminator to what the // translator expects for loading that subclass. Otherwise we'll get the error above since the // translator discriminator and the container discriminator won't match. final StringValue discriminatorValue = StringValue.newBuilder(translator.getDiscriminator()).setExcludeFromIndexes(true).build(); final FullEntity<?> updatedEntity = FullEntity.newBuilder(container.get()).set(DISCRIMINATOR_PROPERTY, discriminatorValue).build(); return translator.load(EntityValue.of(updatedEntity), ctx, path); } } else { // This is a normal load if (log.isTraceEnabled()) log.trace(LogUtils.msg(path, "Instantiating a " + declaredClass.getName())); final P into = forge.construct(declaredClass); populator.load(container.get(), ctx, path, into); return into; } }
@Override public Builder newBuilder(String value) { return StringValue.newBuilder(value); }
public StringValue(String value) { this(newBuilder(value)); }
/** * Adds a task entity to the Datastore. * * @param description The task description * @return The {@link Key} of the entity * @throws DatastoreException if the ID allocation or put fails */ Key addTask(String description) { Key key = datastore.allocateId(keyFactory.newKey()); Entity task = Entity.newBuilder(key) .set("description", StringValue.newBuilder(description).setExcludeFromIndexes(true).build()) .set("created", Timestamp.now()) .set("done", false) .build(); datastore.put(task); return key; } // [END datastore_add_entity]
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(input.toString()); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder((String) input); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(input.toString()); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(String.valueOf((char) input)); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(new String((char[]) input)); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(((LocalDateTime) input).format(FORMATTER)); }
static StringValue jsonValue(Object o) throws JsonProcessingException { return StringValue .newBuilder(OBJECT_MAPPER.writeValueAsString(o)) .setExcludeFromIndexes(true) .build(); }
@Override public ValueBuilder<?, ?, ?> toDatastore(Object input) { if (input == null) { return NullValue.newBuilder(); } return StringValue.newBuilder(((LocalTime) input).format(FORMATTER)); }
static StringValue valueOf(String input) { return StringValue.newBuilder(input) .setExcludeFromIndexes(true) .build(); } }
@Override public WorkflowId store(Workflow workflow) throws IOException { final Key componentKey = DatastoreStorage.componentKey(tx.getDatastore().newKeyFactory(), workflow.componentId()); if (tx.get(componentKey) == null) { tx.put(Entity.newBuilder(componentKey).build()); } final String json = OBJECT_MAPPER.writeValueAsString(workflow); final Key workflowKey = DatastoreStorage.workflowKey(tx.getDatastore().newKeyFactory(), workflow.id()); final Optional<Entity> workflowOpt = DatastoreStorage.getOpt(tx, workflowKey); final Entity workflowEntity = DatastoreStorage.asBuilderOrNew(workflowOpt, workflowKey) .set(PROPERTY_WORKFLOW_JSON, StringValue.newBuilder(json).setExcludeFromIndexes(true).build()) .build(); tx.put(workflowEntity); return workflow.id(); }