Datastore

Wrangler's io.picolabs.ds ruleset provides a simple key-value datastore that multiple rulesets can use at once. It can be used as a data transfer layer between different rulesets.

Installing the Datastore


To install Wrangler's datastore simply install the io.picolabs.ds ruleset in your pico. You can programmatically react to its installation by listening for wrangler:ds_ready events.

On Datastore Ready
/* An example of a rule taken from io.picolabs.wrangler.profile that selects on the initialization of the datastore */
rule set_up_ds_entry {
  select when wrangler ds_ready or
  pre {
    givenInitialProfile = event:attr("initialProfile")
    initialProfile = givenInitialProfile && givenInitialProfile.typeof() == "Map" => givenInitialProfile | initialProfile()
  }
  always {
    raise wrangler event "ds_assign_map_to_domain" attributes { // wrangler:ds_assign_map_to_domain assigns the whole key-value mapping under a certain domain
      "domain":meta:rid,
      "map":initialProfile,
      "co_id":meta:rid
    }
  }
}


Updating Data


Data in a data store can be updated through two different paths. The first is by giving a key-value pair for a domain by raising wrangler:ds_update and then responding to wrangler:ds_updated. The second is by changing all the key-value mappings under a domain by raising wrangler:ds_assign_map_to_domain with a new key-value map and reacting to wrangler:ds_domain_updated. It is recommended to use the latter way of updating sparingly, such as for data migration purposes.

It is convention to use a ruleset ID as the domain to silo your data to your rulesets.


Updating Datastore Data
/* An example of a rule that increments a counter value in the datastore */
rule incrementDS {
  select when test incrementDS
  pre {
    currentCounter = datastore:getItem(meta:rid, "counter")o.picolabs.wrangler.profile that selects on the initialization of the datastore 
    newValue = currentCounter.isnull() => 0 | currentCounter + 1
  }
  always {
    raise wrangler event "ds_update" attributes {
      "domain":meta:rid,	// The domain of the key-value pairings you want to manipulate
      "key":"counter",		// The key of the value you want to change
      "value":newValue		// The new value for the store
    }
  }
}

/* This rule reacts to wrangler:ds_updated to ensure that the counter we are incrementing 
	above is always even by checking if the new value in the store is divisible by 2 */
rule makeCounterEven {
  select when wrangler ds_updated
  pre {
    domain = event:attr("domain")
    key = event:attr("key")
    value = event:attr("value")
  }
  if domain == meta:rid && key == "counter" && value % 2 == 1 then
  noop()
  fired {
    raise wrangler event "ds_update" attributes event:attrs.put("value", value + 1)
  }
}

Copyright Picolabs | Licensed under Creative Commons.