Terracotta 10.7 | TCStore API Developer Guide | Reference | Operations | CRUD Operations
 
CRUD Operations
DatasetReader and DatasetWriterReader
A DatasetReader is required to read records from the dataset, and DatasetWriterReader allows add/update/delete operations on a dataset.
DatasetWriterReader<String> writerReader = persons.writerReader(); // <1>
1
Dataset.writerReader returns the required DatasetWriterReader for mutative access. Similarly, Dataset.reader returns a DatasetReader.
Adding Records
String person1 = "p1";
writerReader.add(person1, // 1
Person.FIRST_NAME.newCell("Marcus"), // 2
Person.LAST_NAME.newCell("Aurelius"),
Person.RATED.newCell(true),
Person.NICENESS.newCell(0.65D));
1
The DatasetWriterReader API provides the add method which takes the specified key of the record,
2
And var-args of Cell. Another variant takes an Iterable of cells.
Accessing Records
Record<String> marcus =
writerReader.get(person1).orElseThrow(AssertionError::new); // <1>

1
DatasetReader has a get method which takes a key as the argument. It returns an Optional of record. If the dataset doesn't have a record against the provided key Optional.isPresent will return false.
Update Existing Records

writerReader.update(marcus.getKey(),
UpdateOperation.write(Person.NICENESS, 0.85D)); // <1>
writerReader.update(person2, UpdateOperation.allOf(
UpdateOperation.write(Person.RATED, false),
UpdateOperation.remove(Person.NICENESS))); // <2>
writerReader.update(person3, UpdateOperation.allOf(
UpdateOperation.write(Person.RATED, true),
UpdateOperation.write(Person.NICENESS, 0.92D)));

1
The DatasetWriterReader.update method requires the key of the record to be updated along with an UpdateOperation of the cell. The UpdateOperation.write method has overloaded variants which can be used to add/update cells in an existing record.
2
For updating multiple cells simultaneously, you can use UpdateOperation.allOf which takes a var-arg. To remove a cell use UpdateOperation.remove. Note that all these updates only happen to an existing record. If the record doesn't exist, an update operation will not result in the addition of a record against the provided key.
Deleting Records
writerReader.delete(marcus.getKey()); // <1>
1
DatasetWriterReader.delete takes key and returns true if the record deletion was successful.
Accessor APIs for CRUD
Another way to perform CRUD operations on a dataset is through using the ReadWriteRecordAccessor API. It provides more control over read-write operations on a record with mapping and conditional reads/writes.

ReadWriteRecordAccessor<String> recordAccessor = writerReader.on(person3); // <1>

recordAccessor.read(record -> record.get(Person.NICENESS).get()); // <2>

recordAccessor.upsert(Person.BIRTH_YEAR.newCell(2000),
Person.PICTURE.newCell(new byte[1024])); // <3>

Optional<Integer> ageDiff = recordAccessor.update(UpdateOperation.write(
Person.BIRTH_YEAR.newCell(1985)), (record1, record2) ->
record1.get(Person.BIRTH_YEAR).get() -
record2.get(Person.BIRTH_YEAR).get()); // <4>

ConditionalReadWriteRecordAccessor<String> conditionalReadWriteRecordAccessor =
recordAccessor.iff(record ->
record.get(Person.BIRTH_YEAR).get().equals(1985)); // <5>

Record<String> record = conditionalReadWriteRecordAccessor.read().get(); // <6>
conditionalReadWriteRecordAccessor.update(
UpdateOperation.write(Person.RATED, false)); // <7>
conditionalReadWriteRecordAccessor.delete(); // <8>

1
An accessor for a record can be obtained by calling DatasetWriterReader.on which takes a key as the argument. DatasetReader.on returns a ReadRecordAccessor which has read only access to the record.
2
The read method takes a Function as an argument which maps the record to the required output.
3
The upsert method is like the same verb in a RDBMS: it will add if the record is absent or update if the record is present.
4
There is an advanced update that takes an additional BiFunction as mapper along with an UpdateOperation. The function maps the record that existed before the update and the record that resulted from the update.
5
Another variant allows conditional read/writes on the record. ReadWriteRecordAccessor.iff takes a predicate, the operations done on ConditionalReadWriteRecordAccessor are supplied with the same predicate. If the predicate returns true, the operation is executed against the record.
6
If the predicate returns true, the read will return a record.
7
The record will only be updated if the predicate returns true.
8
Similarly, the deletion succeeds if the predicate was true.
Please refer to the API documentation for more details.