toql_core/key.rs
1//! Table mapping information for keys.
2//!
3//! The key trait is implemented for every key struct the the Toql derive gernerates..
4//! It is used for internal purposes to build key predicates and for trait bounds.
5//!
6//! Library users may also use it for trait bounds.
7//!
8//! The trait cannot be used to get a key from an entity. This can be done with the [Keyed](crate::keyed::Keyed) trait.
9
10use crate::{sql_arg::SqlArg, sql_expr::SqlExpr};
11
12/// Trait to provide the entity type for a key. This is only used
13/// for ergonomics of the api.
14pub trait Key {
15 type Entity;
16
17 /// Return primary key columns for a given entity.
18 fn columns() -> Vec<String>;
19
20 /// Return foreign key columns that match the primary keys for a given entity.
21 /// This is only needed to merge entities.
22 /// The names are calculated and do not necessarily match
23 /// the actual foreign keys on the other table.
24 /// The translation rules are (for snake case column format):
25 ///
26 /// | Type | Guessing rule | Example |
27 /// | --------------|---------------------------|---------------|
28 /// | Normal fields | tablename + normal field | `id` -> `user_id`, `access_code` -> `user_access_code` |
29 /// | Joins | *No change* | `language_id` -> `language_id` |
30 ///
31 /// If the automatic generated names are not correct, the user is required to correct them by attributing
32 /// the relevant field with
33 ///
34 /// `#[toql( merge( columns( self = "id", other = "user_code")))]`
35 ///
36 fn default_inverse_columns() -> Vec<String>;
37
38 /// Return key values as params. Useful to loop across a composite key.
39 fn params(&self) -> Vec<SqlArg>;
40
41 fn unaliased_predicate_expr(&self) -> SqlExpr {
42 let columns = Self::columns();
43 let mut params = self.params().into_iter();
44 let mut expr = SqlExpr::new();
45
46 for c in columns {
47 if !expr.is_empty() {
48 expr.push_literal(" AND ".to_string());
49 }
50 expr.push_literal(c);
51 expr.push_literal(" = ".to_string());
52 expr.push_arg(params.next().unwrap_or(SqlArg::Null));
53 }
54 expr
55 }
56}