All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder Maven / Gradle / Ivy

Go to download

The AWS Java SDK for Amazon DynamoDB module holds the client classes that are used for communicating with Amazon DynamoDB Service

The newest version!
/*
 * Copyright 2015-2024 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); } }