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 SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).

There is a newer version: 1.11.60
Show newest version
/*
 * Copyright 2015-2016 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); } }