/*
* Copyright (c) 2013-2017 Cinchapi 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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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.cinchapi.concourse;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import com.cinchapi.common.reflect.Reflection;
import com.cinchapi.concourse.annotate.Incubating;
import com.cinchapi.concourse.config.ConcourseClientPreferences;
import com.cinchapi.concourse.lang.BuildableState;
import com.cinchapi.concourse.lang.Criteria;
import com.cinchapi.concourse.thrift.Diff;
import com.cinchapi.concourse.thrift.Operator;
import com.cinchapi.concourse.util.Convert;
import com.google.common.collect.Sets;
import com.google.common.collect.Multimap;
/**
* A client connection to a Concourse node or cluster. Use one of the
* {@link Concourse#connect()} methods to instantiate.
*
* <h2>Overview</h2>
* <p>
* Concourse is a self-tuning database that enables live analytics for large
* streams of operational data. Developers use Concourse to quickly build
* software that requires both ACID transactions and the ability to get data
* insights on demand. With Concourse, end-to-end data management requires no
* extra infrastructure, no prior configuration and no additional coding–all of
* which greatly reduce costs and allow developers to focus on core business
* problems.
* </p>
*
* <h2>Using Transactions</h2>
* <p>
* By default, Concourse conducts every operation in {@code autocommit} mode
* where every change is immediately written. Concourse also supports the
* ability to stage a group of operations within transactions that are atomic,
* consistent, isolated, and durable using the {@link #stage()},
* {@link #commit()} and {@link #abort()} methods.
*
* </p>
* <h2>Thread Safety</h2>
* <p>
* You should <strong>not</strong> use the same client connection in multiple
* threads. If you need to interact with Concourse using multiple threads, you
* should create a separate connection for each thread or use a
* {@link ConnectionPool}.
* </p>
*
* @author Jeff Nelson
*/
@NotThreadSafe
public abstract class Concourse implements AutoCloseable {
/**
* Create a new connection to the Concourse deployment described in
* {@code ./concourse_client.prefs} (or, if the file does not exist, the
* default environment of the server at localhost:1717) and return a handle
* to facilitate interaction.
*
* @return the handle
*/
public static Concourse connect() {
return new ConcourseThriftDriver();
}
/**
* Create a new connection to the specified {@code environment} of the
* Concourse deployment described in {@code ~/concourse_client.prefs} (or,
* if the file does not exist, the server at localhost:1717) and return a
* handle to facilitate interaction.
*
* @param environment the environment to use
* @return the handle
*/
public static Concourse connect(String environment) {
return new ConcourseThriftDriver(environment);
}
/**
* Create a new connection to the default environment of the specified
* Concourse Server and return a handle to facilitate interaction.
*
* @param host the server host
* @param port the listener port for client connections
* @param username the name of the user on behalf of whom to connect
* @param password the password for the {@code username}
* @return the handle
*/
public static Concourse connect(String host, int port, String username,
String password) {
return new ConcourseThriftDriver(host, port, username, password);
}
/**
* Create a new connection to the specified {@code environment} of the
* specified Concourse Server and return a handle to facilitate interaction.
*
* @param host the server host
* @param port the listener port for client connections
* @param username the name of the user on behalf of whom to connect
* @param password the password for the {@code username}
* @param environment the name of the environment to use for the
* connection
* @return the handle
*/
public static Concourse connect(String host, int port, String username,
String password, String environment) {
return new ConcourseThriftDriver(host, port, username, password,
environment);
}
/**
* Create a new connection using the information specified in the prefs
* {@code file}.
*
* @param file the absolute path to the prefs file that contains the
* information for the Concourse deployment (relative paths will
* resolve to the user's home directory)
* @return the handle
*/
public static Concourse connectWithPrefs(String file) {
ConcourseClientPreferences prefs = ConcourseClientPreferences
.open(file);
return connect(prefs.getHost(), prefs.getPort(), prefs.getUsername(),
String.valueOf(prefs.getPassword()), prefs.getEnvironment());
}
/**
* Create a new connecting by copying the connection information from the
* provided {@code concourse} handle.
*
* @param concourse an existing {@link Concourse} connection handle
* @return the handle
*/
public static Concourse copyExistingConnection(Concourse concourse) {
return concourse.copyConnection();
}
/**
* The interface to use for all {@link #calculate() calculation} methods.
*/
private Calculator calculator = null;
/**
* Abort the current transaction and discard any changes that are currently
* staged.
* <p>
* After returning, the driver will return to {@code autocommit} mode and
* all subsequent changes will be committed immediately.
* </p>
* <p>
* Calling this method when the driver is not in {@code staging} mode is a
* no-op.
* </p>
*/
public abstract void abort();
/**
* Append {@code key} as {@code value} in a new record.
*
* @param key the field name
* @param value the value to add
* @return the new record id
*/
public abstract <T> long add(String key, T value);
/**
* Atomically append {@code key} as {@code value} in each of the
* {@code records} where it doesn't exist.
*
* @param key the field name
* @param value the value to add
* @param records a collection of record ids where an attempt is made to
* add the data
* @return a {@link Map} associating each record id to a boolean that
* indicates if the data was added
*/
public abstract <T> Map<Long, Boolean> add(String key, T value,
Collection<Long> records);
/**
* Append {@code key} as {@code value} in {@code record} if and only if it
* doesn't exist.
*
* @param key the field name
* @param value the value to add
* @param record the record id where an attempt is made to add the data
* @return a boolean that indicates if the data was added
*/
public abstract <T> boolean add(String key, T value, long record);
/**
* Return a list all the changes ever made to {@code record}.
*
* @param record the record id
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(long record);
/**
* Return a list all the changes made to {@code record} since {@code start}
* (inclusive).
*
* @param record the record id
* @param start an inclusive {@link Timestamp} of the oldest change that
* should possibly be included in the audit – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(long record, Timestamp start);
/**
* Return a list all the changes made to {@code record} between
* {@code start} (inclusive) and {@code end} (non-inclusive).
*
* @param record the record id
* @param start an inclusive {@link Timestamp} for the oldest change that
* should possibly be included in the audit – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @param end a non-inclusive {@link Timestamp} for the most recent change
* that should possibly be included in the audit – created from
* either a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(long record, Timestamp start,
Timestamp end);
/**
* Return a list all the changes ever made to the {@code key} field in
* {@code record}
*
* @param key the field name
* @param record the record id
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(String key, long record);
/**
* Return a list of all the changes made to the {@code key} field in
* {@code record} since {@code start} (inclusive).
*
* @param key the field name
* @param record the record id
* @param start an inclusive {@link Timestamp} for the oldest change that
* should possibly be included in the audit – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(String key, long record,
Timestamp start);
/**
* Return a list of all the changes made to the {@code key} field in
* {@code record} between {@code start} (inclusive) and {@code end}
* (non-inclusive).
*
* @param key the field name
* @param record the record id
* @param start an inclusive {@link Timestamp} for the oldest change that
* should possibly be included in the audit – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @param end a non-inclusive {@link Timestamp} for the most recent change
* that should possibly be included in the audit – created from
* either a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change
* to the respective description of the change
*/
public abstract Map<Timestamp, String> audit(String key, long record,
Timestamp start, Timestamp end);
/**
* Return a view of the values from all records that are currently stored
* for each of the {@code keys}.
*
* @param keys a collection of field names
* @return a {@link Map} associating each of the {@code keys} to a
* another {@link Map} associating each indexed value to the
* {@link Set} of records that contain that value in the {@code key}
* field
*/
public abstract Map<String, Map<Object, Set<Long>>> browse(
Collection<String> keys);
/**
* Return a view of the values from all records that were stored for each of
* the {@code keys} at {@code timestamp}.
*
* @param keys a collection of field names
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code keys} to a
* another {@link Map} associating each indexed value to the
* {@link Set} of records that contained that value in the
* {@code key} field at {@code timestamp}
*/
public abstract Map<String, Map<Object, Set<Long>>> browse(
Collection<String> keys, Timestamp timestamp);
/**
* Return a view of the values from all records that are currently stored
* for {@code key}.
*
* @param key the field name
* @return a {@link Map} associating each indexed value to the {@link Set}
* of records that contain that value in the {@code key} field
*/
public abstract Map<Object, Set<Long>> browse(String key);
/**
* Return a view of the values from all records that were stored for
* {@code key} at {@code timestamp}.
*
* @param key the field name
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each indexed value to the {@link Set}
* of records that contained that value in the {@code key} field at
* {@code timestamp}
*/
public abstract Map<Object, Set<Long>> browse(String key,
Timestamp timestamp);
/**
* Return a {@link Calculator} to use for calculations across data.
*
* @return a {@link Calculator}
*/
public Calculator calculate() {
if(calculator == null) {
calculator = new Calculator(this);
}
return calculator;
}
/**
* Perform the specified calculation {@code method} using the provided
* {@code args}.
*
* @param method the name of the calculation method in the
* {@link Calculator} interface
* @param args the args to pass to the method
* @return the result of the calculation
*/
public Object calculate(String method, Object... args) {
if(calculator == null) {
calculator = new Calculator(this);
}
return Reflection.call(calculator, method, args);
}
/**
* Return a time series that contains a snapshot of the values stored for
* {@code key} in {@code record} after every change made to the field.
*
* @param key the field name
* @param record the record id
* @return a {@link Map} associating the {@link Timestamp} of each change to
* the {@link Set} of values that were stored in the field after
* that change
*/
public abstract Map<Timestamp, Set<Object>> chronologize(String key,
long record);
/**
* Return a time series between {@code start} (inclusive) and the present
* that contains a snapshot of the values stored for {@code key} in
* {@code record} after every change made to the field during the time span.
*
* @param key the field name
* @param record the record id
* @param start the first possible {@link Timestamp} to include in the
* time series – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change to
* the {@link Set} of values that were stored in the field after
* that change
*/
public abstract Map<Timestamp, Set<Object>> chronologize(String key,
long record, Timestamp start);
/**
* Return a time series between {@code start} (inclusive) and {@code end}
* (non-inclusive) that contains a snapshot of the values stored for
* {@code key} in {@code record} after every change made to the field during
* the time span.
*
* @param key the field name
* @param record the record id
* @param start the first possible {@link Timestamp} to include in the
* time series – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @param end the {@link Timestamp} that should be greater than every
* timestamp in the time series – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating the {@link Timestamp} of each change to
* the {@link Set} of values that were stored in the field after
* that change
*/
public abstract Map<Timestamp, Set<Object>> chronologize(String key,
long record, Timestamp start, Timestamp end);
/**
* Atomically remove all the values stored for every key in each of the
* {@code records}.
*
* @param records a collection of record ids
*/
public abstract void clear(Collection<Long> records);
/**
* Atomically remove all the values stored for each of the {@code keys} in
* each of the {@code records}.
*
* @param keys a collection of field names
* @param records a collection of record ids.
*/
public abstract void clear(Collection<String> keys,
Collection<Long> records);
/**
* Atomically remove all the values stored for each of the {@code keys} in
* {@code record}.
*
* @param keys a collection of field names
* @param record the record id
*/
public abstract void clear(Collection<String> keys, long record);
/**
* Atomically remove all the values stored for every key in {@code record}.
*
* @param record the record id
*/
public abstract void clear(long record);
/**
* Atomically remove all the values stored for {@code key} in each of the
* {@code records}.
*
* @param key the field name
* @param records a collection of record ids
*/
public abstract void clear(String key, Collection<Long> records);
/**
* Atomically remove all the values stored for {@code key} in {@code record}
*
* @param key the field name
* @param record the record id
*/
public abstract void clear(String key, long record);
/**
* <p>
* <em>An alias for the {@link #exit()} method.</em>
* </p>
* {@inheritDoc}
*/
@Override
public final void close() {
exit();
}
/**
* Attempt to permanently commit any changes that are staged in a
* transaction and return {@code true} if and only if all the changes can be
* applied. Otherwise, returns {@code false} and all the changes are
* discarded.
* <p>
* After returning, the driver will return to {@code autocommit} mode and
* all subsequent changes will be committed immediately.
* </p>
* <p>
* This method will return {@code false} if it is called when the driver is
* not in {@code staging} mode.
* </p>
*
* @return {@code true} if all staged changes are committed, otherwise
* {@code false}
*/
public abstract boolean commit();
/**
* For each of the {@code records}, return all of the keys that have at
* least one value.
*
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to the
* {@link Set} of keys in that record
*/
public abstract Map<Long, Set<String>> describe(Collection<Long> records);
/**
* For each of the {@code records}, return all the keys that had at least
* one value at {@code timestamp}.
*
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to the
* {@link Set} of keys that were in that record at {@code timestamp}
*/
public abstract Map<Long, Set<String>> describe(Collection<Long> records,
Timestamp timestamp);
/**
* Return all the keys in {@code record} that have at least one value.
*
* @param record the record id
* @return the {@link Set} of keys in {@code record}
*/
public abstract Set<String> describe(long record);
/**
* Return all the keys in {@code record} that had at least one value at
* {@code timestamp}.
*
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the {@link Set} of keys that were in {@code record} at
* {@code timestamp}
*/
public abstract Set<String> describe(long record, Timestamp timestamp);
/**
* Return the <em>net</em> changes made to {@code record} since
* {@code start}.
* <p>
* If you begin with the state of the {@code record} at {@code start} and
* re-apply all the changes in the diff, you'll re-create the state of the
* {@code record} at the present.
* </p>
* <p>
* Unlike the {@link #audit(long, Timestamp) audit} method,
* {@link #diff(long, Timestamp) diff} does not necessarily reflect ALL the
* changes made to {@code record} during the time span.
* </p>
*
* @param record the record id
* @param start the base timestamp from which the diff is calculated
* @return a {@link Map} associating each key in the {@code record} to
* another {@link Map} associating a {@link Diff change
* description} to the {@link Set} of values that fit the
* description (i.e. <code>
* {"key": {ADDED: ["value1", "value2"], REMOVED: ["value3", "value4"]}}
* </code> )
*/
public abstract <T> Map<String, Map<Diff, Set<T>>> diff(long record,
Timestamp start);
/**
* Return the <em>net</em> changes made to {@code record} from {@code start}
* to {@code end}.
* <p>
* If you begin with the state of the {@code record} at {@code start} and
* re-apply all the changes in the diff, you'll re-create the state of the
* same {@code record} at {@code end}.
* </p>
* <p>
* Unlike the {@link #audit(long, Timestamp, Timestamp) audit} method,
* {@link #diff(long, Timestamp) diff} does not necessarily reflect ALL the
* changes made to {@code record} during the time span.
* </p>
*
* @param record the record id
* @param start the base timestamp from which the diff is calculated
* @param end the comparison timestamp to which the diff is calculated
* @return a {@link Map} associating each key in the {@code record} to
* another {@link Map} associating a {@link Diff change
* description} to the {@link Set} of values that fit the
* description (i.e. <code>
* {"key": {ADDED: ["value1", "value2"], REMOVED: ["value3", "value4"]}}
* </code> )
*/
public abstract <T> Map<String, Map<Diff, Set<T>>> diff(long record,
Timestamp start, Timestamp end);
/**
* List the net changes made to {@code key} in {@code record} since
* {@code start}.
* <p>
* If you begin with the state of the field at {@code start} and re-apply
* all the changes in the diff, you'll re-create the state of the same field
* at the present.
* </p>
*
* @param key the field name
* @param record the record id
* @param start the base timestamp from which the diff is calculated
* @return a {@link Map} associating a {@link Diff change
* description} to the {@link Set} of values that fit the
* description (i.e. <code>
* {ADDED: ["value1", "value2"], REMOVED: ["value3", "value4"]}
* </code> )
*/
public abstract <T> Map<Diff, Set<T>> diff(String key, long record,
Timestamp start);
/**
* Return the <em>net</em> changes made to {@code key} in {@code record}
* from {@code start} to {@code end}.
* <p>
* If you begin with the state of the field at {@code start} and re-apply
* all the changes in the diff, you'll re-create the state of the same field
* at {@code end}.
* </p>
*
* @param key the field name
* @param record the record id
* @param start the base timestamp from which the diff is calculated
* @param end the comparison timestamp to which the diff is calculated
* @return a {@link Map} associating a {@link Diff change
* description} to the {@link Set} of values that fit the
* description (i.e. <code>
* {ADDED: ["value1", "value2"], REMOVED: ["value3", "value4"]}
* </code> )
*/
public abstract <T> Map<Diff, Set<T>> diff(String key, long record,
Timestamp start, Timestamp end);
/**
* Return the <em>net</em> changes made to the {@code key} field across all
* records since {@code start}.
* <p>
* If you begin with the state of the inverted index for {@code key} at
* {@code start} and re-apply all the changes in the diff, you'll re-create
* the state of the same index at the present.
* </p>
* <p>
* Unlike the {@link #audit(String, long, Timestamp) audit} method,
* {@link #diff(long, Timestamp) diff} does not necessarily reflect ALL the
* changes made to {@code key} in {@code record} during the time span.
* </p>
*
* @param key the field name
* @param start the base timestamp from which the diff is calculated
* @return a {@link Map} associating each value stored for {@code key}
* across all records to another {@link Map} that associates a
* {@link Diff change description} to the {@link Set} of records
* where the description applies to that value in the {@code key}
* field (i.e. <code>
* {"value1": {ADDED: [1, 2], REMOVED: [3, 4]}}
* </code>)
*/
public abstract <T> Map<T, Map<Diff, Set<Long>>> diff(String key,
Timestamp start);
/**
* Return the <em>net</em> changes made to the {@code key} field across all
* records from {@code start} to {@code end}.
* <p>
* If you begin with the state of the inverted index for {@code key} at
* {@code start} and re-apply all the changes in the diff, you'll re-create
* the state of the same index at {@code end}.
* </p>
* <p>
* Unlike the {@link #audit(String, long, Timestamp, Timestamp) audit}
* method, {@link #diff(long, Timestamp) diff} does not necessarily return
* ALL the changes made to {@code key} in {@code record} during the time
* span.
* </p>
*
* @param key the field name
* @param start the base timestamp from which the diff is calculated
* @param end the comparison timestamp to which the diff is calculated
* @return a {@link Map} associating each value stored for {@code key}
* across all records to another {@link Map} that associates a
* {@link Diff change description} to the {@link Set} of records
* where the description applies to that value in the {@code key}
* field (i.e. <code>
* {"value1": {ADDED: [1, 2], REMOVED: [3, 4]}}
* </code>)
*/
public abstract <T> Map<T, Map<Diff, Set<Long>>> diff(String key,
Timestamp start, Timestamp end);
/**
* Terminate the client's session and close this connection.
*/
public abstract void exit();
/**
* Return the set of records that satisfy the {@link Criteria criteria}.
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return the records that match the {@code criteria}
*/
public abstract Set<Long> find(Criteria criteria);
/**
* Return the set of records that satisfy the {@code criteria}.
* <p>
* This method is syntactic sugar for {@link #find(Criteria)}. The only
* difference is that this method takes a in-process {@link Criteria}
* building sequence for convenience.
* </p>
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired records
* @return the records that match the {@code criteria}
*/
public abstract Set<Long> find(Object criteria); // this method exists in
// case the caller
// forgets
// to called #build() on
// the CriteriaBuilder
/**
* Return the set of records that satisfy the {@code ccl} filter.
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return the records that match the criteria
*/
public abstract Set<Long> find(String ccl);
/**
* Return the set of records where {@code key} {@link Operator#EQUALS
* equals} {@code value}.
* <p>
* This method is a shortcut for calling
* {@link #find(String, Operator, Object)} with {@link Operator#EQUALS}.
* </p>
*
* @param key the field name
* @param value the value that must exist in the {@code key} field for the
* record to match
* @return the records where {@code key} = {@code value}
*/
public abstract Set<Long> find(String key, Object value);
/**
* Return the set of records where {@code key} was {@link Operator#EQUALS
* equal} to {@code value} at {@code timestamp}.
* <p>
* This method is a shortcut for calling
* {@link #find(String, Operator, Object, Timestamp)} with
* {@link Operator#EQUALS}.
* </p>
*
* @param key the field name
* @param value the value that must exist in the {@code key} field for the
* record to match
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use when checking for matches – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the records where {@code key} was equal to {@code value} at
* {@code timestamp}
*/
public abstract Set<Long> find(String key, Object value,
Timestamp timestamp);
/**
* Return the set of {@code records} where the {@code key} field contains at
* least one value that satisfies the {@code operator} in relation to the
* {@code value}.
*
* @param key the field name
* @param operator the {@link Operator} to use when comparing the specified
* {@code value} to those stored across the {@code key} field
* while determining which records are matches
* @param value the comparison value for the {@code operator}
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, Operator operator, Object value);
/**
* Return the set of {@code records} where the {@code key} field contains at
* least one value that satisfies the {@code operator} in relation to
* {@code value} and {@code value2}.
*
* @param key the field name
* @param operator the {@link Operator} to use when comparing the specified
* values to those stored across the {@code key} field while
* determining which records are matches
* @param value the first comparison value for the {@code operator}
* @param value2 the second comparison value for the {@code operator}
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, Operator operator, Object value,
Object value2);
/**
* Return the set of {@code records} where the {@code key} field contained
* at least one value at {@code timestamp} that satisfies the
* {@code operator} in relation to {@code value} and {@code value2}.
*
* @param key the field name
* @param operator the {@link Operator} to use when comparing the specified
* values to those stored across the {@code key} field while
* determining which records are matches
* @param value the first comparison value for the {@code operator}
* @param value2 the second comparison value for the {@code operator}
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use when checking for matches – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, Operator operator, Object value,
Object value2, Timestamp timestamp);
/**
* Return the set of {@code records} where the {@code key} field contained
* at least one value at {@timestamp} that satisfies the {@code operator} in
* relation to the {@code value}.
*
* @param key the field name
* @param operator the {@link Operator} to use when comparing the specified
* {@code value} to those stored across the {@code key} field
* while determining which records are matches
* @param value the comparison value for the {@code operator}
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use when checking for matches – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, Operator operator, Object value,
Timestamp timestamp);
/**
* Return the set of {@code records} where the {@code key} field contains at
* least one value that satisfies the {@code operator} in relation to the
* {@code value}.
*
* @param key the field name
* @param operator a valid {@link Convert#stringToOperator(String)
* description} of an {@link Operator} to use when comparing the
* specified {@code value} to those stored across the {@code key}
* field while determining which records are matches
* @param value the comparison value for the {@code operator}
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, String operator, Object value);
/**
* Return the set of {@code records} where the {@code key} field contains at
* least one value that satisfies the {@code operator} in relation to
* {@code value} and {@code value2}.
*
* @param key the field name
* @param operator a valid {@link Convert#stringToOperator(String)
* description} of an {@link Operator} to use when comparing the
* specified {@code value} to those stored across the {@code key}
* field while determining which records are matches
* @param value the first comparison value for the {@code operator}
* @param value2 the second comparison value for the {@code operator}
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, String operator, Object value,
Object value2);
/**
* Return the set of {@code records} where the {@code key} field contained
* at least one value at {@code timestamp} that satisfies the
* {@code operator} in relation to {@code value} and {@code value2}.
*
* @param key the field name
* @param operator a valid {@link Convert#stringToOperator(String)
* description} of an {@link Operator} to use when comparing the
* specified {@code value} to those stored across the {@code key}
* field while determining which records are matches
* @param value the first comparison value for the {@code operator}
* @param value2 the second comparison value for the {@code operator}
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use when checking for matches – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, String operator, Object value,
Object value2, Timestamp timestamp);
/**
* Return the set of {@code records} where the {@code key} field contained
* at least one value at {@code timestamp} that satisfies the
* {@code operator} in relation to the {@code value}.
*
* @param key the field name
* @param operator a valid {@link Convert#stringToOperator(String)
* description} of an {@link Operator} to use when comparing the
* specified {@code value} to those stored across the {@code key}
* field while determining which records are matches
* @param value the comparison value for the {@code operator}
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use when checking for matches – created from either
* a {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the records that match the criteria
*/
public abstract Set<Long> find(String key, String operator, Object value,
Timestamp timestamp);
/**
* Return the unique record where {@code key} {@link Operator#EQUALS equals}
* {@code value}, or throw a {@link DuplicateEntryException} if multiple
* records match the condition. If no record matches,
* {@link #add(String, Object) add} {@code key} as {@code value} into an new
* record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only adds data if that condition isn't
* currently satisfied.
* </p>
*
* @param key the field name
* @param value the value that must exist in the {@code key} field of a
* single record for that record to match or the value that is
* added to the {@code key} field in a new record if no existing
* record matches the condition
* @return the unique record where {@code key} = {@code value}, if one exist
* or the record where the {@code key} as {@code value} is added
* @throws DuplicateEntryException
*/
public abstract <T> long findOrAdd(String key, T value)
throws DuplicateEntryException;
/**
* Return the unique record that matches the {@code criteria}, if
* one exist or throw a {@link DuplicateEntryException} if multiple records
* match. If no record matches, {@link #insert(Map)} the {@code data} into a
* new record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
* <p>
* This method is syntactic sugar for {@link #findOrInsert(Criteria, Map)}.
* The only difference is that this method takes a in-process
* {@link Criteria} building sequence for convenience.
* </p>
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired record
* @param data a {@link Map} with key/value associations to insert into the
* new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(BuildableState criteria,
Map<String, Object> data) throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(criteria, json);
}
/**
* Return the unique record that matches the {@code criteria}, if one exist
* or throw a {@link DuplicateEntryException} if multiple records match. If
* no record matches, {@link #insert(Multimap)} the {@code data} into a new
* record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
* <p>
* This method is syntactic sugar for
* {@link #findOrInsert(Criteria, Multimap)}. The only difference is that
* this method takes a in-process {@link Criteria} building sequence for
* convenience.
* </p>
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* record
* @param data a {@link Multimap} with key/value associations to insert into
* the new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(BuildableState criteria,
Multimap<String, Object> data) throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(criteria, json);
}
/**
* Return the unique record that matches the {@code criteria}, if one exist
* or throw a {@link DuplicateEntryException} if multiple records match. If
* no record matches, {@link #insert(String)} the {@code json} into a new
* record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* This method is syntactic sugar for
* {@link #findOrInsert(Criteria, String)}. The only difference is that this
* method takes a in-process {@link Criteria} building sequence for
* convenience.
* </p>
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* record
* @param json a JSON blob describing a single object
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public long findOrInsert(BuildableState criteria, String json)
throws DuplicateEntryException {
return findOrInsert(criteria.build(), json);
}
/**
* Return the unique record that matches the {@code criteria}, if one exist
* or throw a {@link DuplicateEntryException} if multiple records match. If
* no record matches, {@link #insert(Map)} the {@code data} into a
* new record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired record
* @param data a {@link Map} with key/value associations to insert into the
* new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(Criteria criteria, Map<String, Object> data)
throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(criteria, json);
}
/**
* Return the unique record that matches the {@code criteria}, if one exist
* or throw a {@link DuplicateEntryException} if multiple records match. If
* no record matches, {@link #insert(Multimap)} the {@code data} into a new
* record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired record
* @param data a {@link Multimap} with key/value associations to insert into
* the new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(Criteria criteria,
Multimap<String, Object> data) throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(criteria, json);
}
/**
* Return the unique record that matches the {@code criteria}, if one exist
* or throw a {@link DuplicateEntryException} if multiple records match. If
* no record matches, {@link #insert(String)} the {@code json} into a new
* record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired record
* @param data a JSON blob describing a single object
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public abstract long findOrInsert(Criteria criteria, String json)
throws DuplicateEntryException;
/**
* Return the unique record that matches the {@code ccl} filter, if one
* exist or throw a {@link DuplicateEntryException} if multiple records
* match. If no record matches, {@link #insert(Map)} the {@code data} into a
* new record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param data a {@link Map} with key/value associations to insert into the
* new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(String ccl, Map<String, Object> data)
throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(ccl, json);
}
/**
* Return the unique record that matches the {@code ccl} filter, if one
* exist or throw a {@link DuplicateEntryException} if multiple records
* match. If no record matches, {@link #insert(Multimap)} the {@code data}
* into a new record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param data a {@link Multimap} with key/value associations to insert into
* the new record
* @return the unique record that matches {@code criteria}, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public final long findOrInsert(String ccl, Multimap<String, Object> data)
throws DuplicateEntryException {
String json = Convert.mapToJson(data);
return findOrInsert(ccl, json);
}
/**
* Return the unique record that matches the {@code ccl} filter, if one
* exist or throw a {@link DuplicateEntryException} if multiple records
* match. If no record matches, {@link #insert(String)} the {@code json}
* into a new record and return the id.
* <p>
* This method can be used to simulate a unique index because it atomically
* checks for a condition and only inserts data if that condition isn't
* currently satisfied.
* </p>
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param json a JSON blob describing a single object
* @return the unique record that matches {@code ccl} string, if one exist
* or the record where the {@code json} data is inserted
* @throws DuplicateEntryException
*/
public abstract long findOrInsert(String ccl, String json)
throws DuplicateEntryException;
/**
* For each of the {@code keys} in each of the {@code records}, return the
* stored value that was most recently added.
*
* @param keys a collection of field names
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Collection<Long> records);
/**
* For each of the {@code keys} in each of the {@code records}, return the
* stored value that was most recently added at {@code timestamp}.
*
* @param keys a collection of field names
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Collection<Long> records, Timestamp timestamp);
/**
* For each of the {@code keys} in every record that matches the
* {@code criteria}, return the stored value that was most recently
* added.
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Criteria criteria);
/**
* For each of the {@code keys} in every record that matches the
* {@code criteria}, return the stored value that was most recently
* added at {@code timestamp}.
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Criteria criteria, Timestamp timestamp);
/**
* For each of the {@code keys} in {@code record}, return the stored value
* that was most recently added.
*
* @param keys a collection of field names
* @param record the record id
* @return a {@link Map} associating each of the {@code keys} to the
* freshest value in the field
*/
public abstract <T> Map<String, T> get(Collection<String> keys,
long record);
/**
* For each of the {@code keys} in {@code record}, return the stored value
* that was most recently added at {@code timestamp}.
*
* @param keys a collection of field names
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code keys} to the
* freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<String, T> get(Collection<String> keys, long record,
Timestamp timestamp);
/**
* For each of the {@code keys} in every record that matches the
* {@code criteria}, return the stored value that was most recently
* added.
* <p>
* This method is syntactic sugar for {@link #get(Collection, Criteria)}.
* The only difference is that this method takes a in-process
* {@link Criteria} building sequence for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Object criteria);
/**
* For each of the {@code keys} in every record that matches the
* {@code criteria}, return the stored value that was most recently
* added at {@code timestamp}.
* <p>
* This method is syntactic sugar for
* {@link #get(Collection, Criteria, Timestamp)}. The only difference is
* that this method takes a in-process {@link Criteria} building sequence
* for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
Object criteria, Timestamp timestamp);
/**
* For each of the {@code keys} in every record that matches the {@code ccl}
* filter, return the stored value that was most recently added.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
String ccl);
/**
* For each of the {@code keys} in every record that matches the {@code ccl}
* filter, return the stored value that was most recently added at
* {@code timestamp}.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Collection<String> keys,
String ccl, Timestamp timestamp);
/**
* For every key in every record that matches the {@code criteria}, return
* the stored value that was most recently added.
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Criteria criteria);
/**
* For every key in every record that matches the {@code criteria}, return
* the stored value that was most recently added at {@code timestamp} .
*
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Criteria criteria,
Timestamp timestamp);
/**
* For every key in every record that matches the {@code criteria}, return
* the stored value that was most recently added.
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(Object criteria);
/**
* For every key in every record that matches the {@code criteria}, return
* the stored value that was most recently added at {@code timestamp}.
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, T>> get(Object criteria,
Timestamp timestamp);
/**
* For every key in every record that matches the {@code ccl} filter, return
* the stored value that was most recently added.
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(String ccl);
/**
* For each of the {@code records}, return the stored value in the
* {@code key} field that was most recently added.
*
* @param key the field name
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to the
* freshest value in the {@code key} field
*/
public abstract <T> Map<Long, T> get(String key, Collection<Long> records);
/**
* For each of the {@code records}, return the stored value in the
* {@code key} field that was most recently added at {@code timestamp}
*
* @param key the field name
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to the
* freshest value in the {@code key} field at {@code timestamp}
*/
public abstract <T> Map<Long, T> get(String key, Collection<Long> records,
Timestamp timestamp);
/**
* For every record that matches the {@code criteria}, return the stored
* value in the {@code key} field that was most recently added.
*
* @param key the field name
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return a {@link Map} associating each of the matching records to the
* freshest value in the {@code key} field
*/
public abstract <T> Map<Long, T> get(String key, Criteria criteria);
/**
* For every record that matches the {@code criteria}, return the
* stored value in the {@code key} field that was most recently added at
* {@code timestamp}.
*
* @param key the field name
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to the
* freshest value in the {@code key} field
*/
public abstract <T> Map<Long, T> get(String key, Criteria criteria,
Timestamp timestamp);
/**
* Return the stored value that was most recently added for {@code key} in
* {@code record}. If the field is empty, return {@code null}.
*
* @param key the field name
* @param record the record id
* @return the freshest value in the field
*/
@Nullable
public abstract <T> T get(String key, long record);
/**
* Return the stored value that was most recently added for {@code key} in
* {@code record} at {@code timestamp}. If the field was empty at
* {@code timestamp}, return {@code null}.
*
* @param key the field name
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return the freshest value in the field at {@code timestamp}
*/
@Nullable
public abstract <T> T get(String key, long record, Timestamp timestamp);
/**
* For every record that matches the {@code criteria}, return the stored
* value in the {@code key} field that was most recently added.
* <p>
* This method is syntactic sugar for {@link #get(String, Criteria)}. The
* only difference is that this method takes a in-process {@link Criteria}
* building sequence for convenience.
* </p>
*
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field
*/
public abstract <T> Map<Long, T> get(String key, Object criteria);
/**
* For every record that matches the {@code criteria}, return the
* stored value in the {@code key} field that was most recently added at
* {@code timestamp}.
* <p>
* This method is syntactic sugar for
* {@link #get(String, Criteria, Timestamp)}. The only difference is that
* this method takes a in-process {@link Criteria} building sequence for
* convenience.
* </p>
*
* @param key the field name
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to the
* freshest value in the {@code key} field
*/
public abstract <T> Map<Long, T> get(String key, Object criteria,
Timestamp timestamp);
/**
* For every record that matches the {@code ccl} filter, return the
* stored value in the {@code key} field that was most recently added.
* <p>
* This method is syntactic sugar for {@link #get(String, Criteria)}. The
* only difference is that this method takes a in-process {@link Criteria}
* building sequence for convenience.
* </p>
*
* @param key the field name
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the matching records to the
* freshest value in the {@code key} field
*/
public abstract <T> Map<Long, T> get(String key, String ccl);
/**
* For every record that matches the {@code ccl} filter, return the
* stored value in the {@code key} field that was most recently added at
* {@code timestamp}.
* <p>
* This method is syntactic sugar for
* {@link #get(String, Criteria, Timestamp)}. The only difference is that
* this method takes a in-process {@link Criteria} building sequence for
* convenience.
* </p>
*
* @param key the field name
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to the
* freshest value in the {@code key} field at {@code timestamp}
*/
public abstract <T> Map<Long, T> get(String key, String ccl,
Timestamp timestamp);
/**
* For every key in every record that matches the {@code ccl} filter,
* return the stored value that was most recently added.
*
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the record's keys to the freshest
* value in the field
*/
public abstract <T> Map<Long, Map<String, T>> get(String ccl,
Timestamp timestamp);
/**
* Return the name of the connected environment.
*
* @return the server environment to which this client is connected
*/
public abstract String getServerEnvironment();
/**
* Return the version of the connected server.
*
* @return the server version
*/
public abstract String getServerVersion();
/**
* Atomically insert the key/value associations from each of the
* {@link Multimap maps} in {@code data} into new and distinct records.
* <p>
* Each of the values in each map in {@code data} must be a primitive or one
* dimensional object (e.g. no nested {@link Map maps} or {@link Multimap
* multimaps}).
* </p>
*
* @param data a {@link List} of {@link Multimap maps}, each with key/value
* associations to insert into a new record
* @return a {@link Set} containing the ids of the new records where the
* maps in {@code data} were inserted, respectively
*/
public final Set<Long> insert(Collection<Multimap<String, Object>> data) {
String json = Convert.mapsToJson(data);
return insert(json);
}
/**
* Atomically insert the key/value associations from {@link Map data} into a
* new record.
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Map} with key/value associations to insert into the
* new record
* @return the id of the new record where the {@code data} was inserted
*/
public final long insert(Map<String, Object> data) {
String json = Convert.mapToJson(data);
return insert(json).iterator().next();
}
/**
* Atomically insert the key/value associations from {@link Map data} into
* each of the {@code records}, if possible.
* <p>
* An insert will fail for a given record if any of the key/value
* associations in {@code data} currently exist in that record (e.g.
* {@link #add(String, Object, long) adding} the key/value association would
* fail).
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Map} with key/value associations to insert into each
* of the {@code records}
* @param records a collection of ids for records where the {@code data}
* should attempt to be inserted
* @return a {@link Map} associating each record id to a boolean that
* indicates if the {@code data} was successfully inserted in that
* record
*/
public final Map<Long, Boolean> insert(Map<String, Object> data,
Collection<Long> records) {
String json = Convert.mapToJson(data);
return insert(json, records);
}
/**
* Atomically insert the key/value associations from {@link Map data} into
* {@code record}, if possible.
* <p>
* The insert will fail if any of the key/value associations in {@code data}
* currently exist in {@code record} (e.g.
* {@link #add(String, Object, long) adding} the key/value association would
* fail).
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Map} with key/value associations to insert into
* {@code record}
* @param record the record id
* @return {@code true} if all of the {@code data} is successfully inserted
* into {@code record}, otherwise {@code false}
*/
public final boolean insert(Map<String, Object> data, long record) {
String json = Convert.mapToJson(data);
return insert(json, record);
}
/**
* Atomically insert the key/value associations from {@code Multimap data}
* into a new record.
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Multimap} with key/value associations to insert into
* the new record
* @return the id of the new record where the {@code data} was inserted
*/
public final long insert(Multimap<String, Object> data) {
String json = Convert.mapToJson(data);
return insert(json).iterator().next();
}
/**
* Atomically insert the key/value associations from {@code Multimap data}
* into each of the {@code records}, if possible.
* <p>
* An insert will fail for a given record if any of the key/value
* associations in {@code data} currently exist in that record (e.g.
* {@link #add(String, Object, long) adding} the key/value association would
* fail).
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Multimap} with key/value associations to insert into
* each of the {@code records}
* @param records a collection of ids for records where the {@code data}
* should attempt to be inserted
* @return a {@link Map} associating each record id to a boolean that
* indicates if the {@code data} was successfully inserted in that
* record
*/
public final Map<Long, Boolean> insert(Multimap<String, Object> data,
Collection<Long> records) {
String json = Convert.mapToJson(data);
return insert(json, records);
}
/**
* Atomically insert the key/value associations in {@link Multimap data}
* into {@code record}, if possible.
* <p>
* The insert will fail if any of the key/value associations in {@code data}
* currently exist in {@code record} (e.g.
* {@link #add(String, Object, long) adding} the key/value association would
* fail).
* </p>
* <p>
* Each of the values in {@code data} must be a primitive or one dimensional
* object (e.g. no nested {@link Map maps} or {@link Multimap multimaps}).
* </p>
*
* @param data a {@link Multimap} with key/value associations to insert into
* {@code record}
* @param record the record id
* @return {@code true} if all of the {@code data} is successfully inserted
* into {@code record}, otherwise {@code false}
*/
public final boolean insert(Multimap<String, Object> data, long record) {
String json = Convert.mapToJson(data);
return insert(json, record);
}
/**
* Atomically insert the key/value associations from the {@code json} string
* into as many new records as necessary.
* <p>
* If the {@code json} string contains a top-level array (of objects), this
* method will insert each of the objects in a new and distinct record. The
* {@link Set} that is returned will contain the ids of all those records.
* On the other hand, if the {@code json} string contains a single top-level
* object, this method will insert that object in a single new record. The
* {@link Set} that is returned will only contain the id of that record.
* </p>
* <p>
* Regardless of whether the top-level element is an object or an array,
* each object in the {@code json} string contains one or more keys, each of
* which maps to a JSON primitive or an array of JSON primitives (e.g. no
* nested objects or arrays).
* </p>
*
* @param json a valid json string with either a top-level object or array
* @return a {@link Set} that contains one or more records ids where the
* objects in {@code json} are inserted, respectively
*/
public abstract Set<Long> insert(String json);
/**
* Atomically insert the key/value associations from the {@code json} object
* into each of the {@code records}, if possible.
* <p>
* An insert will fail for a given record if any of the key/value
* associations in the {@code json} object currently exist in that record
* (e.g. {@link #add(String, Object, long) adding} the key/value association
* would fail).
* </p>
* <p>
* The {@code json} must contain a top-level object that contains one or
* more keys, each of which maps to a JSON primitive or an array of JSON
* primitives (e.g. no nested objects or arrays).
* </p>
*
* @param json a valid json string containing a top-level object
* @param records a collection of record ids
* @return a {@link Map} associating each record id to a boolean that
* indicates if the {@code json} was successfully inserted in that
* record
*/
public abstract Map<Long, Boolean> insert(String json,
Collection<Long> records);
/**
* Atomically insert the key/value associations from the {@code json} object
* into {@code record}, if possible.
* <p>
* The insert will fail if any of the key/value associations in the
* {@code json} object currently exist in {@code record} (e.g.
* {@link #add(String, Object, long)
* adding} the key/value association would fail).
* </p>
* <p>
* The {@code json} must contain a JSON object that contains one or more
* keys, each of which maps to a JSON primitive or an array of JSON
* primitives.
* </p>
*
* @param json json a valid json string containing a top-level object
* @param record the record id
* @return {@code true} if the {@code json} is inserted into {@code record}
*/
public abstract boolean insert(String json, long record);
/**
* Return all the records that have current or historical data.
*
* @return a {@link Set} containing the ids of records that have current or
* historical data
*/
public abstract Set<Long> inventory();
/**
* Invoke {@code method} using {@code args} within the plugin identified by
* {@code id}.
*
* <p>
* There must be a class named {@code id} available in Concourse Server via
* a plugin distribution. The {@code method} must also be accessible within
* the class.
* </p>
* <p>
* If the plugin throws any {@link Exception}, it'll be re-thrown here as a
* {@link RuntimeException}.
* </p>
*
* @param id the fully qualified name of the plugin class (e.g.
* com.cinchapi.plugin.PluginClass)
* @param method the name of the method within the {@code pluginClass}
* @param args the arguments to pass to the {@code method}
* @return the result returned from the plugin
*/
public abstract <T> T invokePlugin(String id, String method,
Object... args);
/**
* Atomically dump the data in each of the {@code records} as a JSON array
* of objects.
*
* @param records a collection of record ids
* @return a JSON array of objects, each of which contains the data in the
* one of the {@code records}, respectively
*/
public abstract String jsonify(Collection<Long> records);
/**
* Atomically dump the data in each of the {@code records} as a JSON array
* of objects and optionally include a special {@code identifier} key that
* contains the record id for each of the dumped objects.
*
* @param records a collection of record ids
* @param identifier a boolean that indicates whether to include a special
* key ({@link Constants#JSON_RESERVED_IDENTIFIER_NAME}) that
* maps to the record id in each of the dumped objects
* @return a JSON array of objects, each of which contains the data in the
* one of the {@code records}, respectively
*/
public abstract String jsonify(Collection<Long> records,
boolean identifier);
/**
* Atomically dump the data in each of the {@code records} at
* {@code timestamp} as a JSON array of objects.
*
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a JSON array of objects, each of which contains the data in the
* one of the {@code records} at {@code timestamp}, respectively
*/
public abstract String jsonify(Collection<Long> records,
Timestamp timestamp);
/**
* Atomically dump the data in each of the {@code records} at
* {@code timestamp} as a JSON array of objects and optionally include a
* special {@code identifier} key that contains the record id for each of
* the dumped objects.
*
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @param identifier a boolean that indicates whether to include a special
* key ({@link Constants#JSON_RESERVED_IDENTIFIER_NAME}) that
* maps to the record id in each of the dumped objects
* @return a JSON array of objects, each of which contains the data in the
* one of the {@code records} at {@code timestamp}, respectively
*/
public abstract String jsonify(Collection<Long> records,
Timestamp timestamp, boolean identifier);
/**
* Atomically dump all the data in {@code record} as a JSON object.
*
* @param record the record id
* @return a JSON object that contains all the data in {@code record}
*/
public abstract String jsonify(long record);
/**
* Atomically dump all the data in {@code record} as a JSON object and
* optionally include a special {@code identifier} key that contains the
* record id.
*
* @param record the record id
* @param identifier a boolean that indicates whether to include a special
* key ({@link Constants#JSON_RESERVED_IDENTIFIER_NAME}) that
* maps to the record id in each of the dumped objects
* @return a JSON object that contains all the data in {@code record}
*/
public abstract String jsonify(long record, boolean identifier);
/**
* Atomically dump all the data in {@code record} at {@code timestamp} as a
* JSON object.
*
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a JSON object that contains all the data in {@code record} at
* {@code timestamp}
*/
public abstract String jsonify(long record, Timestamp timestamp);
/**
* Atomically dump all the data in {@code record} at {@code timestamp} as a
* JSON object and optionally include a special {@code identifier} key that
* contains the record id.
*
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @param identifier a boolean that indicates whether to include a special
* key ({@link Constants#JSON_RESERVED_IDENTIFIER_NAME}) that
* maps to the record id in each of the dumped objects
* @return a JSON object that contains all the data in {@code record} at
* {@code timestamp}
*/
public abstract String jsonify(long record, Timestamp timestamp,
boolean identifier);
/**
* Append links from {@code key} in {@code source} to each of the
* {@code destinations}.
*
* @param key the field name
* @param destinations a collection of ids for the records where each of the
* links points, respectively
* @param source the id of the record where each of the links originate
* @return a {@link Map} associating the ids for each of the
* {@code destinations} to a boolean that indicates whether the link
* was successfully added
*/
public abstract Map<Long, Boolean> link(String key,
Collection<Long> destinations, long source);
/**
* Append a link from {@code key} in {@code source} to {@code destination}.
*
* @param key the field name
* @param destination the id of the record where the link points
* @param source the id of the record where the link originates
* @return {@code true} if the link is added
*/
public abstract boolean link(String key, long destination, long source);
/**
* Atomically check to see if each of the {@code records} currently contains
* any data.
*
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to a
* boolean that indicates whether that record currently contains any
* data.
*/
public abstract Map<Long, Boolean> ping(Collection<Long> records);
/**
* Check to see if {@code record} currently contains any data.
*
* @param record the record id
* @return {@code true} if {@code record} currently contains any data,
* otherwise {@code false}
*/
public abstract boolean ping(long record);
/**
* Make the necessary changes to the data stored for {@code key} in
* {@code record} so that it contains the exact same {@code values} as the
* specified collection.
*
* @param key the field name
* @param record the record id
* @param values the collection of values that should be exactly what is
* contained in the field after this method executes
*/
@Incubating
public abstract <T> void reconcile(String key, long record,
Collection<T> values);
/**
* Make the necessary changes to the data stored for {@code key} in
* {@code record} so that it contains the exact same {@code values} as the
* specified array.
*
* @param key the field name
* @param record the record id
* @param values the array of values that should be exactly what is
* contained in the field after this method executes
*/
@SuppressWarnings("unchecked")
@Incubating
public final <T> void reconcile(String key, long record, T... values) {
reconcile(key, record, Sets.newHashSet(values));
}
/**
* Atomically remove {@code key} as {@code value} from each of the
* {@code records} where it currently exists.
*
* @param key the field name
* @param value the value to remove
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to a
* boolean that indicates whether the data was removed
*/
public abstract <T> Map<Long, Boolean> remove(String key, T value,
Collection<Long> records);
/**
* Remove {@code key} as {@code value} from {@code record} if it currently
* exists.
*
* @param key the field name
* @param value the value to remove
* @param record the record id
* @return {@code true} if the data is removed
*/
public abstract <T> boolean remove(String key, T value, long record);
/**
* Atomically revert each of the {@code keys} in each of the {@code records}
* to their state at {@code timestamp} by creating new revisions that undo
* the net changes that have occurred since {@code timestamp}.
*
* @param keys a collection of field names
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
*/
public abstract void revert(Collection<String> keys,
Collection<Long> records, Timestamp timestamp);
/**
* Atomically revert each of the {@code keys} in {@code record} to their
* state at {@code timestamp} by creating new revisions that undo the net
* changes that have occurred since {@code timestamp}.
*
* @param keys a collection of field names
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
*/
public abstract void revert(Collection<String> keys, long record,
Timestamp timestamp);
/**
* Atomically revert {@code key} in each of the {@code records} to its state
* at {@code timestamp} by creating new revisions that undo the net
* changes that have occurred since {@code timestamp}.
*
* @param key the field name
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
*/
public abstract void revert(String key, Collection<Long> records,
Timestamp timestamp);
/**
* Atomically revert {@code key} in {@code record} to its state at
* {@code timestamp} by creating new revisions that undo the net
* changes that have occurred since {@code timestamp}.
*
* @param key the field name
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
*/
public abstract void revert(String key, long record, Timestamp timestamp);
/**
* Perform a full text search for {@code query} against the {@code key}
* field and return the records that contain a {@link String} or {@link Tag}
* value that matches.
*
* @param key
* @param query
* @return a {@link Set} of ids for records that match the search query
*/
public abstract Set<Long> search(String key, String query);
/**
* Return all the data that is currently stored in each of the
* {@code records}.
*
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating every key in that record to a {@link Set}
* containing all the values stored in the respective field
*/
public abstract Map<Long, Map<String, Set<Object>>> select(
Collection<Long> records);
/**
* Return all the data that was stored in each of the {@code records} at
* {@code timestamp}.
*
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating every key in that record at
* {@code timestamp} to a {@link Set} containing all the values
* stored in the respective field at {@code timestamp}
*/
public abstract Map<Long, Map<String, Set<Object>>> select(
Collection<Long> records, Timestamp timestamp);
/**
* Return all the values stored for each of the {@code keys} in each of the
* {@code records}.
*
* @param keys a collection of field names
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating each of the {@code keys} to a {@link Set}
* containing all the values stored in the respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Collection<Long> records);
/**
* Return all the values stored for each of the {@code keys} in each of the
* {@code records} at {@code timestamp}.
*
* @param keys a collection of field names
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to another
* {@link Map} associating each of the {@code keys} to a {@link Set}
* containing all the values stored in the respective field at
* {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Collection<Long> records,
Timestamp timestamp);
/**
* Return all the values stored for each of the {@code keys} in every record
* that matches the {@code criteria}.
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a
* well-formed filter for the desired records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Criteria criteria);
/**
* Return all the values stored for each of the {@code keys} at
* {@code timestamp} in every record that matches the {@code criteria}
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a
* well-formed filter for the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Criteria criteria, Timestamp timestamp);
/**
* Return all the values stored for each of the {@code keys} in
* {@code record}.
*
* @param keys a collection of field names
* @param record the record id
* @return a {@link Map} associating each of the {@code keys} to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract <T> Map<String, Set<T>> select(Collection<String> keys,
long record);
/**
* Return all the values stored for each of the {@code keys} in
* {@code record} at {@code timestamp}.
*
* @param keys a collection of field names
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code keys} to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract <T> Map<String, Set<T>> select(Collection<String> keys,
long record, Timestamp timestamp);
/**
* Return all the values stored for each of the {@code keys} in every record
* that matches the {@code criteria}.
* <p>
* This method is syntactic sugar for {@link #select(Collection, Criteria)}.
* The only difference is that this method takes a in-process
* {@link Criteria} building sequence for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Object criteria);
/**
* Return all the values stored for each of the {@code keys} at
* {@code timestamp} in every record that matches the {@code criteria}.
* <p>
* This method is syntactic sugar for
* {@link #select(Collection, Criteria, Timestamp)}. The only difference is
* that this method takes a in-process {@link Criteria} building sequence
* for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, Object criteria, Timestamp timestamp);
/**
* Return all the values stored for each of the {@code keys} in every record
* that matches the {@code ccl} filter.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, String ccl);
/**
* Return all the values stored for each of the {@code keys} at
* {@code timestamp} in every record that matches the {@code ccl} filter.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Collection<String> keys, String ccl, Timestamp timestamp);
/**
* Return all the data from every record that matches {@code criteria}.
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(
Criteria criteria);
/**
* Return all the data at {@code timestamp} from every record that
* matches the {@code criteria}.
*
* @param keys a collection of field names
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(Criteria criteria,
Timestamp timestamp);
/**
* Return all the data from {@code record}.
*
* @param record the record id
* @return a {@link Map} associating each key in {@code record} to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract Map<String, Set<Object>> select(long record);
/**
* Return all the data from {@code record} at {@code timestamp}.
*
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each key in {@code record} to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract Map<String, Set<Object>> select(long record,
Timestamp timestamp);
/**
* Return all the data from every record that matches {@code criteria}.
* <p>
* This method is syntactic sugar for {@link #select(Criteria)}. The only
* difference is that this method takes a in-process {@link Criteria}
* building sequence for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(Object criteria);
/**
* Return all the data at {@code timestamp} from every record that
* matches the {@code criteria}.
* <p>
* This method is syntactic sugar for {@link #select(Criteria, Timestamp)}.
* The only difference is that this method takes a in-process
* {@link Criteria} building sequence for convenience.
* </p>
*
* @param keys a collection of field names
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(Object criteria,
Timestamp timestamp);
/**
* Return all the data from every record that matches {@code ccl} filter.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(String ccl);
/**
* Return all values stored for {@code key} in each of the {@code records}.
*
* @param key the field name
* @param records a collection of record ids
* @return a {@link Map} associating each of the {@code records} to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract <T> Map<Long, Set<T>> select(String key,
Collection<Long> records);
/**
* Return all values stored for {@code key} in each of the {@code records}
* at {@code timestamp}.
*
* @param key the field name
* @param records a collection of record ids
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the {@code records} to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract <T> Map<Long, Set<T>> select(String key,
Collection<Long> records, Timestamp timestamp);
/**
* Return all the values stored for {@code key} in every record that
* matches the {@code criteria}.
*
* @param key the field name
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @return a {@link Map} associating each of the matching records to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract <T> Map<Long, Set<T>> select(String key, Criteria criteria);
/**
* Return all the values stored for {@code key} at {@code timestamp} in
* every record that matches the {@code criteria}.
*
* @param key the field name
* @param criteria a {@link Criteria} that contains a well-formed filter for
* the desired records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract <T> Map<Long, Set<T>> select(String key, Criteria criteria,
Timestamp timestamp);
/**
* Return all the values stored for {@code key} in {@code record}.
*
* @param key the field name
* @param record the record id
* @return a {@link Set} containing all the values stored in the field
*/
public abstract <T> Set<T> select(String key, long record);
/**
* Return all the values stored for {@code key} in {@code record} at
* {@code timestamp}.
*
* @param key the field name
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Set} containing all the values stored in the field at
* {@code timestamp}
*/
public abstract <T> Set<T> select(String key, long record,
Timestamp timestamp);
/**
* Return all the values stored for {@code key} in every record that
* matches the {@code criteria}.
* <p>
* This method is syntactic sugar for {@link #select(String, Criteria)}. The
* only difference is that this method takes a in-process {@link Criteria}
* building sequence for convenience.
* </p>
*
* @param key the field name
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @return a {@link Map} associating each of the matching records to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract <T> Map<Long, Set<T>> select(String key, Object criteria);
/**
* Return all the values stored for {@code key} at {@code timestamp} in
* every record that matches the {@code criteria}.
* <p>
* This method is syntactic sugar for
* {@link #select(String, Criteria, Timestamp)}. The only difference is that
* this method takes a in-process {@link Criteria} building sequence for
* convenience.
* </p>
*
* @param key the field name
* @param criteria an in-process {@link Criteria} building sequence that
* contains an {@link BuildableState#build() unfinalized},
* but well-formed filter for the desired
* records
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract <T> Map<Long, Set<T>> select(String key, Object criteria,
Timestamp timestamp);
/**
* Return all the values stored for {@code key} in every record that
* matches the {@code ccl} filter.
*
* @param key the field name
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @return a {@link Map} associating each of the the matching records to a
* {@link Set} containing all the values stored in the respective
* field
*/
public abstract <T> Map<Long, Set<T>> select(String key, String ccl);
/**
* Return all the values stored for {@code key} at {@code timestamp} in
* every record that matches the {@code ccl} filter.
*
* @param key the field name
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to a
* {@link Set} containing all the values stored in the respective
* field at {@code timestamp}
*/
public abstract <T> Map<Long, Set<T>> select(String key, String ccl,
Timestamp timestamp);
/**
* Return all the data at {@code timestamp} from every record that
* matches the {@code ccl} filter.
*
* @param keys a collection of field names
* @param ccl a well-formed criteria expressed using the Concourse Criteria
* Language
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return a {@link Map} associating each of the matching records to another
* {@link Map} associating each of the {@code keys} in that record
* to a {@link Set} containing all the values stored in the
* respective field at {@code timestamp}
*/
public abstract <T> Map<Long, Map<String, Set<T>>> select(String ccl,
Timestamp timestamp);
/**
* In each of the {@code records}, atomically remove all the values stored
* for {@code key} and then add {@code key} as {@code value} in the
* respective record.
*
* @param key the field name
* @param value the value to set
* @param records a collection of record ids
*/
public abstract void set(String key, Object value,
Collection<Long> records);
/**
* Atomically remove all the values stored for {@code key} in {@code record}
* and add then {@code key} as {@code value}.
*
* @param key the field name
* @param value the value to set
* @param record the record id
*/
public abstract <T> void set(String key, T value, long record);
/**
* Start a new transaction.
* <p>
* This method will turn on STAGING mode so that all subsequent changes are
* collected in an isolated buffer before possibly being committed to the
* database. Staged operations are guaranteed to be reliable, all or nothing
* units of work that allow correct recovery from failures and provide
* isolation between clients so the database is always in a consistent
* state.
* </p>
* <p>
* After this method returns, all subsequent operations will be done in
* {@code staging} mode until either {@link #abort()} or {@link #commit()}
* is invoked.
* </p>
* <p>
* All operations that occur within a transaction should be wrapped in a
* try-catch block so that transaction exceptions can be caught and the
* transaction can be properly aborted.
*
* <pre>
* concourse.stage();
* try {
* concourse.get("foo", 1);
* concourse.add("foo", "bar", 1);
* concourse.commit();
* }
* catch (TransactionException e) {
* concourse.abort();
* }
* </pre>
*
* </p>
*/
public abstract void stage() throws TransactionException;
/**
* Execute {@code task} within a new transaction.
* <p>
* This method will automatically start a transaction for {@code task} and
* attempt to commit. There is also logic to gracefully handle exceptions
* that may result from any actions in the {@code task}.
* </p>
*
* @param task a {@link Runnable} that contains the group of operations to
* execute in the transaction
* @return a boolean that indicates if the transaction successfully
* committed
* @throws TransactionException
*/
public final boolean stage(Runnable task) throws TransactionException {
stage();
try {
task.run();
return commit();
}
catch (TransactionException e) {
abort();
throw e;
}
}
/**
* Return a {@link Timestamp} that represents the current instant according
* to the server.
*
* @return the current time
*/
public abstract Timestamp time();
/**
* Return a {@link Timestamp} that corresponds to the specified number of
* {@code micros}econds since the Unix epoch.
*
* @param micros the number of microseconds since the unix epoch
* @return the {@link Timestamp} that represents the desired instant
*/
public final Timestamp time(long micros) {
return Timestamp.fromMicros(micros);
}
/**
* Return the {@link Timestamp} that corresponds to the specified number of
* {@code micros}econds since the Unix epoch.
*
* @param micros the number of microseconds since the unix epoch
* @return the {@link Timestamp} that represents the desired instant
*/
public final Timestamp time(Number micros) {
return time(micros.longValue());
}
/**
* Return the {@link Timestamp}, according to the server, that corresponds
* to the instant described by the {@code phrase}.
*
* @param phrase a natural language description of a point in time.
* @return the {@link Timestamp} that represents the desired instant
*/
public abstract Timestamp time(String phrase);
/**
* If it exists, remove the link from {@code key} in {@code source} to
* {@code destination}.
*
* @param key the field name
* @param destination the id of the record where the link points
* @param source the id of the record where the link originates
* @return {@code true} if the link is removed
*/
public abstract boolean unlink(String key, long destination, long source);
/**
* Return {@code true} if {@code value} is stored for {@code key} in
* {@code record}.
*
* @param key the field name
* @param value the value to check
* @param record the record id
* @return {@code true} if {@code value} is stored in the field, otherwise
* {@code false}
*/
public abstract boolean verify(String key, Object value, long record);
/**
* Return {@code true} if {@code value} was stored for {@code key} in
* {@code record} at {@code timestamp}.
*
* @param key the field name
* @param value the value to check
* @param record the record id
* @param timestamp a {@link Timestamp} that represents the historical
* instant to use in the lookup – created from either a
* {@link Timestamp#fromString(String) natural language
* description} of a point in time (i.e. two weeks ago), OR
* the {@link Timestamp#fromMicros(long) number
* of microseconds} since the Unix epoch, OR
* a {@link Timestamp#fromJoda(org.joda.time.DateTime) Joda
* DateTime} object
* @return {@code true} if {@code value} is stored in the field, otherwise
* {@code false}
*/
public abstract boolean verify(String key, Object value, long record,
Timestamp timestamp);
/**
* Atomically replace {@code expected} with {@code replacement} for
* {@code key} in {@code record} if and only if {@code expected} is
* currently stored in the field.
*
* @param key the field name
* @param expected the value expected to currently exist in the field
* @param record the record id
* @param replacement the value with which to replace {@code expected} if
* and only if it currently exists in the field
* @return {@code true} if the swap is successful
*/
public abstract boolean verifyAndSwap(String key, Object expected,
long record, Object replacement);
/**
* Atomically verify that {@code key} equals {@code expected} in
* {@code record} or set it as such.
* <p>
* Please note that after returning, this method guarantees that {@code key}
* in {@code record} will only contain {@code value}, even if {@code value}
* already existed alongside other values [e.g. calling verifyOrSet("foo",
* "bar", 1) will mean that "foo" in 1 only has "bar" as a value after
* returning, even if "foo" in 1 already had "bar", "baz", and "apple" as
* values].
* </p>
* <p>
* <em>So, basically, this function has the same guarantee as the
* {@link #set(String, Object, long)} method, except it will not create any
* new revisions unless it is necessary to do so.</em> The {@code set}
* method, on the other hand, would indiscriminately clear all the values
* for {@code key} in {@code record} before adding {@code value}, even if
* {@code value} already existed.
* </p>
* <p>
* If you want to add a new value only if it does not exist while also
* preserving other values, you should use the
* {@link #add(String, Object, long)} method instead.
* </p>
*
* @param key the field name
* @param value the value to check
* @param record the record id
*/
public abstract void verifyOrSet(String key, Object value, long record);
/**
* Return a new {@link Concourse} connection that is connected to the same
* deployment with the same credentials as this connection.
*
* @return a copy of this connection handle
*/
protected abstract Concourse copyConnection();
}