TwiceDB client libraries provide a convenient API for common operations. Below are some snippets to illustrate their use.
Most TwiceDB client methods support both synchronous and asynchronous execution. In Go, async methods return a chan, and in Java, async methods return a Future<>.
Methods marked with async
support asynchronous execution.
Setup
For these snippets, let’s use the following objects:
typeMyObjectstruct {
api.IndexableF// Name is indexed. Methods will be
// generated to do fast lookups by Name.
Name*string`twicedb:"index"`// Code is uniquely indexed. Methods
// will be generated to do fast lookups
// by Code, and TwiceDB will enforce
// that only 0 or 1 instances of
// MyObject will have the same Code
// at any given (tt, vt).
Code*string`twicedb:"unique"`// ANumber is projected. Methods
// will be generated to do aggregations
// on ANumber.
ANumber*int32`twicedb:"project"`// OtherObject *MyObject
}
typeMyEventstruct {
api.EventFAStringstring
}
@TwiceDBObjectpublicclassMyObjectextends Indexable<MyObject>implements MyObjectRefSupport {// Name is indexed. Methods will be
// generated to do fast lookups by Name.
@TwiceDBIndexpublic String name;// code is uniquely indexed. Methods
// will be generated to do fast lookups
// by code, and TwiceDB will enforce
// that only 0 or 1 instances of
// MyObject will have the same code
// at any given (tt, vt).
@TwiceDBUniquepublic String code;// aNumber is projected. Methods
// will be generated to do aggregations
// on aNumber.
@TwiceDBProjectpublic Integer aNumber;@TwiceDBRefprivatefinal MyObject otherObject =null;public String getName(){returnthis.name;}}@TwiceDBEventpublicclassMyEventextends Event<MyEvent>{privatefinal String aString;public String getAString(){returnthis.aString;}}
Get server status
Get basic status information from either the reader or the writer to which the client is currently connected.
it:=newMyObjectIterator(
client,
shared.BatchSize(10),
client.Lsqt().Tt())
for {
hn, _:=it.HasNext()
if !hn {
break
}
o, _:=it.Next()
}
Iterator<MyObject> it =
MyObjectIterator.getNew(
client,
client.getLsqt().toTt(),new BatchSize(10));while(it.hasNext()){
MyObject o = it.next();}
Read referenced objects (foreign keys)
async
Load referenced objects at the (tt, vt) at which the parent object was loaded.
otherObject, _:=o.OtherObject(client)
MyObject otherObject = o.getOtherObject(client);
Timelines
TwiceDB supports timelines that allow you to fix the tt and to see how objects changed along the vt or to fix the vt and to see how objects changed along the tt.
Read Tt timeline
async
Read all versions of an object at the given vt in tt order.
TwiceDB will notify subscribers of data changes in a publish-subscribe (“Pub/Sub”) manner.
Subscribe to IndexedQuery
Subscribe to an IndexedQuery to receive a notification each time an object matching the query is written.
iq:=NewMyObjectIndexedQueryBuilder()
.WhereNameEq("a name")
.WhereANumberGt(int32(9))
.Build()
subscriptionId, ch, _:=client.SubscribeToIndexedQuery(ctx, iq)
for {
subscribeResponse:=<-chfmt.Printf(
"Update received for SubscriptionId %d",
subscribeResponse.SubscriptionId)
}
IndexedQuery<MyIndexableObject> iq =
MyObjectIndexedQueryBuilder
.getNew().whereNameEqual("a name").whereANumberGreaterThan(9).build();
client.subscribeToIndexedQuery(
iq,new Function<SubscribeResponse, Boolean>(){@Overridepublic Boolean apply(
SubscribeResponse subscribeResponse
){
System.out.println("Update received for SubscriptionId "+
subscribeResponse.subscriptionId());returntrue;}});
Subscribe to ObjectId
Subscribe to an ObjectId to receive a notification each time it is written.
// Suppose we have an ObjectId oId.
subscriptionId, ch, _:=client.SubscribeToObjectId(
ctx,
oId)
for {
subscribeResponse:=<-chfmt.Printf(
"Update received for SubscriptionId %d",
subscribeResponse.SubscriptionId)
}
// Suppose we have an ObjectId oId.
client.subscribeToObjectId(
oId,new Function<SubscribeResponse, Boolean>(){@Overridepublic Boolean apply(
SubscribeResponse subscribeResponse
){
System.out.println("Update received for SubscriptionId "+
subscribeResponse.subscriptionId());returntrue;}});
Writes
TwiceDB supports a variety of query types to write, or save, data.
Delete single object
async
Delete a single object.
// Suppose we have an object o.
wo, _:=o.DeleteObject(
client.Context(),
shared.VtOf(time.Now()))
// Suppose we have an object o.
WrittenObject wo =
IndexableI.deleteObject(
client,
o,
Vt.of(LocalDate.now()));
Reindex single object
async
Reindex a single object after modifying its indexed and/or projected fields.
// Suppose we have an object o.
wo, _:=o.ReindexObject(
client)
// Suppose we have an object o.
WrittenObject wo =
client.ReindexObject(o);
Reinstate single object
async
Reinstate a single deleted object exactly as it was before it was deleted.
// Suppose we have an object o.
wo, _:=o.ReinstateObject(
client,
shared.VtOf(time.Now()))
// Suppose we have an object o.
WrittenObject wo =
IndexableI.reinstateObject(
client,
o,
Vt.of(LocalDate.now()));
Write single object
async
Write a single object with a user-assigned vt and a database-assigned tt.
o:=NewMyObject(
"object to write",
int32(246),
nil)
w, _:=o.PutObject(
client,
shared.VtOf(time.Now()))
MyObject o =
MyObjectFactory.getNew("object to write",
246,null);
WrittenObject w =
IndexableI.putObject(
client,
o,
Vt.of(LocalDate.now()));
Write multiple objects (transactions)
async
Use a transaction to save multiple objects together at the same tt.
o:=NewMyObject(
"object to write in a transaction",
int32(13),
other)
other:=NewMyObject(
"other object to write in a transaction",
int32(11),
nil)
vt:=shared.VtOf(time.Now())
tx:=txn.NewTxn()
tx.PutObject(o, vt)
tx.PutObject(other, vt)
w, _:=client.CommitTxn(tx)
MyObject o =
MyObjectFactory.getNew("object to write in a transaction",
13,
other);
MyObject other =
MyObjectFactory.getNew("other object to write in a transaction",
11,null);
Vt vt = Vt.of(LocalDate.now());
Txn tx =new Txn();
tx.putObject(o, vt);
tx.putObject(other, vt);
WrittenTransaction w = client.commitTxn(tx);
Write objects with an Event
async
Attach an Event to a transaction to link the objects in the transaction and/or to add metadata.
o:=NewMyObject(
"object to bind to an Event",
int32(-3),
nil)
e:=NewMyEvent(
AString: "remember this",
)
tx:=txn.NewEventTxn(e)
tx.PutObject(o, shared.VtOf(time.Now()))
w, _:=client.CommitTxn(tx)
MyObject o =
MyObjectFactory.getNew("object to bind to an Event",-3,null);
Txn tx = Txn.eventTxn(
MyEventFactory.getNew("remember this"));
tx.putObject(o, Vt.of(LocalDate.now()));
WrittenTransaction w = client.commitTxn(tx);
Aggregations
TwiceDB supports a variety of descriptive statistics for data.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").count(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Max of a field
async
Max of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").maxANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Mean of a field
async
Mean of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").meanANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Median of a field
async
Median of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").medianANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Min of a field
async
Min of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").minANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Percentile of a field
async
Percentile of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").percentileANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
StdDev of a field
async
StdDev of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").stddevANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Sum of a field
async
Sum of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").sumANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));
Variance of a field
async
Variance of a field of objects matching an IndexedQuery.
AggregationResponse r =
MyObjectIndexedQueryBuilder.getNew().whereNameEqual("An important name").varANumber(
client,new TemporalCoordinates(
client.getLsqt().toTt(),
Vt.of(LocalDate.now())));