ckb_migrate/
migrate.rs

1//! migrate helper
2
3use crate::migrations;
4use ckb_db::{ReadOnlyDB, RocksDB};
5use ckb_db_migration::{DefaultMigration, Migrations};
6use ckb_db_schema::{COLUMN_META, COLUMNS};
7use ckb_error::Error;
8use ckb_types::core::hardfork::HardForks;
9use std::cmp::Ordering;
10use std::path::PathBuf;
11use std::sync::Arc;
12
13const INIT_DB_VERSION: &str = "20191127135521";
14
15/// migrate helper
16pub struct Migrate {
17    migrations: Migrations,
18    path: PathBuf,
19}
20
21impl Migrate {
22    /// Construct new migrate
23    pub fn new<P: Into<PathBuf>>(path: P, hardforks: HardForks) -> Self {
24        let mut migrations = Migrations::default();
25        migrations.add_migration(Arc::new(DefaultMigration::new(INIT_DB_VERSION)));
26        migrations.add_migration(Arc::new(migrations::ChangeMoleculeTableToStruct)); // since v0.35.0
27        migrations.add_migration(Arc::new(migrations::CellMigration)); // since v0.37.0
28        migrations.add_migration(Arc::new(migrations::AddNumberHashMapping)); // since v0.40.0
29        migrations.add_migration(Arc::new(migrations::AddExtraDataHash)); // since v0.43.0
30        migrations.add_migration(Arc::new(migrations::AddBlockExtensionColumnFamily)); // since v0.100.0
31        migrations.add_migration(Arc::new(migrations::AddChainRootMMR)); // TODO(light-client) update the comment: which version?
32        migrations.add_migration(Arc::new(migrations::AddBlockFilterColumnFamily)); // since v0.105.0
33        migrations.add_migration(Arc::new(migrations::AddBlockFilterHash)); // since v0.108.0
34        migrations.add_migration(Arc::new(migrations::BlockExt2019ToZero::new(hardforks))); // since v0.111.1
35
36        Migrate {
37            migrations,
38            path: path.into(),
39        }
40    }
41
42    /// Open read only db
43    pub fn open_read_only_db(&self) -> Result<Option<ReadOnlyDB>, Error> {
44        // open cf meta column for empty check
45        ReadOnlyDB::open_cf(&self.path, vec![COLUMN_META])
46    }
47
48    /// Check if database's version is matched with the executable binary version.
49    ///
50    /// Returns
51    /// - Less: The database version is less than the matched version of the executable binary.
52    ///   Requires migration.
53    /// - Equal: The database version is matched with the executable binary version.
54    /// - Greater: The database version is greater than the matched version of the executable binary.
55    ///   Requires upgrade the executable binary.
56    pub fn check(&self, db: &ReadOnlyDB, include_background: bool) -> Ordering {
57        self.migrations.check(db, include_background)
58    }
59
60    /// Check whether database requires expensive migrations.
61    pub fn require_expensive(&self, db: &ReadOnlyDB, include_background: bool) -> bool {
62        self.migrations.expensive(db, include_background)
63    }
64
65    /// Check whether the pending migrations are all background migrations.
66    pub fn can_run_in_background(&self, db: &ReadOnlyDB) -> bool {
67        self.migrations.can_run_in_background(db)
68    }
69
70    /// Open bulk load db.
71    pub fn open_bulk_load_db(&self) -> Result<Option<RocksDB>, Error> {
72        RocksDB::prepare_for_bulk_load_open(&self.path, COLUMNS)
73    }
74
75    /// Perform migrate.
76    pub fn migrate(self, db: RocksDB, run_in_background: bool) -> Result<RocksDB, Error> {
77        self.migrations.migrate(db, run_in_background)
78    }
79
80    /// Perform init_db_version.
81    pub fn init_db_version(self, db: &RocksDB) -> Result<(), Error> {
82        self.migrations.init_db_version(db)
83    }
84}