#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
pub mod connection;
pub mod criteria;
pub mod migrator;
pub mod model;
pub mod pagination;
pub mod raw;
pub mod relation;
pub mod repository;
pub mod row;
pub mod statement;
pub mod testing;
pub use connection::{Connection, Database};
pub use criteria::{Constraint, Criteria};
pub use migrator::{Down, Migration, Migrator, Step};
pub use model::{Created, Creating, Deleted, Deleting, Model, Updated, Updating};
pub use pagination::Paginated;
pub use raw::RawQuery;
pub use relation::{
BelongsTo, BelongsToMany, HasMany, HasOne, PivotQuery, Related, RelatedCounts, Relation,
RelationKey,
};
pub use repository::{EntityRepository, Repository};
pub use row::{Cell, ColumnRequest, OwnedRow};
pub use statement::Prepared;
pub use rainier_orm;
pub use rainier_orm::{
ddl, migrate, repo, schema, Action, Blueprint, ColumnKind, Dialect, Entity, Executor, IndexDef,
Query, TableChanges,
};
#[doc(hidden)]
pub mod reexport {
pub use crate::row::{ColumnRequest, OwnedRow};
pub use rainier_orm::sea_query::Value;
pub use rainier_orm::{Dialect, ExecOutcome, Executor, Row, ShardRoute};
pub use rainier_support::{BoxFuture, Error, LocalBoxFuture, Result};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::{fake_database, MemoryConnection};
#[derive(rainier_orm::Entity, Clone, Debug, PartialEq)]
#[orm(table = "users")]
struct User {
#[orm(pk, auto_increment)]
id: u64,
#[orm(unique)]
email: String,
}
impl Model for User {}
#[tokio::test]
async fn the_orm_surface_is_reachable_through_the_executor_impl() {
let (db, connection) = fake_database(
MemoryConnection::new(Dialect::Sqlite)
.returning([OwnedRow::new().with("id", 1_u64).with("email", "a@b.c")]),
);
let found: Option<User> = repo::find_one_by(&db, "email", "a@b.c").await.unwrap();
assert_eq!(found.unwrap().email, "a@b.c");
let sql = connection.last_statement().unwrap();
assert!(sql.contains("users"), "{sql}");
assert!(sql.contains("email"), "{sql}");
}
#[tokio::test]
async fn the_query_builder_works_against_a_database() {
let (db, connection) = fake_database(MemoryConnection::new(Dialect::Sqlite));
let _: Vec<User> = repo::query::<User>()
.where_like("email", "%@example.com")
.order_by_desc("id")
.limit(5)
.all(&db)
.await
.unwrap();
let sql = connection.last_statement().unwrap();
assert!(sql.contains("LIKE"), "{sql}");
assert!(sql.contains("ORDER BY"), "{sql}");
}
#[tokio::test]
async fn the_repository_path_covers_the_same_ground_and_stays_send() {
let (db, connection) = fake_database(
MemoryConnection::new(Dialect::Sqlite)
.returning([OwnedRow::new().with("id", 1_u64).with("email", "a@b.c")]),
);
let users = EntityRepository::<User>::new(db);
let found = users.first_by("email", "a@b.c".into()).await.unwrap();
assert_eq!(found.unwrap().email, "a@b.c");
assert!(connection.last_statement().unwrap().contains("users"));
}
#[test]
fn the_orms_own_futures_are_send_once_upstream_scopes_its_statements() {
fn assert_send<T: Send>(_: T) {}
let (db, _) = fake_database(MemoryConnection::new(Dialect::Sqlite));
assert_send(async move {
let found: rainier_orm::Result<Option<User>> =
repo::find_one_by(&db, "email", "a@b.c").await;
let listed: rainier_orm::Result<Vec<User>> =
repo::query::<User>().where_eq("id", 1_i64).all(&db).await;
(found.is_ok(), listed.is_ok())
});
}
#[tokio::test]
async fn schema_ddl_renders_for_the_connections_dialect() {
let ddl = schema::create_table_ddl::<User>(Dialect::Sqlite);
assert!(ddl.contains("users"), "{ddl}");
assert!(ddl.contains("email"), "{ddl}");
}
}