Redesign primary key
This commit is contained in:
parent
3a59d896e4
commit
58f4059c3e
@ -6,5 +6,6 @@ publish = false
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "^1.9", features = [ "attributes" ] }
|
||||
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls" ] }
|
||||
# sea-query = { path = "../../../sea-query" }
|
||||
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls", "debug-print" ] }
|
||||
sea-query = { path = "../../../sea-query" }
|
||||
strum = { version = "^0.20", features = [ "derive" ] }
|
4
examples/sqlx-mysql/import.sh
Normal file
4
examples/sqlx-mysql/import.sh
Normal file
@ -0,0 +1,4 @@
|
||||
cp ../../src/tests_cfg/cake.rs src/example_cake.rs
|
||||
cp ../../src/tests_cfg/fruit.rs src/example_fruit.rs
|
||||
|
||||
sed -i 's/^use crate::/use sea_orm::/g' src/*.rs
|
122
examples/sqlx-mysql/src/example_cake.rs
Normal file
122
examples/sqlx-mysql/src/example_cake.rs
Normal file
@ -0,0 +1,122 @@
|
||||
use sea_orm::{
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic,
|
||||
ModelTrait, QueryResult, Related, RelationDef, RelationTrait, Select, TypeErr, Value, PrimaryKeyTrait
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Iden)]
|
||||
#[iden = "cake"]
|
||||
pub struct Entity;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct Model {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum Column {
|
||||
Id,
|
||||
Name,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum PrimaryKey {
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {
|
||||
Fruit,
|
||||
}
|
||||
|
||||
impl EntityTrait for Entity {
|
||||
type Model = Model;
|
||||
|
||||
type Column = Column;
|
||||
|
||||
type PrimaryKey = PrimaryKey;
|
||||
|
||||
type Relation = Relation;
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl ModelTrait for Model {
|
||||
type Column = Column;
|
||||
|
||||
fn get(&self, c: Self::Column) -> Value {
|
||||
match c {
|
||||
Column::Id => self.id.clone().into(),
|
||||
Column::Name => self.name.clone().into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, c: Self::Column, v: Value) {
|
||||
match c {
|
||||
Column::Id => self.id = v.unwrap(),
|
||||
Column::Name => self.name = v.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_query_result(row: QueryResult) -> Result<Self, TypeErr> {
|
||||
Ok(Self {
|
||||
id: row.try_get(Column::Id.as_str())?,
|
||||
name: row.try_get(Column::Name.as_str())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for Column {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
Self::Name => "name",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColumnTrait for Column {
|
||||
type Entity = Entity;
|
||||
|
||||
fn def(&self) -> ColumnType {
|
||||
match self {
|
||||
Self::Id => ColumnType::Integer(None),
|
||||
Self::Name => ColumnType::String(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for PrimaryKey {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl PrimaryKeyTrait for PrimaryKey {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
match self {
|
||||
Self::Fruit => Entity::has_many(super::fruit::Entity)
|
||||
.from(Column::Id)
|
||||
.to(super::fruit::Column::CakeId)
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::fruit::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Fruit.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Model {
|
||||
pub fn find_fruit(&self) -> Select<super::fruit::Entity> {
|
||||
Entity::find_related().belongs_to::<Entity>(self)
|
||||
}
|
||||
}
|
110
examples/sqlx-mysql/src/example_fruit.rs
Normal file
110
examples/sqlx-mysql/src/example_fruit.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use sea_orm::{
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic,
|
||||
ModelTrait, QueryResult, RelationDef, RelationTrait, TypeErr, Value, PrimaryKeyTrait
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Iden)]
|
||||
#[iden = "fruit"]
|
||||
pub struct Entity;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct Model {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
pub cake_id: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum Column {
|
||||
Id,
|
||||
Name,
|
||||
CakeId,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum PrimaryKey {
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl EntityTrait for Entity {
|
||||
type Model = Model;
|
||||
|
||||
type Column = Column;
|
||||
|
||||
type PrimaryKey = PrimaryKey;
|
||||
|
||||
type Relation = Relation;
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl ModelTrait for Model {
|
||||
type Column = Column;
|
||||
|
||||
fn get(&self, c: Self::Column) -> Value {
|
||||
match c {
|
||||
Column::Id => self.id.clone().into(),
|
||||
Column::Name => self.name.clone().into(),
|
||||
Column::CakeId => self.cake_id.clone().into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, c: Self::Column, v: Value) {
|
||||
match c {
|
||||
Column::Id => self.id = v.unwrap(),
|
||||
Column::Name => self.name = v.unwrap(),
|
||||
Column::CakeId => self.cake_id = v.unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_query_result(row: QueryResult) -> Result<Self, TypeErr> {
|
||||
Ok(Self {
|
||||
id: row.try_get(Column::Id.as_str())?,
|
||||
name: row.try_get(Column::Name.as_str())?,
|
||||
cake_id: row.try_get(Column::CakeId.as_str())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for Column {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
Self::Name => "name",
|
||||
Self::CakeId => "cake_id",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ColumnTrait for Column {
|
||||
type Entity = Entity;
|
||||
|
||||
fn def(&self) -> ColumnType {
|
||||
match self {
|
||||
Self::Id => ColumnType::Integer(None),
|
||||
Self::Name => ColumnType::String(None),
|
||||
Self::CakeId => ColumnType::Integer(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for PrimaryKey {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl PrimaryKeyTrait for PrimaryKey {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!()
|
||||
}
|
||||
}
|
@ -1,4 +1,10 @@
|
||||
use sea_orm::{tests_cfg::*, Database, EntityTrait};
|
||||
use sea_orm::{Database, EntityTrait};
|
||||
|
||||
mod example_cake;
|
||||
mod example_fruit;
|
||||
|
||||
use example_cake as cake;
|
||||
use example_fruit as fruit;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
@ -10,20 +16,20 @@ async fn main() {
|
||||
println!();
|
||||
|
||||
println!("find all");
|
||||
println!();
|
||||
|
||||
let cakes = cake::Entity::find().all(&db).await.unwrap();
|
||||
|
||||
println!();
|
||||
for cc in cakes.iter() {
|
||||
println!("{:?}", cc);
|
||||
println!();
|
||||
}
|
||||
|
||||
println!("find one by primary key");
|
||||
println!();
|
||||
|
||||
let cheese = cake::Entity::find_one(&db, 1).await.unwrap();
|
||||
|
||||
println!();
|
||||
println!("{:?}", cheese);
|
||||
println!();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ColumnTrait, Connection, Database, Identity, ModelTrait, QueryErr, RelationBuilder,
|
||||
RelationTrait, RelationType, Select,
|
||||
ColumnTrait, Connection, Database, ModelTrait, QueryErr, RelationBuilder,
|
||||
RelationTrait, RelationType, Select, PrimaryKeyTrait
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use sea_query::{Expr, Iden, IntoIden, Value};
|
||||
@ -15,7 +15,7 @@ pub trait EntityTrait: Iden + Default + Debug + 'static {
|
||||
|
||||
type Relation: RelationTrait + Iterable;
|
||||
|
||||
fn primary_key() -> Identity;
|
||||
type PrimaryKey: PrimaryKeyTrait + Iterable;
|
||||
|
||||
fn auto_increment() -> bool {
|
||||
true
|
||||
@ -63,10 +63,11 @@ pub trait EntityTrait: Iden + Default + Debug + 'static {
|
||||
let builder = db.get_query_builder_backend();
|
||||
let stmt = {
|
||||
let mut select = Self::find();
|
||||
match Self::primary_key() {
|
||||
Identity::Unary(iden) => {
|
||||
select = select.filter(Expr::tbl(Self::default(), iden).eq(v));
|
||||
}
|
||||
if let Some(key) = Self::PrimaryKey::iter().next() {
|
||||
// TODO: supporting composite primary key
|
||||
select = select.filter(Expr::tbl(Self::default(), key).eq(v));
|
||||
} else {
|
||||
panic!("undefined primary key");
|
||||
}
|
||||
select.build(builder)
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ macro_rules! bind_oper {
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
Expr::tbl(self.entity_iden(), *self).$op(v)
|
||||
Expr::tbl(self.as_iden(), *self).$op(v)
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -28,7 +28,7 @@ pub trait ColumnTrait: IdenStatic {
|
||||
|
||||
fn def(&self) -> ColumnType;
|
||||
|
||||
fn entity_iden(&self) -> Rc<dyn Iden> {
|
||||
fn as_iden(&self) -> Rc<dyn Iden> {
|
||||
Rc::new(Self::Entity::default()) as Rc<dyn Iden>
|
||||
}
|
||||
|
||||
@ -43,14 +43,14 @@ pub trait ColumnTrait: IdenStatic {
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
Expr::tbl(self.entity_iden(), *self).between(a, b)
|
||||
Expr::tbl(self.as_iden(), *self).between(a, b)
|
||||
}
|
||||
|
||||
fn not_between<V>(&self, a: V, b: V) -> SimpleExpr
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
Expr::tbl(self.entity_iden(), *self).not_between(a, b)
|
||||
Expr::tbl(self.as_iden(), *self).not_between(a, b)
|
||||
}
|
||||
|
||||
/// ```
|
||||
@ -65,7 +65,7 @@ pub trait ColumnTrait: IdenStatic {
|
||||
/// );
|
||||
/// ```
|
||||
fn like(&self, s: &str) -> SimpleExpr {
|
||||
Expr::tbl(self.entity_iden(), *self).like(s)
|
||||
Expr::tbl(self.as_iden(), *self).like(s)
|
||||
}
|
||||
|
||||
/// ```
|
||||
@ -80,7 +80,7 @@ pub trait ColumnTrait: IdenStatic {
|
||||
/// );
|
||||
/// ```
|
||||
fn not_like(&self, s: &str) -> SimpleExpr {
|
||||
Expr::tbl(self.entity_iden(), *self).not_like(s)
|
||||
Expr::tbl(self.as_iden(), *self).not_like(s)
|
||||
}
|
||||
|
||||
/// ```
|
||||
@ -96,7 +96,7 @@ pub trait ColumnTrait: IdenStatic {
|
||||
/// ```
|
||||
fn starts_with(&self, s: &str) -> SimpleExpr {
|
||||
let pattern = format!("{}%", s);
|
||||
Expr::tbl(self.entity_iden(), *self).like(&pattern)
|
||||
Expr::tbl(self.as_iden(), *self).like(&pattern)
|
||||
}
|
||||
|
||||
/// ```
|
||||
@ -112,7 +112,7 @@ pub trait ColumnTrait: IdenStatic {
|
||||
/// ```
|
||||
fn ends_with(&self, s: &str) -> SimpleExpr {
|
||||
let pattern = format!("%{}", s);
|
||||
Expr::tbl(self.entity_iden(), *self).like(&pattern)
|
||||
Expr::tbl(self.as_iden(), *self).like(&pattern)
|
||||
}
|
||||
|
||||
/// ```
|
||||
@ -128,6 +128,6 @@ pub trait ColumnTrait: IdenStatic {
|
||||
/// ```
|
||||
fn contains(&self, s: &str) -> SimpleExpr {
|
||||
let pattern = format!("%{}%", s);
|
||||
Expr::tbl(self.entity_iden(), *self).like(&pattern)
|
||||
Expr::tbl(self.as_iden(), *self).like(&pattern)
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@ mod base;
|
||||
mod column;
|
||||
mod identity;
|
||||
mod model;
|
||||
mod primary_key;
|
||||
mod relation;
|
||||
|
||||
pub use base::*;
|
||||
pub use column::*;
|
||||
pub use identity::*;
|
||||
pub use model::*;
|
||||
pub use primary_key::*;
|
||||
pub use relation::*;
|
||||
|
3
src/entity/primary_key.rs
Normal file
3
src/entity/primary_key.rs
Normal file
@ -0,0 +1,3 @@
|
||||
use super::IdenStatic;
|
||||
|
||||
pub trait PrimaryKeyTrait: IdenStatic {}
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic, Identity, IntoIdentity,
|
||||
ModelTrait, QueryResult, Related, RelationDef, RelationTrait, Select, TypeErr, Value,
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic,
|
||||
ModelTrait, QueryResult, Related, RelationDef, RelationTrait, Select, TypeErr, Value, PrimaryKeyTrait
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Iden)]
|
||||
@ -19,6 +19,11 @@ pub enum Column {
|
||||
Name,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum PrimaryKey {
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {
|
||||
Fruit,
|
||||
@ -29,11 +34,9 @@ impl EntityTrait for Entity {
|
||||
|
||||
type Column = Column;
|
||||
|
||||
type Relation = Relation;
|
||||
type PrimaryKey = PrimaryKey;
|
||||
|
||||
fn primary_key() -> Identity {
|
||||
Column::Id.into_identity()
|
||||
}
|
||||
type Relation = Relation;
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
@ -66,8 +69,8 @@ impl ModelTrait for Model {
|
||||
impl IdenStatic for Column {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Column::Id => "id",
|
||||
Column::Name => "name",
|
||||
Self::Id => "id",
|
||||
Self::Name => "name",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,6 +86,18 @@ impl ColumnTrait for Column {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for PrimaryKey {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl PrimaryKeyTrait for PrimaryKey {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
match self {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic, Identity, IntoIdentity,
|
||||
ModelTrait, QueryResult, RelationDef, RelationTrait, TypeErr, Value,
|
||||
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, IdenStatic,
|
||||
ModelTrait, QueryResult, RelationDef, RelationTrait, TypeErr, Value, PrimaryKeyTrait
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Iden)]
|
||||
@ -21,6 +21,11 @@ pub enum Column {
|
||||
CakeId,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Iden, EnumIter)]
|
||||
pub enum PrimaryKey {
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
||||
pub enum Relation {}
|
||||
|
||||
@ -29,11 +34,9 @@ impl EntityTrait for Entity {
|
||||
|
||||
type Column = Column;
|
||||
|
||||
type Relation = Relation;
|
||||
type PrimaryKey = PrimaryKey;
|
||||
|
||||
fn primary_key() -> Identity {
|
||||
Column::Id.into_identity()
|
||||
}
|
||||
type Relation = Relation;
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
@ -69,9 +72,9 @@ impl ModelTrait for Model {
|
||||
impl IdenStatic for Column {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Column::Id => "id",
|
||||
Column::Name => "name",
|
||||
Column::CakeId => "cake_id",
|
||||
Self::Id => "id",
|
||||
Self::Name => "name",
|
||||
Self::CakeId => "cake_id",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,6 +91,18 @@ impl ColumnTrait for Column {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl IdenStatic for PrimaryKey {
|
||||
fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Id => "id",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement with derive macro
|
||||
impl PrimaryKeyTrait for PrimaryKey {}
|
||||
|
||||
impl RelationTrait for Relation {
|
||||
fn def(&self) -> RelationDef {
|
||||
panic!()
|
||||
|
Loading…
x
Reference in New Issue
Block a user