Skip to main content
A tuple topic loads rows produced by a supplier function, rather than rows read from a source format such as CSV files or a JDBC query. The supplier builds each row in code, so the data can come from anywhere the supplier can reach: values computed on the fly, the parameters of the load request, a query against the datastore, or an external service such as a REST endpoint. The topic is configured through ITupleTopicConfigurator; the supplier and the names of the produced columns are described by ITupleTopicSettings. For the general topic and channel concepts, see the data loading overview.

How to load a fixed set of tuples

  1. Call configurator.channels().addChannel(channelName, tableName) to declare the channel that loads rows into the target table.
  2. Call configurator.topics().addTopic(topicName, ITupleTopicConfigurator.class) to declare a tuple topic.
  3. Call settings(ITupleTopicSettings.of(supplier, columns)). The supplier returns the rows to load, and columns names the fields each row carries, in order.
  4. Call attachChannel(channelName) on the topic to feed the channel.
Each row is an Object[] whose entries line up with the declared column names, so the first entry fills the first column, and so on. The following example loads two rows into the Sales table:

How the tuple supplier uses the load scope

The supplier is a Function<IDlcScope, Collection<Object[]>>. It receives the scope of the load request (the parameters supplied when the load is requested), so the produced rows can differ from one load to the next. The scope is a map of named parameters; read a parameter with a default when it may be absent.

How to build tuples from a datastore query

The supplier can read data already in the datastore and turn it into tuples. This is how a tuple topic derives a table from another table: one topic populates the source table, and the tuple topic queries it and loads a derived table. The same approach applies to any external source the supplier can call, such as a REST service. The supplier reads the datastore through the current transaction’s query runner (datastore.getTransactionManager().getQueryRunner()), so it sees the rows the ongoing load has already loaded, even before they are committed. For those rows to be there, the topic that feeds the queried table must run first: order the tuple topic after it with configurator.topics().orderTopicAfterTopic(topicName, afterTopicName). Both arguments are topic names, and both topics must already be registered. The following example loads a Products reference table from CSV files, then derives a ProductSummary table by querying Products and emitting one tuple per product:
The tuple topic re-derives the whole ProductSummary table on every load, so its previous rows must be cleared first, otherwise they accumulate. The example registers a data-operation trigger that empties ProductSummary. Because the trigger reads Products, it is fired by the products-csv topic and runs right after it; and because orderTopicAfterTopic waits for a topic and the triggers it fires, product-summary re-derives only once Products is loaded and ProductSummary has been cleared. For how data-operation triggers work, see data operation triggers.