[−][src]Struct exonum::runtime::migrations::LinearMigrations
Linearly ordered migrations.
This type allows to construct a MigrateData
implementation that will follow migrations
performed during service evolution. In this way, the mechanism is similar to how migrations
are implemented in apps involving relational databases:
- Migration scripts will be applied to service data in a specific order during evolution of a particular service instance. Each script will be applied exactly once.
- Several migration scripts may be applied sequentially if the instance is old enough.
- Migrations for different service instances are independent, and migration scripts for them are fully reusable.
Retaining Old Data Types
Migration script logic needs retain the knowledge about data types used in the service
in the past. Since these data types may be unused currently, retaining them may place
a burden on the service. To mitigate this, you can provide a minimum supported starting version
of the service via set_min_version
.
Pre-releases
Special care must be taken to support pre-release versions (i.e., versions like 0.2.0-pre.2
or
1.2.34-rc.5
). As per the semver specification:
- Any pre-release version is lesser than a corresponding version without a pre-release suffix
- Pre-release versions with the same base triple are ordered alphabetically by their suffixes
The support of prerelease versions needs to be explicitly enabled by using the
with_prereleases
constructor. Otherwise, a prerelease mentioned
in the builder stage will lead to a panic, and select
will return an error
if a prerelease is specified as a start_version
.
Examples
Consider the following hypothetical evolution of a crypto-token service:
Version | Migration |
---|---|
0.2.0 | #1: Split name in user accounts into first_name and last_name |
0.3.0 | - |
0.4.0 | #2: Consolidate token metadata into a single Entry |
0.4.1 | - |
0.4.2 | #3: Compute total number of tokens and add it to metadata |
In this case:
- If a service instance is migrated from version 0.1.0 to the newest version 0.4.2, all three scripts need to be executed.
- If an instance is migrated from 0.2.0 or 0.3.0, only scripts #2 and #3 need to be executed.
- If an instance is migrated from 0.4.0 or 0.4.1, only script #3 needs to be executed.
- If the instance version is 0.4.2, no scripts need to be executed.
The migrations can be described in the service code as follows:
fn split_account_name(ctx: &mut MigrationContext) -> Result<(), MigrationError> { // script logic... } fn consolidate_metadata(ctx: &mut MigrationContext) -> Result<(), MigrationError> { // script logic... } fn compute_total_tokens(ctx: &mut MigrationContext) -> Result<(), MigrationError> { // script logic... } fn migrations() -> LinearMigrations { LinearMigrations::new(Version::new(0, 4, 3)) .add_script(Version::new(0, 2, 0), split_account_name) .add_script(Version::new(0, 4, 0), consolidate_metadata) .add_script(Version::new(0, 4, 2), compute_total_tokens) } /// Service with migrations. pub struct TokenService; impl MigrateData for TokenService { fn migration_scripts( &self, start_version: &Version, ) -> Result<Vec<MigrationScript>, InitMigrationError> { migrations().select(start_version) } } // Check that the migration scripts are selected properly. let scripts = TokenService.migration_scripts(&Version::new(0, 3, 0))?; assert_eq!(scripts.len(), 2); assert_eq!(*scripts[0].end_version(), Version::new(0, 4, 0));
Methods
impl LinearMigrations
[src]
pub fn new(latest_version: Version) -> Self
[src]
Creates a new set of migrations with the specified latest supported version.
Panics
- If
latest_version
is a prerelease.
pub fn with_prereleases(latest_version: Version) -> Self
[src]
Creates a new set of migrations with the specified latest supported version.
Unlike the new
constructor, this one indicates that prerelease versions are allowed
in the list of migrations and as the start version.
pub fn set_min_version(self, version: Version) -> Self
[src]
Signals to return an error if the starting version is less than the specified version.
Panics
- If
version
is a prerelease and this instance was not created by thewith_prereleases
constructor.
pub fn add_script<F>(self, version: Version, script: F) -> Self where
F: FnOnce(&mut MigrationContext) -> Result<(), MigrationError> + Send + 'static,
[src]
F: FnOnce(&mut MigrationContext) -> Result<(), MigrationError> + Send + 'static,
Adds a migration script at the specified version.
Panics
- If
version
is a prerelease and this instance was not created by thewith_prereleases
constructor.
pub fn select(
self,
start_version: &Version
) -> Result<Vec<MigrationScript>, InitMigrationError>
[src]
self,
start_version: &Version
) -> Result<Vec<MigrationScript>, InitMigrationError>
Selects a list of migration scripts based on the provided start version of the artifact.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for LinearMigrations
impl Send for LinearMigrations
impl !Sync for LinearMigrations
impl Unpin for LinearMigrations
impl !UnwindSafe for LinearMigrations
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,