Computed object properties

import {
   ComputedDataProcessor
} from '@phfaist/zoodb/dbprocessor/computeddata';
class ComputedDataProcessor()

A database processor for computing data derived from the database data

This database processor is given an object that specifies which zoodb objects have which properties that need to be computed, and which specifies functions to compute them. This database processor ensures the computed properties are computed when loading the zoo (or when the property is requested; see the lazy config option).

The computed properties are expected to be accessed not directly on the object, but through special methods that are automatically installed on the zoodb object. For instance, if a user object has a computed property short_name, the zoodb instance will be given a custom method user_short_name(user) that takes a user object as single argument and which returns the computed property value. This special method accesses a cached value, making it efficient to be called repeatedly.

After it is computed, the value of a computed property is stored within the zoodb.scratch of the zoodb. (Try accessing zoodb.scratch.computed_data_values, and see the computed_data_fieldset_name config option below to use a scratch property name other than computed_data_values.) If the lazy config option is set to false, then all computed property values are computed when loading or reloading the zoo. If the lazy option is set to true, then any property that we can compute on-the-fly is only computed at the time it is requested on a specific object (see below for more details about which computed properties can be computed lazily).

There are two ways to specify how to compute a computed property’s value in the computed property spec object (more details on the global structure below). You may specify a property named fn and set it to a function that computes the property value for a single object. Alternatively, you can specify a property named fn_bulk that computes the property over many objects in bulk. The major difference is that fn_bulk can be made async, whereas fn cannot. Because fn_bulk can be async, however, computed properties defined with fn_bulk cannot be lazy; they are always computed in their entirety when loading or updating the zoo. (Indeed, this is to guarantee that the property value can always be accessed from a non-async scope.)

Configuration options:

  • config.computed_data: An object that specifies how to compute all the relevant computed data for each object type. The object’s keys are object type names. For each object type, the value is an object that specifies the computed properties of that object; each key name is a computed property name. The value associated with each computed property name is an object that specifies how to compute the property. That object should either have a property named fn or one named fn_bulk.

    If you set fn, it should be set to a function that takes a single object as its only argument. It should return the computed property value. The function may not be async.

    If you set fn_bulk, it should be set to a function that takes a dictionary (i.e. an Object) obj_db as single argument. The obj_db argument is a dictionary of object id’s to objects. The function should return a dictionary of all the values of the computed property values of these objects for this computed property.

    In both cases, this is set to the zoodb object so that the zoodb object can be easily accessed from the function body.

  • config.object_types: a list of object type names to which the processing will be applied. If empty or null, processing is applied to all object types.

  • lazy: if set to true, then we try to defer computing property values until they are requested by a call on the zoodb’s special method. (By default, it is set to false.) Computed properties with a bulk computing function (fn_bulk) cannot be lazily computed (because they are async) and are always computed when loading or updating the zoo.

  • keep_computed_data_in_data_dumps: if set to true, then data dumps of the zoodb will produce objects in which the computed properties are included as regular properties of the objects. This can be overridden per-dump by passing keep_computed_data in the options to data_dump().

  • create_zoo_methods: if set to true (the default), then special methods named <object_type>_<computed_property_name>(obj) are installed on the main zoodb object and are expected to be used to access the computed properties. Computation of lazily-computed property values is triggered by calling the corresponding special method on the zoodb object.

    WARNING: If create_zoo_methods is set to false, the only way to access the computed properties’ values is by accessing zoodb.scratch.computed_data_values directly (or whatever computed_data_fieldset_name config option is set to)!

    WARNING: If create_zoo_methods is set to false, the automatic computation of lazy properties will never automatically be triggered, and they might never be computed!

  • computed_data_fieldset_name: The name of the property to set on the zoodb’s scratch dictionary to store the computed data values. By default, this is computed_data_values. You should only change this if you have a good reason to, e.g., if it is essential to have multiple instances of ComputedDataProcessor on the same zoodb. But that’s probably really asking for trouble!

  • create_zoodb_special_method: A function taking named object arguments ({zoodb, object_type, computed_property_name, accessor_function}) that is responsible for creating the special method to access the computed properties’ values. The special method’s implementation that needs to be called is provided as accessor_function. By default, this function simply creates a property on the zoodb object named <object_type>_<computed_property_name> and with value accessor_function. You can override this behavior here, e.g., to change the special method’s name or the object on which it is attached. The default implementation goes like:

    create_zoodb_special_method: ({zoodb, object_type, computed_property_name, accessor_function}) => {
        zoodb[`${object_type}_${computed_property_name}`] = accessor_function;
    }
    
ComputedDataProcessor.ComputedDataProcessor