pub struct Migrations<'m> { /* private fields */ }
Expand description
Set of migrations
Implementations§
source§impl<'m> Migrations<'m>
impl<'m> Migrations<'m>
sourcepub fn new(ms: Vec<M<'m>>) -> Self
pub fn new(ms: Vec<M<'m>>) -> Self
Create a set of migrations.
§Example
use rusqlite_migration::{Migrations, M};
let migrations = Migrations::new(vec![
M::up("CREATE TABLE animals (name TEXT);"),
M::up("CREATE TABLE food (name TEXT);"),
]);
sourcepub fn from_directory(dir: &'static Dir<'static>) -> Result<Self>
Available on crate feature from-directory
only.
pub fn from_directory(dir: &'static Dir<'static>) -> Result<Self>
from-directory
only.Creates a set of migrations from a given directory by scanning subdirectories with a specified name pattern. The migrations are loaded and stored in the binary.
§Directory Structure Requirements
The migration directory pointed to by include_dir!()
must contain
subdirectories in accordance with the given pattern:
{usize id indicating the order}-{convenient migration name}
Those directories must contain at lest an up.sql
file containing a valid upward
migration. They can also contain a down.sql
file containing a downward migration.
§Example structure
migrations
├── 01-friend_car
│ └── up.sql
├── 02-add_birthday_column
│ └── up.sql
└── 03-add_animal_table
├── down.sql
└── up.sql
§Example
use rusqlite_migration::Migrations;
use include_dir::{Dir, include_dir};
static MIGRATION_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/../examples/from-directory/migrations");
let migrations = Migrations::from_directory(&MIGRATION_DIR).unwrap();
§Errors
Returns Error::FileLoad
in case the subdirectory names are incorrect,
or don’t contain at least a valid up.sql
file.
sourcepub fn new_iter<I: IntoIterator<Item = M<'m>>>(ms: I) -> Self
👎Deprecated: Use the FromIterator
trait implementation instead. For instance, you can call Migrations::from_iter.
pub fn new_iter<I: IntoIterator<Item = M<'m>>>(ms: I) -> Self
FromIterator
trait implementation instead. For instance, you can call Migrations::from_iter.Deprecated: Migrations
now implements FromIterator
, so use Migrations::from_iter
instead.
Performs allocations transparently.
sourcepub fn current_version(&self, conn: &Connection) -> Result<SchemaVersion>
pub fn current_version(&self, conn: &Connection) -> Result<SchemaVersion>
Get the current schema version
§Example
use rusqlite_migration::{Migrations, M, SchemaVersion};
use std::num::NonZeroUsize;
let mut conn = rusqlite::Connection::open_in_memory().unwrap();
let migrations = Migrations::new(vec![
M::up("CREATE TABLE animals (name TEXT);"),
M::up("CREATE TABLE food (name TEXT);"),
]);
assert_eq!(SchemaVersion::NoneSet, migrations.current_version(&conn).unwrap());
// Go to the latest version
migrations.to_latest(&mut conn).unwrap();
assert_eq!(SchemaVersion::Inside(NonZeroUsize::new(2).unwrap()), migrations.current_version(&conn).unwrap());
§Errors
Returns Error::RusqliteError
in case the user version cannot be queried.
sourcepub fn to_latest(&self, conn: &mut Connection) -> Result<()>
pub fn to_latest(&self, conn: &mut Connection) -> Result<()>
Migrate the database to latest schema version. The migrations are applied atomically.
§Example
use rusqlite_migration::{Migrations, M};
let mut conn = rusqlite::Connection::open_in_memory().unwrap();
let migrations = Migrations::new(vec![
M::up("CREATE TABLE animals (name TEXT);"),
M::up("CREATE TABLE food (name TEXT);"),
]);
// Go to the latest version
migrations.to_latest(&mut conn).unwrap();
// You can then insert values in the database
conn.execute("INSERT INTO animals (name) VALUES (?)", ["dog"]).unwrap();
conn.execute("INSERT INTO food (name) VALUES (?)", ["carrot"]).unwrap();
§Errors
Returns Error::MigrationDefinition
if no migration is defined.
Returns Error::RusqliteError
if rusqlite returns an error when executing a migration
statement. Note that this immediatley stops applying migrations.
let mut conn = rusqlite::Connection::open_in_memory().unwrap();
let migrations = Migrations::new(vec![
M::up("CREATE TABLE t1 (c);"),
M::up("SYNTAX ERROR"), // This won’t be applied
M::up("CREATE TABLE t2 (c);"), // This won’t be applied either because the migration above
// failed
]);
assert!(matches!(
migrations.to_latest(&mut conn),
Err(rusqlite_migration::Error::RusqliteError {
query: _,
err: rusqlite::Error::SqliteFailure(_, _),
})
));
If rusqlite extra_check
feature is enabled, any migration that returns a value will error
and no further migrations will be applied.
§Transaction Behavior
Since rusqlite 0.33, a default transaction behavior can be set. For now, when applying migrations, this setting will be respected.
Please note that future minor versions of rusqlite_migration might decide to ignore the setting and to instead use any transaction behavior deemed most appropriate. You can read more in the corresponding page of the SQLite documentation.
sourcepub fn to_version(&self, conn: &mut Connection, version: usize) -> Result<()>
pub fn to_version(&self, conn: &mut Connection, version: usize) -> Result<()>
Migrate the database to a given schema version. The migrations are applied atomically.
§Specifying versions
- Empty database (no migrations run yet) has version
0
. - The version increases after each migration, so after the first migration has run, the schema version is
1
. For instance, if there are 3 migrations, version3
is after all migrations have run.
Note: As a result, the version is the index in the migrations vector starting from 1.
§Example
use rusqlite_migration::{Migrations, M};
let mut conn = rusqlite::Connection::open_in_memory().unwrap();
let migrations = Migrations::new(vec![
// 0: version 0, before having run any migration
M::up("CREATE TABLE animals (name TEXT);").down("DROP TABLE animals;"),
// 1: version 1, after having created the “animals” table
M::up("CREATE TABLE food (name TEXT);").down("DROP TABLE food;"),
// 2: version 2, after having created the food table
]);
migrations.to_latest(&mut conn).unwrap(); // Create all tables
// Go back to version 1, i.e. after running the first migration
migrations.to_version(&mut conn, 1);
conn.execute("INSERT INTO animals (name) VALUES (?)", ["dog"]).unwrap();
conn.execute("INSERT INTO food (name) VALUES (?)", ["carrot"]).unwrap_err();
// Go back to an empty database
migrations.to_version(&mut conn, 0);
conn.execute("INSERT INTO animals (name) VALUES (?)", ["cat"]).unwrap_err();
conn.execute("INSERT INTO food (name) VALUES (?)", ["milk"]).unwrap_err();
§Errors
Attempts to migrate to a higher version than is supported will result in an error.
When migrating downwards, all the reversed migrations must have a .down()
variant,
otherwise no migrations are run and the function returns an error.
sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Run upward migrations on a temporary in-memory database from first to last, one by one. Convenience method for testing.
§Example
#[cfg(test)]
mod tests {
// … Other tests …
#[test]
fn migrations_test() {
migrations.validate().unwrap();
}
}
§Errors
Returns Error::RusqliteError
if the underlying sqlite database open call fails.
Trait Implementations§
source§impl<'m> Clone for Migrations<'m>
impl<'m> Clone for Migrations<'m>
source§fn clone(&self) -> Migrations<'m>
fn clone(&self) -> Migrations<'m>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<'m> Debug for Migrations<'m>
impl<'m> Debug for Migrations<'m>
source§impl<'u> FromIterator<M<'u>> for Migrations<'u>
impl<'u> FromIterator<M<'u>> for Migrations<'u>
source§impl<'m> PartialEq for Migrations<'m>
impl<'m> PartialEq for Migrations<'m>
impl<'m> Eq for Migrations<'m>
impl<'m> StructuralPartialEq for Migrations<'m>
Auto Trait Implementations§
impl<'m> Freeze for Migrations<'m>
impl<'m> !RefUnwindSafe for Migrations<'m>
impl<'m> Send for Migrations<'m>
impl<'m> Sync for Migrations<'m>
impl<'m> Unpin for Migrations<'m>
impl<'m> !UnwindSafe for Migrations<'m>
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)