pub struct TestDatabase { /* private fields */ }db only.Expand description
A test database.
This is used to create a separate database for testing and run migrations on it.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let mut test_database = TestDatabase::new_sqlite().await?;
let request = TestRequestBuilder::get("/")
.database(test_database.database())
.build();
// do something with the request
test_database.cleanup().await?;Implementations§
Source§impl TestDatabase
impl TestDatabase
Sourcepub async fn new_sqlite() -> Result<Self>
pub async fn new_sqlite() -> Result<Self>
Create a new in-memory SQLite database for testing.
§Errors
If the database could not have been created.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let mut test_database = TestDatabase::new_sqlite().await?;
let request = TestRequestBuilder::get("/")
.database(test_database.database())
.build();
// do something with the request
test_database.cleanup().await?;Sourcepub async fn new_postgres(test_name: &str) -> Result<Self>
pub async fn new_postgres(test_name: &str) -> Result<Self>
Create a new PostgreSQL database for testing and connects to it.
The database URL is read from the POSTGRES_URL environment variable.
Note that it shouldn’t include the database name — the function will
create a new database for the test by connecting to the postgres
database. If no URL is provided, it defaults to
postgresql://cot:cot@localhost.
The database is created with the name test_cot__{test_name}.
Make sure that test_name is unique for each test so that the databases
don’t conflict with each other.
The database is dropped when self.cleanup() is called. Note that this
means that the database will not be dropped if the test panics.
§Errors
Returns an error if a database connection (either to the test database, or postgres maintenance database) could not be established.
Returns an error if the old test database could not be dropped.
Returns an error if the new test database could not be created.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let mut test_database = TestDatabase::new_postgres("my_test").await?;
let request = TestRequestBuilder::get("/")
.database(test_database.database())
.build();
// do something with the request
test_database.cleanup().await?;Sourcepub async fn new_mysql(test_name: &str) -> Result<Self>
pub async fn new_mysql(test_name: &str) -> Result<Self>
Create a new MySQL database for testing and connects to it.
The database URL is read from the MYSQL_URL environment variable.
Note that it shouldn’t include the database name — the function will
create a new database for the test by connecting to the mysql
database. If no URL is provided, it defaults to
mysql://root:@localhost.
The database is created with the name test_cot__{test_name}.
Make sure that test_name is unique for each test so that the databases
don’t conflict with each other.
The database is dropped when self.cleanup() is called. Note that this
means that the database will not be dropped if the test panics.
§Errors
Returns an error if a database connection (either to the test database, or MySQL maintenance database) could not be established.
Returns an error if the old test database could not be dropped.
Returns an error if the new test database could not be created.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let mut test_database = TestDatabase::new_mysql("my_test").await?;
let request = TestRequestBuilder::get("/")
.database(test_database.database())
.build();
// do something with the request
test_database.cleanup().await?;Sourcepub fn with_auth(&mut self) -> &mut Self
pub fn with_auth(&mut self) -> &mut Self
Add the default Cot authentication migrations to the test database.
This is useful if you want to test something that requires authentication.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let mut test_database = TestDatabase::new_sqlite().await?;
test_database.with_auth().run_migrations().await;
let request = TestRequestBuilder::get("/")
.with_db_auth(test_database.database())
.await
.build();
// do something with the request
test_database.cleanup().await?;Sourcepub fn add_migrations<T: DynMigration + Send + Sync + 'static, V: IntoIterator<Item = T>>(
&mut self,
migrations: V,
) -> &mut Self
pub fn add_migrations<T: DynMigration + Send + Sync + 'static, V: IntoIterator<Item = T>>( &mut self, migrations: V, ) -> &mut Self
Add migrations to the test database.
§Examples
use cot::test::{TestDatabase, TestMigration};
let mut test_database = TestDatabase::new_sqlite().await?;
test_database.add_migrations(vec![TestMigration::new(
"auth",
"create_users",
vec![],
vec![],
)]);Sourcepub async fn run_migrations(&mut self) -> &mut Self
pub async fn run_migrations(&mut self) -> &mut Self
Run the migrations on the test database.
§Panics
Panics if the migration engine could not be initialized or if the migrations could not be run.
§Examples
use cot::test::{TestDatabase, TestMigration};
let mut test_database = TestDatabase::new_sqlite().await?;
test_database.add_migrations(vec![TestMigration::new(
"auth",
"create_users",
vec![],
vec![],
)]);
test_database.run_migrations().await;Sourcepub fn database(&self) -> Arc<Database>
pub fn database(&self) -> Arc<Database>
Get the database.
§Examples
use cot::test::{TestDatabase, TestRequestBuilder};
let database = TestDatabase::new_sqlite().await?;
let request = TestRequestBuilder::get("/")
.database(database.database())
.build();Sourcepub async fn cleanup(&self) -> Result<()>
pub async fn cleanup(&self) -> Result<()>
Cleanup the test database.
This removes the test database and closes the connection. Note that this means that the database will not be dropped if the test panics, nor will it be dropped if you don’t call this function.
§Errors
Returns an error if the database could not be closed or if the database could not be dropped.
§Examples
use cot::test::TestDatabase;
let mut test_database = TestDatabase::new_sqlite().await?;
test_database.cleanup().await?;Methods from Deref<Target = Database>§
Sourcepub async fn close(&self) -> Result<()>
pub async fn close(&self) -> Result<()>
Closes the database connection.
This method should be called when the database connection is no longer needed. The connection is closed and the resources are released.
§Errors
This method can return an error if the connection to the database could not be closed gracefully, for instance because the connection has already been dropped.
§Examples
use cot::db::Database;
#[tokio::main]
async fn main() {
let db = Database::new("sqlite::memory:").await.unwrap();
db.close().await.unwrap();
}Sourcepub async fn insert<T: Model>(&self, data: &mut T) -> Result<()>
pub async fn insert<T: Model>(&self, data: &mut T) -> Result<()>
Inserts a new row into the database.
§Errors
This method can return an error if the row could not be inserted into the database, for instance because the migrations haven’t been applied, or there was a problem with the database connection.
Sourcepub async fn insert_or_update<T: Model>(&self, data: &mut T) -> Result<()>
pub async fn insert_or_update<T: Model>(&self, data: &mut T) -> Result<()>
Inserts a new row into the database, or updates it if a row with the same primary key already exists.
§Errors
This method can return an error if the row could not be inserted into the database, for instance because the migrations haven’t been applied, or there was a problem with the database connection.
Sourcepub async fn update<T: Model>(&self, data: &mut T) -> Result<()>
pub async fn update<T: Model>(&self, data: &mut T) -> Result<()>
Updates an existing row in a database.
§Errors
This method can return an error if the row could not be updated in the database, for instance because the migrations haven’t been applied, or there was a problem with the database connection.
This method can return an error if the row with the given primary key could not be found in the database.
Sourcepub async fn query<T: Model>(&self, query: &Query<T>) -> Result<Vec<T>>
pub async fn query<T: Model>(&self, query: &Query<T>) -> Result<Vec<T>>
Executes the given query and returns the results converted to the model type.
§Errors
This method can return an error if the query is invalid.
This method can return an error if the data in the database is not compatible with the model (usually meaning the migrations haven’t been generated or applied).
Can return an error if the database connection is lost.
Sourcepub async fn get<T: Model>(&self, query: &Query<T>) -> Result<Option<T>>
pub async fn get<T: Model>(&self, query: &Query<T>) -> Result<Option<T>>
Returns the first row that matches the given query. If no rows match the
query, returns None.
§Errors
This method can return an error if the query is invalid.
This method can return an error if the model doesn’t exist in the database (usually meaning the migrations haven’t been generated or applied).
Can return an error if the database connection is lost.
Sourcepub async fn exists<T: Model>(&self, query: &Query<T>) -> Result<bool>
pub async fn exists<T: Model>(&self, query: &Query<T>) -> Result<bool>
Returns whether a row exists that matches the given query.
§Errors
This method can return an error if the query is invalid.
This method can return an error if the model doesn’t exist in the database (usually meaning the migrations haven’t been generated or applied).
Can return an error if the database connection is lost.
Sourcepub async fn delete<T: Model>(
&self,
query: &Query<T>,
) -> Result<StatementResult>
pub async fn delete<T: Model>( &self, query: &Query<T>, ) -> Result<StatementResult>
Deletes all rows that match the given query.
§Errors
This method can return an error if the query is invalid.
This method can return an error if the model doesn’t exist in the database (usually meaning the migrations haven’t been generated or applied).
Can return an error if the database connection is lost.
Sourcepub async fn raw(&self, query: &str) -> Result<StatementResult>
pub async fn raw(&self, query: &str) -> Result<StatementResult>
Executes a raw SQL query.
§Errors
This method can return an error if the query is invalid.
Can return an error if the database connection is lost.
§Examples
use cot::db::Database;
let db = Database::new("sqlite::memory:").await?;
db.raw("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)")
.await?;Sourcepub async fn raw_with(
&self,
query: &str,
values: &[&dyn ToDbValue],
) -> Result<StatementResult>
pub async fn raw_with( &self, query: &str, values: &[&dyn ToDbValue], ) -> Result<StatementResult>
Executes a raw SQL query with parameters.
§Errors
This method can return an error if the query is invalid.
Can return an error if the database connection is lost.
§Examples
use cot::db::Database;
let db = Database::new("sqlite::memory:").await?;
db.raw("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)")
.await?;
db.raw_with("SELECT * FROM test WHERE id = ?", &[&1])
.await?;Trait Implementations§
Source§impl Debug for TestDatabase
impl Debug for TestDatabase
Auto Trait Implementations§
impl Freeze for TestDatabase
impl !RefUnwindSafe for TestDatabase
impl Send for TestDatabase
impl Sync for TestDatabase
impl Unpin for TestDatabase
impl !UnwindSafe for TestDatabase
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoField<Auto<T>> for T
impl<T> IntoField<Auto<T>> for T
Source§fn into_field(self) -> Auto<T>
fn into_field(self) -> Auto<T>
db only.