Skip to content

Command API#

The Command API provides a type-safe, fluent interface for building and executing Concourse operations. Commands can be constructed programmatically, parsed from CCL strings, executed individually, or submitted as a batch.

Building Commands#

Commands are built using fluent builders accessed through three interchangeable entry points:

  • Command.to() — for actions (e.g., add, set, remove)
  • Command.is() — for checks and queries (e.g., holds, verify)
  • Command.go() — for imperatives (e.g., ping)

All three return the same builder — the choice is purely for readability at the call site.

Write Commands#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Java
Command addCmd = Command.to()
    .add("name").as("Jeff Nelson").in(1);

Command setCmd = Command.to()
    .set("email").as("jeff@cinchapi.com").in(1);

Command removeCmd = Command.to()
    .remove("tag").as("beta").from(1);

Command clearCmd = Command.to()
    .clear("name").from(1);

Command insertCmd = Command.to()
    .insert("{\"name\": \"Jeff\"}");

Command linkCmd = Command.to()
    .link("employer").from(1).to(100);

Command unlinkCmd = Command.to()
    .unlink("employer").from(1).to(100);

Read Commands#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Java
Command selectCmd = Command.to()
    .select("name", "age").from(1);

Command selectAllCmd = Command.to()
    .selectAll().from(1);

Command getCmd = Command.to()
    .get("name").from(1);

Command browseCmd = Command.to()
    .browse("color");

Command describeCmd = Command.to()
    .describe(1);

Command navigateCmd = Command.to()
    .navigate("employer.name").from(1);

Query Commands#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Java
Command findCmd = Command.to()
    .find("age > 30");

Command findWithCriteria = Command.to()
    .find(Criteria.where()
        .key("age")
        .operator(Operator.GREATER_THAN)
        .value(30)
        .build());

Command searchCmd = Command.to()
    .search("name").for_("Jeff");

Check Commands#

1
2
3
4
5
6
// Java
Command holdsCmd = Command.is()
    .holds(1);

Command verifyCmd = Command.to()
    .verify("name").as("Jeff").in(1);

Atomic Operation Commands#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// Java
Command vasCmd = Command.to()
    .verifyAndSwap("balance")
    .as(100).in(1).to(90);

Command vosCmd = Command.to()
    .verifyOrSet("status").as("active").in(1);

Command foaCmd = Command.to()
    .findOrAdd("email").as("jeff@cinchapi.com");

Command foiCmd = Command.to()
    .findOrInsert("email = jeff@cinchapi.com")
    .with("{\"email\": \"jeff@cinchapi.com\"}");

Time Travel Commands#

Commands support temporal operations:

1
2
3
4
5
6
// Java
Command historicalGet = Command.to()
    .get("name").from(1).at("yesterday");

Command historicalFind = Command.to()
    .find("age > 30").at("last month");

Ordering and Pagination#

1
2
3
4
5
6
7
8
// Java
Command ordered = Command.to()
    .select("name").from("age > 21")
    .order().by("name").ascending();

Command paged = Command.to()
    .select("name").from("age > 21")
    .page().skip(0).limit(10);

Parsing Commands from CCL#

Commands can be parsed from CCL command strings:

1
2
3
4
5
6
// Java
Command cmd = Command.parse("select name from 1");

// Parse multiple semicolon-separated commands
List<Command> cmds = Command.parseAll(
    "add name as Jeff in 1; set age as 30 in 1");

Converting Commands to CCL#

Any command can be rendered as a CCL string:

1
2
// Java
String ccl = command.ccl();

Executing Commands#

exec()#

Execute one or more commands and return the result of the last command:

1
2
3
// Java
Object result = concourse.exec(
    Command.to().get("name").from(1));

submit()#

Execute one or more commands and return the results of all commands:

1
2
3
4
5
// Java
List<Object> results = concourse.submit(
    Command.to().add("name").as("Jeff").in(1),
    Command.to().add("age").as(30).in(1),
    Command.to().select(1));

Command Groups (Prepare/Submit)#

Use prepare() to queue multiple commands for batch submission. This creates a CommandGroup that accumulates commands and submits them together.

1
2
3
4
5
6
7
// Java
CommandGroup group = concourse.prepare();
group.add("name", "Jeff", 1);
group.add("age", 30, 1);
group.set("status", "active", 1);
List<Object> results = concourse.submit(
    group.commands().toArray(new Command[0]));

The CommandGroup mirrors the full Concourse API, so you can call any operation on it:

1
2
3
4
5
6
// Java
CommandGroup group = concourse.prepare();
group.stage();
group.add("name", "Jeff", 1);
group.set("email", "jeff@cinchapi.com", 1);
group.commit();

Commands in CaSH#

CaSH natively supports CCL command syntax. You can type commands directly at the prompt:

1
2
3
4
[default/cash]$ select name, age from 1
[default/cash]$ find age > 30
[default/cash]$ add name as "Jeff" in 1
[default/cash]$ get name from 1 at "yesterday"

See Concourse Shell for details on CaSH’s dual-mode input and prepare mode.