Model property

Similar to the concepts of calculated property of programming languages, model properties in Teo represents data inputs and outputs which have a calculated nature. It's saved into the database if it's cached.

Property getter

A readable property has a getter. The getter is a pipeline that returns a value of declared data type. Field dependencies should be declared, too if it's cached.

model Student {
  @id @readonly @autoIncrement
  id: Int
  firstName: String
  lastName: String
  @getter($self.get(.firstName).presents.append(" ").append($self.get(.lastName).presents))
  @deps([.firstName, .lastName])
  name: String
}

In this example, name is calculated with firstName and lastName. Since it depends on firstName and lastName, the deps list is also declared.

Property setter

A writable property has a setter. The value is finally set to other fields of the object.

Let's add a setter to the readonly property in the previous section.

model Student {
  @id @readonly @autoIncrement
  id: Int
  firstName: String
  lastName: String
  @getter($self.get(.firstName).presents.append(" ").append($self.get(.lastName).presents))
  @setter($regexMatch(/^.+ .+$/).split(" ").assign(.firstName, $get(0).presents).assign(.lastName, $get(1).presents))
  @deps([.firstName, .lastName])
  name: String
}

Now, this property is readwrite. You can read from it and write to it.

Cached property

If the calculation is heavy loading, why not just save the value in memory and database? Cached property cames to the rescue.

model Student {
  @id @readonly @autoIncrement
  id: Int
  firstName: String
  lastName: String
  @getter($self.get(.firstName).append(" ").append($self.get(.lastName)))
  @setter($regexMatch(/^.+ .+$/).split(" ").assign(.firstName, $get(0).presents).assign(.lastName, $get(1).presents))
  @deps([.firstName, .lastName]) @cached
  name: String
}

When a property is cached, there is a table column for it. Unless any value of its dependency fields are updated, this value won't be recalculated.

Index

Like model scalar fields, calculated properties can be indexed. The API works the same way.

model Student {
  @id @readonly @autoIncrement
  id: Int
  firstName: String
  lastName: String
  @getter($self.get(.firstName.presents).append(" ").append($self.get(.lastName).presents))
  @deps([.firstName, .lastName]) @cached @index
  name: String
}