rusqlite_migration

Struct Migrations

source
pub struct Migrations<'m> { /* private fields */ }
Expand description

Set of migrations

Implementations§

source§

impl<'m> Migrations<'m>

source

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);"),
]);
source

pub fn from_directory(dir: &'static Dir<'static>) -> Result<Self>

Available on crate feature 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.

source

pub 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.

Deprecated: Migrations now implements FromIterator, so use Migrations::from_iter instead.

Performs allocations transparently.

source

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.

source

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.

source

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, version 3 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.

source

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>

source§

fn clone(&self) -> Migrations<'m>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'m> Debug for Migrations<'m>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'u> FromIterator<M<'u>> for Migrations<'u>

source§

fn from_iter<T: IntoIterator<Item = M<'u>>>(iter: T) -> Self

Creates a value from an iterator. Read more
source§

impl<'m> PartialEq for Migrations<'m>

source§

fn eq(&self, other: &Migrations<'m>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'m> Eq for Migrations<'m>

source§

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> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.