Improve API

This commit is contained in:
Chris Tsang 2021-05-09 21:10:57 +08:00
parent 6203d967eb
commit 486a081509
11 changed files with 73 additions and 38 deletions

View File

@ -6,11 +6,20 @@ CREATE TABLE `cake` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `cake` (`id`, `name`) VALUES
(1, 'New York Cheese'),
(2, 'Chocolate Fudge');
DROP TABLE IF EXISTS `fruit`;
CREATE TABLE `fruit` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cake_id` int,
`cake_id` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `fruit` (`id`, `name`, `cake_id`) VALUES
(1, 'Blueberry', 1),
(2, 'Rasberry', 1),
(3, 'Strawberry', 2);

View File

@ -117,7 +117,6 @@ impl IdenStatic for Column {
}
}
// TODO: implement with derive macro
impl Iden for PrimaryKey {
fn unquoted(&self, s: &mut dyn std::fmt::Write) {

View File

@ -15,7 +15,7 @@ async fn main() {
println!("{:?}", db);
println!();
println!("find all");
print!("find all: ");
let cakes = cake::Entity::find().all(&db).await.unwrap();
@ -25,15 +25,23 @@ async fn main() {
println!();
}
println!("find one by primary key");
let fruits = fruit::Entity::find().all(&db).await.unwrap();
let cheese = cake::Entity::find_one(&db, 1).await.unwrap();
println!();
for cc in fruits.iter() {
println!("{:?}", cc);
println!();
}
print!("find one by primary key: ");
let cheese = cake::Entity::find_by(1).one(&db).await.unwrap();
println!();
println!("{:?}", cheese);
println!();
println!("find models belongs to");
print!("find models belong to: ");
let fruits = cheese.find_fruit().all(&db).await.unwrap();

View File

@ -4,8 +4,9 @@ impl<E: 'static> Select<E>
where
E: EntityTrait,
{
pub async fn one(self, db: &Database) -> Result<E::Model, QueryErr> {
pub async fn one(mut self, db: &Database) -> Result<E::Model, QueryErr> {
let builder = db.get_query_builder_backend();
self.query().limit(1);
let row = db.get_connection().query_one(self.build(builder)).await?;
Ok(<E as EntityTrait>::Model::from_query_result(row)?)
}

View File

@ -1,6 +1,5 @@
use crate::{
ColumnTrait, Connection, Database, ModelTrait, PrimaryKeyTrait, QueryErr, RelationBuilder,
RelationTrait, RelationType, Select,
ColumnTrait, ModelTrait, PrimaryKeyTrait, RelationBuilder, RelationTrait, RelationType, Select,
};
use async_trait::async_trait;
use sea_query::{Expr, Iden, IntoIden, Value};
@ -41,13 +40,6 @@ pub trait EntityTrait: EntityName {
RelationBuilder::new(RelationType::HasMany, Self::default(), entity)
}
fn belongs_to<E>(entity: E) -> RelationBuilder
where
E: IntoIden,
{
RelationBuilder::new(RelationType::BelongsTo, Self::default(), entity)
}
/// ```
/// use sea_orm::{ColumnTrait, EntityTrait, tests_cfg::cake, sea_query::MysqlQueryBuilder};
///
@ -62,12 +54,21 @@ pub trait EntityTrait: EntityName {
Select::<Self>::new()
}
async fn find_one<V>(db: &Database, v: V) -> Result<Self::Model, QueryErr>
/// Find a model by primary key
/// ```
/// use sea_orm::{ColumnTrait, EntityTrait, tests_cfg::cake, sea_query::MysqlQueryBuilder};
///
/// assert_eq!(
/// cake::Entity::find_by(11)
/// .build(MysqlQueryBuilder)
/// .to_string(),
/// "SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 11"
/// );
/// ```
fn find_by<V>(v: V) -> Select<Self>
where
V: Into<Value> + Send,
V: Into<Value>,
{
let builder = db.get_query_builder_backend();
let stmt = {
let mut select = Self::find();
if let Some(key) = Self::PrimaryKey::iter().next() {
// TODO: supporting composite primary key
@ -75,9 +76,6 @@ pub trait EntityTrait: EntityName {
} else {
panic!("undefined primary key");
}
select.build(builder)
};
let row = db.get_connection().query_one(stmt).await?;
Ok(Self::Model::from_query_result(row)?)
select
}
}

View File

@ -31,6 +31,17 @@ pub trait ColumnTrait: IdenStatic {
bind_oper!(lt);
bind_oper!(lte);
/// ```
/// use sea_orm::{ColumnTrait, EntityTrait, tests_cfg::cake, sea_query::MysqlQueryBuilder};
///
/// assert_eq!(
/// cake::Entity::find()
/// .filter(cake::Column::Id.between(2,3))
/// .build(MysqlQueryBuilder)
/// .to_string(),
/// "SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` BETWEEN 2 AND 3"
/// );
/// ```
fn between<V>(&self, a: V, b: V) -> SimpleExpr
where
V: Into<Value>,
@ -38,6 +49,17 @@ pub trait ColumnTrait: IdenStatic {
Expr::tbl(self.as_iden(), *self).between(a, b)
}
/// ```
/// use sea_orm::{ColumnTrait, EntityTrait, tests_cfg::cake, sea_query::MysqlQueryBuilder};
///
/// assert_eq!(
/// cake::Entity::find()
/// .filter(cake::Column::Id.not_between(2,3))
/// .build(MysqlQueryBuilder)
/// .to_string(),
/// "SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` NOT BETWEEN 2 AND 3"
/// );
/// ```
fn not_between<V>(&self, a: V, b: V) -> SimpleExpr
where
V: Into<Value>,

View File

@ -7,7 +7,6 @@ use std::rc::Rc;
pub enum RelationType {
HasOne,
HasMany,
BelongsTo,
}
pub trait RelationTrait: Debug + 'static {

View File

@ -8,7 +8,7 @@ pub use sea_query::JoinType;
use sea_query::{Expr, Iden, IntoIden, Order, QueryBuilder, SelectStatement, SimpleExpr};
use std::rc::Rc;
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Select<E: 'static>
where
E: EntityTrait,

View File

@ -117,7 +117,6 @@ impl IdenStatic for Column {
}
}
// TODO: implement with derive macro
impl Iden for PrimaryKey {
fn unquoted(&self, s: &mut dyn std::fmt::Write) {