The Registry
The registry is a vector of hash-map called attribute
. The
registry contains all the information about data available to EQL
consumers.
Most important types of attributes are roots, true columns, pseudo columns, joins and variables; each identified by a unique key.
Let’s see what we can have in the registry in details.
|
True columns
A true column is a keyword that denote a real column in a database table.
Please note: For security reason, only exposed columns are available
for querying. Keywords not found in the column set will be
ignored. That means if you forget to include any of them in a root’s
|
Walkable will scan for columns in the whole registry for true columns
(in |
Pseudo columns
In your registry you can define so-called pseudo columns that look just like normal columns from client-side view:
[{:key :person/id (1)
:type :true-column
:primary-key true
:output [:person/yob :person/age]} (1)
{:key :person/age
:type :pseudo-column
:formula [:- 2018 :person/yob]}]
1 | :person/age must be mentioned in :person/id’s `:output
to be accessible, just like :person/yob . |
You can’t tell the difference from client-side:
[{[:person/id 9]
[:person/yob]}]
[{[:person/id 9]
[:person/age]}]
[{(:people/list {:filters [:= 1988 :person/yob]})
[:person/name]}]
[{(:people/list {:filters [:= 30 :person/age]})
[:person/name]}]
Behind the scenes, Walkable will expand the pseudo columns to whatever they are defined. You can also use pseudo columns in other pseudo columns’ definition.
Please note you can only use true columns from the same table in the definition of pseudo columns. For instance, the following doesn’t make sense:
Your RDMS will throw an exception once you query for such pseudo-column anyway.
Joins
A join describes the relationship between two tables. You declare it
in the registry with :join-path
which is the path to traverse from
the source table to the target one.
The api for join is being improved. Expect some breaking changes. |
There are two patterns of join paths:
-
A column in the source table equals another column in the target table.
-
A dedicated join table is involved.
Let’s see some examples.
Pattern 1: Two equal columns from two tables
Assume table cow
contains:
id | color |
---|---|
10 |
white |
20 |
brown |
and table farmer
has:
id | name | cow_id |
---|---|---|
1 |
jon |
10 |
2 |
mary |
20 |
and you want to get a farmer along with their cow using the query:
[{[:farmer/id 1] [:farmer/name {:farmer/cow [:cow/id :cow/color]}]}]
For the join :farmer/cow
, table farmer
is the source and table
cow
is the target.
then you must define the :join-path
like this:
[{:key :farmer/cow
:type :join
:join-path [:farmer/cow-id :cow/id] (1)
:output [:cow/id :cow/color]}] (2)
1 | the join-path says: start with the value of column
farmer.cow_id (the join column) then find the correspondent in the
column cow.id . |
2 | don’t forget :output |
Internally, Walkable will generate this query to fetch the entity whose
ident is [:farmer/id 1]
:
SELECT `farmer`.`name`, `farmer`.`cow_id` FROM `farmer` WHERE `farmer`.`id` = 1
the value of column farmer
.cow_id
will be collected (for this
example it’s 10
). Walkable will then build the query for the join
:farmer/cow
:
SELECT `cow`.`id`, `cow`.`color` FROM `cow` WHERE `cow`.`id` = 10
{[:farmer/id 1] #:farmer{:number 1,
:name "jon",
:cow #:cow{:index 10,
:color "white"}}}
Pattern 2: A join involving a join table
Assume the following tables:
source table person
:
id | name |
---|---|
1 |
jon |
2 |
mary |
target table pet
:
id | name |
---|---|
10 |
kitty |
11 |
maggie |
20 |
ginger |
join table person_pet
:
person_id | pet_id | adoption_year |
---|---|---|
1 |
10 |
2010 |
1 |
11 |
2011 |
2 |
20 |
2010 |
you may query for a person and their pets along with their adoption year
[{[:person/id 1] [:person/name {:person/pets [:pet/name :person-pet/adoption-year]}]}]
then the :join-path
is as simple as:
[{:key :person/pets
:type :join
:output [:pet/name :person-pet/adoption-year] (2)
:join-path [:person/id :person-pet/person-id
:person-pet/pet-id :pet/id]}]
Never forget :output
!
Walkable will issue an SQL query for [:person/id 1]
:
SELECT `person`.`name` FROM `person` WHERE `person`.`id` = 1
and another query for the join :person/pets
:
SELECT `pet`.`name`, `person_pet`.`adoption_year`
FROM `person_pet` JOIN `pet` ON `person_pet`.`pet_id` = `pet`.`id` WHERE `person_pet`.`person_id` = 1
and our not-so-atonishing result:
{[:person/id 1] #:person{:id 1,
:name "jon",
:pets [{:pet/id 10,
:pet/name "kitty"
:person-pet/adoption-year 2010}
{:pet/id 11,
:pet/name "maggie"
:person-pet/adoption-year 2011}]}}