View on GitHub

Red

A WiP ORM for Raku

Red ORM Architechture

Red is an ORM for Raku that tries to mimic Raku’s Seq’s API but for querying databases. Red implements a custom Metamodel based on Metamodel::ClassHOW. You use its new model keyword to describe your table and its relations as a Raku class.

The Red Metamodel exports a meta-method called all (called using MyModel.^all) or rs (called using MyModel.^rs) , which returns an instance of a class called Red::ResultSeq. Red::ResultSeq is essentially a specialization of Raku’s Seq type for data in the database. So

MyModel.^all

represents all rows in the MyModel table, and

MyModel.^all.grep: *.col1 > 3

represents all rows in the MyModel table where the value of col1 is higher than 3. The grep method (and most of the other Red::ResultSeq methods) returns a new ResultSeq.

A ResultSeq stores a Red::AST tree and each method that returns a new Red::ResultSeq creates a new Red::AST tree adding some more Red::AST nodes.

For example, the .map method runs the Callable code passing the model’s object type as the only parameter for that Callable. It has some logic to convert what the Callable does to Red::AST and creates a new Red::ResultSeq combining the Red::AST from the previous one with the one generated by the .map. (It’s planned to change as soon as it’s possible to create custom compile passes with RakuAST.)

Once a Red::ResultSeq is iterated, it uses the current Red::Driver to do two things:

  1. translate the Red::AST tree to SQL according to the database variant (each Red::AST has its own translation)
  2. connect to the database and run the query

Once the database responds, it gets the response and returns a Seq with an object for each row.