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:
- translate the
Red::AST
tree to SQL according to the database variant (eachRed::AST
has its own translation) - 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.