Models

Models are elements that live through the whole execution of a program. Can be declared and configured, and then instancied in a treatment declaration.

use sql::SqlPool

model MyDatabase(const max: u32 = 5) : SqlPool
{
    min_connections = 1
    max_connections = max
    url = "postgresql://my-user@my-server:4321/my_database"
}

Reference for SqlPool

Models are instancied by treatments in their prelude.

use sql::fetch
use std/data/block::entry
use std/data/block::get
use std/flow::trigger

treatment myApp()
  /*
    When model is instancied, it is made available within the
    treatment as if it where given as configuration parameter.
  */
  model database: MyDatabase(max=3)
  input user_id:       Block<string>
  output user_name:    Block<Option<string>>
  output user_level:   Block<Option<u32>>
  output user_failure: Block<string>
{
    userData[database=database]()

    Self.user_id -> userData.user_id,user_name -> Self.user_name
                    userData.user_level --------> Self.user_level
                    userData.failure -----------> Self.user_failure
}

/*
  Model can be given as configuration parameter.
*/
treatment userData[database: SqlPool]()
  input user_id:     Block<string>
  output user_name:  Block<Option<string>>
  output user_level: Block<Option<u32>>
  output failure:    Block<string>
{

    /*
      And then passed again as configuration parameter.
    */
    fetchUser: fetch[pool=database](
      sql = "SELECT name, level IN users WHERE id = ? LIMIT 1",
      bindings = ["user_id"]
    )
    stream<string>()
    entry<string>(key="user_id")
    trigger<Map>()

    Self.user_id -> entry.value,map -> fetchUser.bind,data -> trigger.stream

    getUserName: get<string>(key="name")
    getUserLevel: get<u32>(key="level")

    trigger.first --> getUserName.map,value -> Self.user_name
    trigger.first -> getUserLevel.map,value -> Self.user_level

    fetchUser.failure -> Self.failure
}

Reference for fetch, entry, get, trigger

In most cases, models are instancied internally by treatments and not exposed, user developer can make direct call on model-dependent treatments without instancing its own, just giving required parameters to the sequence. The cases where user may give its own defined model is to configure elements such as external software connections or interfaces.