Skip to main content

The API

ActivePivot cube builder

Copper calculations are specified in the withCalculations(Consumer<ICopperContext>) method available in the cube builder.

The entry point of Copper API is the "Copper context" or simply the "context", which is aware of the already defined measures and hierarchies. Copper measures and hierarchies are created with the API and then published to the context like so:

.withCalculations(
context -> {
// Here you can describe your calculations with the context
});

The above snippet shows that all the Copper measures are defined in a single lambda method. For the sake of brevity, all examples from now on only show its body.

Once you have specified your calculations in the lambda, the new measures and hierarchies are added to the pivot description before it is started.

The Copper class provides all the static methods that serve as an entry point for measure and hierarchy creation. All created measures are objects that implement the same interface CopperMeasure, representing the basic bricks of Copper calculations that give you access to methods to build more complex calculations.

Inside the lambda itself, you may also reuse previously published measures or hierarchies for subsequent Copper calculations (pseudo-code):

CopperMeasure m1 = Copper.method(); // Create a measure with a static method from the Copper class
m1.publish(context);
// m1 is now available in following calculations

CopperMeasure m2 = m1.function(); // Apply function() on m1 to create a new measure
m2.publish(context);
// m2 is now available in following calculations

All your measures can be declared within this lambda, in Copper, at the same place and in the same way. This includes CopperMeasures, but also native measures, aggregated measures, as well as legacy post-processors.

Copper and distributed environments (experimental)

For more information about ActivePivot's distributed architecture and its concepts, please refer to the following article about distribution.

This is feature is currently in experimental stage. The API and behaviors can change between bug fix releases.

Copper in Query Cubes

You can use Copper in query cubes to declare measures that perform advanced calculations on measures defined in data cubes from applications that do not share the same topology.

This API is similar to the API that defines measure in a data cube with two key differences:

Measure to referenceUse
measure defined in a data cubeCopper.measureFromDataCube(measureName, measureType)
measure defined within the same query cubeCopper.measure(measureName)

CopperMeasure m1 = Copper.measureFromDataCube("measureFromDataCube1", ILiteralType.DOUBLE);
CopperMeasure m2 = Copper.measureFromDataCube("measureFromDataCube2", ILiteralType.LONG);
CopperMeasure m1_plus_m2 = m1.plus(m2).as("m1+m2").publish(context);
Copper.measure("m1+m2").multiply(Copper.constant(2)).as("multiply").publish(context);

The following features are yet to be implemented and will be available in future releases:

  • copperMeasure.shift(...)
  • copperMeasure.filter(...)

The features that need to access the database will not be supported: field aggregation, store lookup, join.

Copper in Data Cubes

Post-Processors defined with the Copper.newPostProcessor method will not inherit the default value of IClusterDefinition.EXECUTE_POST_PROCESSORS_IN_DATA_CUBE_PROPERTY. If you need to force the evaluation in the Data Cubes, you will have to call the executeInDataCube() method. The results coming from the Data Cubes will be merged with the SUM aggregation function when the distributing levels are not expressed in the locations of the queries.

Copper.newPostProcessor("pluginKey").executeInDataCube().as("measureName").publish(context);

Limitations

Continuous query on Copper measures that use Copper.storeLookup will not be notified on the updates in the database, because the Query Cube does not have access to the database.