Canyon Entity
Welcome to the section dedicated to one of the most iconic features of Canyon
- The Entities.
Definition of Canyon Entity
Throughout the previous chapters, we have already introduced the concept of entity and demonstrated its usage in various contexts. In Canyon
, however, an entity holds an even more powerful meaning than what was presented before.
Put simply, a Canyon Entity
is a user-defined type, which is represented as a struct, and is annotated with a special procedural macro
:
#![allow(unused)] fn main() { use canyon_sql::macros::canyon_entity; #[canyon_entity] pub struct League { #[primary_key] pub id: i32, pub ext_id: i64, pub slug: String, pub name: String, pub region: String, pub image_url: String } }
This macro unlocks a set of new features for the type. These features include:
- Inform
Canyon
that it should handle everything in the program that relates to this type on the database; - Track the type along with all the necessary metadata on a special register;
- Allow the user to configure an alternative table name and specify the schema in which the entity being pointed to resides;
These features provide a wealth of functionalities that will be explored further in upcoming chapters.
The table_name
and the schema
attribute parameters
The canyon_entity
macro can optionally receive two parameters: table_name
and schema
.
Example:
#![allow(unused)] fn main() { #[canyon_entity(table_name = "other_league", schema = "tic")] }
The naming convention for Rust types is CamelCase
. On the other hand, the naming convention for databases tables and schemas is often snake_case
. These attributes allow us to fulfill both standards.
Typically, Canyon
adheres to the convention of converting the name of a user-defined struct to a snake-case identifier for the purpose of generating database operations. This approach eliminates the need for modifying anything other than the defaults. Enabling users to conform to established ORM conventions in conjunction with the most common method of defining a table across various database engines.
However, it is not always necessary to follow this convention. In some cases, tables may already exist in the database, requiring different mapping. There may also be situations where the user prefer to use a different type name that cannot be converted to snake_case
as described above. To accomodate these scenarios, the user has the ability to specify the name of the database entity accordingly.
Additionally, Canyon
assumes assumes that the entities will be placed in the default schema, such as public
in PostgreSQL or dbo
in MSSQL. If there is need to use an alternative schema, the user may configure this on a per-entity basis using the schema
parameter.
The #[primary_key]
field attribute
Let's discuss one of the fundamental concepts in relational databases: the primary_key
. Each table in a database typically has its own primary key, and the primary purpose of designating one is to identify each unique record in a particular table.
In Canyon
, this is a significant concept. Almost every entity must be annotated with a primary_key
to unlock the full potential of the CRUD
operations generated by the CanyonCrud
derive macro. It also manages other things, such as:
- Identifying each unique record in a table;
- Facilitating data serialization;
- Auto-incrementing the
primary_key
of new inserted rows;
The primary_key
attribute has one optional parameter: autoincremental
. This is enabled by default
. And means that each new row will have the key of the last row incremented by 1.
Sometimes, the user may not wish an incremental primary key (usually on rare cases where a unique String
is used as primary key). Although this is not common, it is sometimes used. In that case, the user may disable autoincremental
by including:
#![allow(unused)] fn main() { #[primary_key(autoincremental = false)] }
Note:
autoincremental
is enabled by default. Not specifying it means it istrue
.