com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder Maven / Gradle / Ivy
/*
* Copyright 2015-2021 Amazon Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.services.dynamodbv2.xspec;
import java.nio.ByteBuffer;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.amazonaws.annotation.Beta;
/**
* A request-centric Expression Specification Builder that can be used to
* construct valid expressions, and the respective name maps and value maps, for
* various DynamoDB requests in a typeful manner. This includes Update expression, Condition expression (including Filter expression and Key Condition
* expression), and Projection expression. This class is the API entry point to this
* library.
*
* This builder object is not thread-safe but you can reuse or build on (the
* specific states of) a builder by cloning it into separate instances for use
* in a concurrent environment.
*
*
Sample Usage 1: Conditional Updates with Expressions
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
* // num2 BETWEEN 0 AND 100
* .withCondition(
* N("num2").between(0, 100)
* ).buildForUpdate();
*
* table.updateItem(HASH_KEY_NAME, "hashKeyValue", RANGE_KEY_NAME, 0, xspec);
*
*
* Sample Usage 2: Conditional Updates with complex Condition Expression
*
* Let's say you want to include a complex condition expression such as:
*
*
* (attribute_not_exists(item_version) AND attribute_not_exists(config_id) AND attribute_not_exists(config_version)) OR
* (item_version < 123) OR
* (item_version = 123 AND config_id < 456) OR
* (item_version = 123 AND config_id = 456 AND config_version < 999)
*
*
* Here is how:
*
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
* // a complex condition expression (as shown above)
* .withCondition(
* // add explicit parenthesis
* parenthesize( attribute_not_exists("item_version")
* .and( attribute_not_exists("config_id") )
* .and( attribute_not_exists("config_version") )
* ).or( N("item_version").lt(123) )
* .or( N("item_version").eq(123)
* .and( N("config_id").lt(456) ) )
* .or( N("item_version").eq(123)
* .and( N("config_id").eq(456) )
* .and( N("config_version").lt(999) ))
* ).buildForUpdate();
*
* table.updateItem(HASH_KEY_NAME, "hashKeyValue", RANGE_KEY_NAME, 0, xspec);
*
*
* Sample Usage 3: Scan with Filter Expression
*
* Without ExpressionSpecBuilder, the code (using the DynamoDB Document API)
* could be something like:
*
*
* ItemCollection<?> col = table.scan(
* "(#hk = :hashkeyAttrValue) AND (#rk BETWEEN :lo AND :hi)",
* new NameMap().with("#hk", HASH_KEY_NAME).with("#rk", RANGE_KEY_NAME),
* new ValueMap().withString(":hashkeyAttrValue", "allDataTypes")
* .withInt(":lo", 1).withInt(":hi", 10));
*
*
* In contrast, using ExpressionSpecBuilder:
*
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* ScanExpressionSpec xspec = new ExpressionSpecBuilder()
* .withCondition(
* S(HASH_KEY_NAME).eq("allDataTypes")
* .and(N(RANGE_KEY_NAME).between(1, 10))
* ).buildForScan();
*
* ItemCollection col = table.scan(xspec);
*
*
* Sample Usage 4: Updates with SET, ADD, DELETE and REMOVE
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* .addUpdate(S("mapAttr.colors[0]").set("red"))
* .addUpdate(S("mapAttr.colors[1]").set("blue"))
* .addUpdate(L("mapAttr.members").set(
* L("mapAttr.members").listAppend("marry", "liza")))
* .addUpdate(SS("mapAttr.countries").append("cn", "uk"))
* .addUpdate(SS("mapAttr.brands").delete("Facebook", "LinkedIn"))
* .addUpdate(attribute("mapAttr.foo").remove())
* .buildForUpdate();
*
* assertEquals("SET #0.#1[0] = :0, #0.#1[1] = :1, #0.#2 = list_append(#0.#2, :2) ADD #0.#3 :3 DELETE #0.#4 :4 REMOVE #0.#5",
* xspec.getUpdateExpression());
*
* final String hashkey = "addRemoveDeleteColors";
* table.updateItem(HASH_KEY_NAME, hashkey, RANGE_KEY_NAME, 0, xspec);
*
*
* @see PathOperand
*/
@Beta
public final class ExpressionSpecBuilder implements Cloneable {
private final Map> updates;
private Condition keyCondition;
private Condition condition;
private final Set projections;
/**
* Constructs a request-centric Expression Specification Builder that can be used to
* construct valid expressions, and the respective name maps and value maps, for
* various DynamoDB requests in a typeful manner. This includes Update expression, Condition expression (including Filter expression and Key Condition
* expression), and Projection expression. This class is the API entry point to this
* library.
*
* This builder object is not thread-safe but you can reuse or build on (the
* specific states of) a builder by cloning it into separate instances for use
* in a concurrent environment.
*
Sample Usage: Query with Filter Expression
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* QueryExpressionSpec xspec = new ExpressionSpecBuilder()
* .addProjections("numberAttr", "stringAttr")
* .withCondition(BOOL("booleanTrue").eq(true)
* .and(S("mapAttr.key1").eq("value1"))
* ).buildForQuery();
*
* ItemCollection col = table.query(HASH_KEY_NAME, "allDataTypes",
* new RangeKeyCondition("range_key_name").between(1, 10), xspec);
*
*
* Sample Usage: Conditional Updates with Expressions
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
* // num2 BETWEEN 0 AND 100
* .withCondition(
* N("num2").between(0, 100)
* ).buildForUpdate();
*
* table.updateItem(HASH_KEY_NAME, "hashKeyValue", RANGE_KEY_NAME, 0, xspec);
*
* Sample Usage: Scan with Filter Expression
*
* Without ExpressionSpecBuilder, the code (using the DynamoDB Document API)
* could be something like:
*
*
* ItemCollection<?> col = table.scan(
* "(#hk = :hashkeyAttrValue) AND (#rk BETWEEN :lo AND :hi)",
* new NameMap().with("#hk", HASH_KEY_NAME).with("#rk", RANGE_KEY_NAME),
* new ValueMap().withString(":hashkeyAttrValue", "allDataTypes")
* .withInt(":lo", 1).withInt(":hi", 10));
*
*
* In contrast, using ExpressionSpecBuilder:
*
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* ScanExpressionSpec xspec = new ExpressionSpecBuilder()
* .withCondition(
* S(HASH_KEY_NAME).eq("allDataTypes")
* .and(N(RANGE_KEY_NAME).between(1, 10))
* ).buildForScan();
*
* ItemCollection col = table.scan(xspec);
*
*
* Sample Usage: Conditional Updates with Expressions
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
* // num2 BETWEEN 0 AND 100
* .withCondition(
* N("num2").between(0, 100)
* ).buildForUpdate();
*
* table.updateItem(HASH_KEY_NAME, "hashKeyValue", RANGE_KEY_NAME, 0, xspec);
*
*
* Sample Usage: Conditional Updates with complex Condition Expression
*
* Let's say you want to include a complex condition expression such as:
*
*
* (attribute_not_exists(item_version) AND attribute_not_exists(config_id) AND attribute_not_exists(config_version)) OR
* (item_version < 123) OR
* (item_version = 123 AND config_id < 456) OR
* (item_version = 123 AND config_id = 456 AND config_version < 999)
*
*
* Here is how:
*
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
* // a complex condition expression (as shown above)
* .withCondition(
* // add explicit parenthesis
* parenthesize( attribute_not_exists("item_version")
* .and( attribute_not_exists("config_id") )
* .and( attribute_not_exists("config_version") )
* ).or( N("item_version").lt(123) )
* .or( N("item_version").eq(123)
* .and( N("config_id").lt(456) ) )
* .or( N("item_version").eq(123)
* .and( N("config_id").eq(456) )
* .and( N("config_version").lt(999) ))
* ).buildForUpdate();
*
* table.updateItem(HASH_KEY_NAME, "hashKeyValue", RANGE_KEY_NAME, 0, xspec);
*
*
* Sample Usage: Updates with SET, ADD, DELETE and REMOVE
*
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* Table table = dynamo.getTable(TABLE_NAME);
*
* UpdateItemExpressionSpec xspec = new ExpressionSpecBuilder()
* .addUpdate(S("mapAttr.colors[0]").set("red"))
* .addUpdate(S("mapAttr.colors[1]").set("blue"))
* .addUpdate(L("mapAttr.members").set(
* L("mapAttr.members").listAppend("marry", "liza")))
* .addUpdate(SS("mapAttr.countries").append("cn", "uk"))
* .addUpdate(SS("mapAttr.brands").delete("Facebook", "LinkedIn"))
* .addUpdate(attribute("mapAttr.foo").remove())
* .buildForUpdate();
*
* assertEquals("SET #0.#1[0] = :0, #0.#1[1] = :1, #0.#2 = list_append(#0.#2, :2) ADD #0.#3 :3 DELETE #0.#4 :4 REMOVE #0.#5",
* xspec.getUpdateExpression());
*
* final String hashkey = "addRemoveDeleteColors";
* table.updateItem(HASH_KEY_NAME, hashkey, RANGE_KEY_NAME, 0, xspec);
*
*
* @see PathOperand
*/
public ExpressionSpecBuilder() {
this.updates = new LinkedHashMap>();
this.projections = new LinkedHashSet();
}
private ExpressionSpecBuilder(ExpressionSpecBuilder from) {
this.updates = new LinkedHashMap>(from.updates);
this.projections = new LinkedHashSet(from.projections);
this.keyCondition = from.keyCondition;
this.condition = from.condition;
}
/**
* Fluent API to add the given Update expression for a request.
*
* For example:
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* builder
* // SET num1 = num1 + 20
* .addUpdate(
* N("num1").set(N("num1").plus(20)))
* // SET string-attr = "string-value"
* .addUpdate(
* S("string-attr").set("string-value")
* )
*/
public ExpressionSpecBuilder addUpdate(UpdateAction updateAction) {
final String operator = updateAction.getOperator();
List list = updates.get(operator);
if (list == null) {
list = new LinkedList();
updates.put(operator, list);
}
list.add(updateAction);
return this;
}
/**
* Fluent API to set the condition expression for a request.
*
* For example:
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* builder.withCondition(
* // num2 BETWEEN 0 AND 100
* ExpressionSpecBuilder.N("num2").between(0, 100)
* )
* ...
*
* Example of specifying a complex condition:
*
* import static com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder.*;
* ...
* // A complex condition expression:
* //
* // (attribute_not_exists(item_version) AND attribute_not_exists(config_id) AND attribute_not_exists(config_version)) OR
* // (item_version < 123) OR
* // (item_version = 123 AND config_id < 456) OR
* // (item_version = 123 AND config_id = 456 AND config_version < 999)
* //
* builder.withCondition(
* // add explicit parenthesis
* parenthesize( attribute_not_exists("item_version")
* .and( attribute_not_exists("config_id") )
* .and( attribute_not_exists("config_version") )
* ).or( N("item_version").lt(123) )
* .or( N("item_version").eq(123)
* .and( N("config_id").lt(456) ) )
* .or( N("item_version").eq(123)
* .and( N("config_id").eq(456) )
* .and( N("config_version").lt(999) ))
* )
* ...
*
*/
public ExpressionSpecBuilder withCondition(Condition condition) {
this.condition = condition;
return this;
}
public ExpressionSpecBuilder withKeyCondition(Condition keyCondition) {
this.keyCondition = keyCondition;
return this;
}
/**
* Fluent API to add the given attribute to the list of projection of a request.
* For example:
*
* builder.addProjection("binarySetAttribute")
* .addProjection("listAttr[0]")
* .addProjection("mapAttr.name")
* .addProjection("stringSetAttr")
* ;
*
*/
public ExpressionSpecBuilder addProjection(String path) {
projections.add(new PathOperand(path));
return this;
}
/**
* Fluent API to add the given attributes to the list of projection of a request.
* For example:
*
* builder.addProjections("binarySetAttribute", "listAttr[0]", "mapAttr.name", "stringSetAttr");
*
*/
public ExpressionSpecBuilder addProjections(String ... paths) {
for (String path: paths)
addProjection(path);
return this;
}
/**
* Returns an expression specification for use in a DeleteItem
* request to DynamoDB.
*/
public DeleteItemExpressionSpec buildForDeleteItem() {
return new DeleteItemExpressionSpec(this);
}
/**
* Returns an expression specification for use in a GetItem
* request to DynamoDB.
*/
public GetItemExpressionSpec buildForGetItem() {
return new GetItemExpressionSpec(this);
}
/**
* Returns an expression specification for use in a query
* request to DynamoDB.
*/
public QueryExpressionSpec buildForQuery() {
return new QueryExpressionSpec(this);
}
/**
* Returns an expression specification for use in a scan
* request to DynamoDB.
*/
public ScanExpressionSpec buildForScan() {
return new ScanExpressionSpec(this);
}
/**
* Returns an expression specification for use in an UpdateItem
* request to DynamoDB.
*/
public UpdateItemExpressionSpec buildForUpdate() {
return new UpdateItemExpressionSpec(this);
}
/**
* Returns an expression specification for use in a PutItem
* request to DynamoDB.
*/
public PutItemExpressionSpec buildForPut() {
return new PutItemExpressionSpec(this);
}
/**
* Builds and returns the update expression to be used in a dynamodb
* request; or null if there is none.
*/
String buildUpdateExpression(SubstitutionContext context) {
StringBuilder sb = new StringBuilder();
for (Map.Entry> e: updates.entrySet()) {
boolean firstOfUpdateType = true;
for (UpdateAction expr: e.getValue()) {
if (firstOfUpdateType) {
firstOfUpdateType = false;
final String operator = e.getKey();
if (sb.length() > 0)
sb.append(" ");
sb.append(operator).append(" ");
} else {
sb.append(", ");
}
sb.append(expr.asSubstituted(context));
}
}
return sb.toString();
}
/**
* Builds and returns the projection expression to be used in a dynamodb
* GetItem request; or null if there is none.
*/
String buildProjectionExpression(SubstitutionContext context) {
if (projections.size() == 0)
return null;
StringBuilder sb = new StringBuilder();
for (PathOperand projection : projections) {
if (sb.length() > 0)
sb.append(", ");
sb.append(projection.asSubstituted(context));
}
return sb.toString();
}
/**
* Builds and returns the condition expression to be used in a dynamodb
* request; or null if there is none.
*/
String buildConditionExpression(SubstitutionContext context) {
return condition == null ? null : condition.asSubstituted(context);
}
/**
* Builds and returns the key condition expression to be used in a dynamodb
* query request; or null if there is none.
*/
String buildKeyConditionExpression(SubstitutionContext context) {
return keyCondition == null ? null : keyCondition.asSubstituted(context);
}
@Override
public ExpressionSpecBuilder clone() {
return new ExpressionSpecBuilder(this);
}
////////////// static factory methods //////////////
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param pathOperand
* path operand that refers to the attribute
* @param operand
* default value if the attribute doesn't exist
*/
static IfNotExistsFunction if_not_exists(
PathOperand pathOperand, Operand operand) {
return new IfNotExistsFunction(pathOperand, operand);
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for number (N) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
Number defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for binary (B) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
byte[] defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for binary (B) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
ByteBuffer defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for boolean (BOOL) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
boolean defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for binary set (BS) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
byte[] ... defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for binary set (BS) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
ByteBuffer ... defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for list (L) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
List defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for map (M) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
Map defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for number set (NS) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
Number ... defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for string (S) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
String defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns an IfNotExists
object which represents an if_not_exists(path, operand) function call; used for building
* expression.
*
*
* "if_not_exists (path, operand) – If the item does not contain an attribute
* at the specified path, then if_not_exists evaluates to operand; otherwise,
* it evaluates to path. You can use this function to avoid overwriting an
* attribute already present in the item."
*
*
* @param path
* document path to an attribute
* @param defaultValue
* default value if the attribute doesn't exist
*
* @return an IfNotExists
object for string set (SS) attribute.
*/
public static IfNotExistsFunction if_not_exists(String path,
String ... defaultValue) {
return if_not_exists(new PathOperand(path), new LiteralOperand(
defaultValue));
}
/**
* Returns a ListAppend
object which represents a list_append(operand, operand) function call; used for building
* expression.
*
*
* "list_append(operand, operand) – This function evaluates to a list with a
* new element added to it. You can append the new element to the start or
* the end of the list by reversing the order of the operands."
*
*
* @param path
* document path to a list attribute
* @param value
* single value to be appended to the list attribute
*/
public static ListAppendFunction list_append(String path, T value) {
LinkedList list = new LinkedList();
list.add(value);
return list_append(path, list);
}
/**
* Returns a ListAppend
object which represents a list_append(operand, operand) function call; used for building
* expression.
*
*
* "list_append(operand, operand) – This function evaluates to a list with a
* new element added to it. You can append the new element to the start or
* the end of the list by reversing the order of the operands."
*
*
* @param path
* document path to a list attribute
* @param value
* list of values to be appended to the list attribute
*/
public static ListAppendFunction list_append(String path,
List value) {
return new ListAppendFunction(L(path), new ListLiteralOperand(new LinkedList(
value)));
}
/**
* Returns a ListAppend
object which represents a list_append(operand, operand) function call; used for building
* expression.
*
*
* "list_append(operand, operand) – This function evaluates to a list with a
* new element added to it. You can append the new element to the start or
* the end of the list by reversing the order of the operands."
*
*
* @param value
* list of values to be appended to
* @param path
* document path to a list attribute
*/
public static ListAppendFunction list_append(List value,
String path) {
return new ListAppendFunction(new ListLiteralOperand(new LinkedList(value)),
L(path));
}
// ///////////////////////// FunctionCondition factory methods
/**
* Returns a function condition (that evaluates to true if the attribute of the
* specified path operand exists) for building condition expression.
*/
public static FunctionCondition attribute_exists(
PathOperand pathOperand) {
return new FunctionCondition("attribute_exists", pathOperand);
}
/**
* Returns a function condition (that evaluates to true if the attribute at the
* specified path exists) for building condition expression.
*/
public static FunctionCondition attribute_exists(String path) {
return attribute_exists(new PathOperand(path));
}
/**
* Returns a function condition (that evaluates to true if the attribute of the
* specified path operand does not exist) for building condition expression.
*/
public static FunctionCondition attribute_not_exists(
PathOperand pathOperand) {
return new FunctionCondition("attribute_not_exists", pathOperand);
}
/**
* Returns a function condition (that evaluates to true if the attribute at the
* specified path does not exist) for building condition expression.
*/
public static FunctionCondition attribute_not_exists(String path) {
return attribute_not_exists(new PathOperand(path));
}
/**
* Returns a negation of the specified condition; used for building condition
* expression.
*/
public static NegationCondition not(Condition cond) {
return new NegationCondition(cond);
}
/**
* Returns a RemoveAction
for removing the attribute with the
* specified path from an item; used for building update expression.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static RemoveAction remove(String path) {
return new PathOperand(path).remove();
}
/**
* Returns a path operand that refers to an attribute of some unspecified
* data type; used for building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static PathOperand attribute(String path) {
return new PathOperand(path);
}
/**
* Creates a path operand that refers to a boolean attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static BOOL BOOL(String path) {
return new BOOL(path);
}
/**
* Creates a path operand that refers to a NULL attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static NULL NULL(String path) {
return new NULL(path);
}
/**
* Creates a path operand that refers to a binary attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static B B(String path) {
return new B(path);
}
/**
* Creates a path operand that refers to a number attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static N N(String path) {
return new N(path);
}
/**
* Creates a path operand that refers to a string attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static S S(String path) {
return new S(path);
}
/**
* Creates a path operand that refers to a binary-set attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static BS BS(String path) {
return new BS(path);
}
/**
* Creates a path operand that refers to a number-set attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static NS NS(String path) {
return new NS(path);
}
/**
* Creates a path operand that refers to a string-set attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static SS SS(String path) {
return new SS(path);
}
/**
* Creates a path operand that refers to a list attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static L L(String path) {
return new L(path);
}
/**
* Creates a path operand that refers to a map attribute for the purpose of building expressions.
*
* @param path
* the document path to the attribute, where nested path elements
* are assumed to be delimited by either "." or array indexing
* such as "[1]".
*/
public static M M(String path) {
return new M(path);
}
/**
* Returns an explicitly parenthesized condition, ie '(' condition ')' used
* in building condition expressions.
*
* @see #_(Condition)
*/
public static ParenthesizedCondition parenthesize(Condition condition) {
return ParenthesizedCondition.getInstance(condition);
}
/**
* A short hand for calling {@link #parenthesize(Condition)} to explicitly
* parenthesize a given condition for building condition expressions.
*/
public static ParenthesizedCondition _(Condition condition) {
return parenthesize(condition);
}
}