11'use strict'
22
33const migrations = require ( '../migrations' )
4- const repo_version = require ( './repo/version' )
5- const repo_lock = require ( './repo/lock' )
4+ const repoVersion = require ( './repo/version' )
5+ const repoLock = require ( './repo/lock' )
6+ const isBrowser = require ( './option-node' )
7+ const errors = require ( './errors' )
68const debug = require ( 'debug' )
79
810const log = debug ( 'js-ipfs-repo-migrations:migrator' )
911
10- exports . getLatestMigrationVersion = getLatestMigrationVersion
1112
1213/**
1314 * Returns the version of latest migration.
1415 *
15- * @returns int
16+ * @returns { int }
1617 */
1718function getLatestMigrationVersion ( ) {
1819 return migrations [ migrations . length - 1 ] . version
1920}
21+ exports . getLatestMigrationVersion = getLatestMigrationVersion
2022
21- async function migrate ( store , toVersion , progressCb , isDryRun ) {
23+ /**
24+ * Main function to execute forward migrations.
25+ * It acquire lock on the provided path before doing any migrations.
26+ *
27+ * Signature of the progress callback is: function(migrationObject: object, currentMigrationNumber: int, totalMigrationsCount: int)
28+ *
29+ * @param {string } path - Path to initialized (!) JS-IPFS repo
30+ * @param {int|undefined } toVersion - Version to which the repo should be migrated, if undefined repo will be migrated to the latest version.
31+ * @param {function|undefined } progressCb - Callback which will be called after each executed migration to report progress
32+ * @param {boolean|undefined } isDryRun - Allows to simulate the execution of the migrations without any effect.
33+ * @returns {Promise<void> }
34+ */
35+ async function migrate ( path , toVersion , progressCb , isDryRun ) {
2236 if ( toVersion && ( ! Number . isInteger ( toVersion ) || toVersion <= 0 ) ) {
2337 throw new Error ( 'Version has to be positive integer!' )
2438 }
2539 toVersion = toVersion || getLatestMigrationVersion ( )
2640
27- const currentVersion = await repo_version . getVersion ( store )
41+ const currentVersion = await repoVersion . getVersion ( path )
2842
2943 let lock
30- if ( ! isDryRun ) lock = await repo_lock . lock ( currentVersion , store . path )
44+ if ( ! isDryRun ) lock = await repoLock . lock ( currentVersion , path )
3145
3246 if ( currentVersion === toVersion ) {
3347 log ( 'Nothing to migrate, skipping migrations.' )
@@ -44,7 +58,7 @@ async function migrate(store, toVersion, progressCb, isDryRun) {
4458 log ( `Migrating version ${ migration . version } ` )
4559 if ( ! isDryRun ) {
4660 try {
47- await migration . migrate ( store )
61+ await migration . migrate ( path , isBrowser )
4862 } catch ( e ) {
4963 e . message = `During migration to version ${ migration . version } exception was raised: ${ e . message } `
5064 throw e
@@ -55,16 +69,26 @@ async function migrate(store, toVersion, progressCb, isDryRun) {
5569 }
5670 }
5771
58- if ( ! isDryRun ) await repo_version . setVersion ( store , toVersion || getLatestMigrationVersion ( ) )
72+ if ( ! isDryRun ) await repoVersion . setVersion ( path , toVersion || getLatestMigrationVersion ( ) )
5973 log ( 'All migrations successfully migrated ' , toVersion !== undefined ? `to version ${ toVersion } !` : 'to latest version!' )
6074
6175 if ( ! isDryRun ) await lock . close ( )
62- await store . close ( )
6376}
64-
6577exports . migrate = migrate
6678
67- async function revert ( store , toVersion , progressCb , isDryRun ) {
79+ /**
80+ * Main function to execute backward migration (reversion).
81+ * It acquire lock on the provided path before doing any migrations.
82+ *
83+ * Signature of the progress callback is: function(migrationObject: object, currentMigrationNumber: int, totalMigrationsCount: int)
84+ *
85+ * @param {string } path - Path to initialized (!) JS-IPFS repo
86+ * @param {int } toVersion - Version to which the repo will be reverted.
87+ * @param {function|undefined } progressCb - Callback which will be called after each reverted migration to report progress
88+ * @param {boolean|undefined } isDryRun - Allows to simulate the execution of the reversion without any effect.
89+ * @returns {Promise<void> }
90+ */
91+ async function revert ( path , toVersion , progressCb , isDryRun ) {
6892 if ( ! toVersion ) {
6993 throw new Error ( 'When reverting migrations, you have to specify to which version to revert!' )
7094 }
@@ -73,19 +97,19 @@ async function revert(store, toVersion, progressCb, isDryRun) {
7397 throw new Error ( 'Version has to be positive integer!' )
7498 }
7599
76- const currentVersion = await repo_version . getVersion ( store )
100+ const currentVersion = await repoVersion . getVersion ( path )
77101 if ( currentVersion === toVersion ) {
78102 log ( 'Nothing to revert, skipping reverting.' )
79103 return
80104 }
81105
82106 let { reversible, problematicMigration} = verifyReversibility ( currentVersion , toVersion )
83107 if ( ! reversible ) {
84- throw new Error ( `Migration version ${ problematicMigration } is not possible to revert! Cancelling reversion.` )
108+ throw new errors . NonReversibleMigration ( `Migration version ${ problematicMigration } is not possible to revert! Cancelling reversion.` )
85109 }
86110
87111 let lock
88- if ( ! isDryRun ) lock = await repo_lock . lock ( currentVersion , store . path )
112+ if ( ! isDryRun ) lock = await repoLock . lock ( currentVersion , path )
89113 let counter = 0 , totalMigrations = currentVersion - toVersion
90114 const reversedMigrationArray = migrations . reverse ( )
91115 for ( let migration of reversedMigrationArray ) {
@@ -98,7 +122,7 @@ async function revert(store, toVersion, progressCb, isDryRun) {
98122 log ( `Reverting migration version ${ migration . version } ` )
99123 if ( ! isDryRun ) {
100124 try {
101- await migration . revert ( store )
125+ await migration . revert ( path , isBrowser )
102126 } catch ( e ) {
103127 e . message = `During reversion to version ${ migration . version } exception was raised: ${ e . message } `
104128 throw e
@@ -109,15 +133,20 @@ async function revert(store, toVersion, progressCb, isDryRun) {
109133 }
110134 }
111135
112- if ( ! isDryRun ) await repo_version . setVersion ( store , toVersion )
136+ if ( ! isDryRun ) await repoVersion . setVersion ( path , toVersion )
113137 log ( `All migrations successfully reverted to version ${ toVersion } !` )
114138
115139 if ( ! isDryRun ) await lock . close ( )
116- await store . close ( )
117140}
118-
119141exports . revert = revert
120142
143+ /**
144+ * Function checks if all migrations in given range supports reversion.
145+ *
146+ * @param {int } fromVersion
147+ * @param {int } toVersion
148+ * @returns {object }
149+ */
121150function verifyReversibility ( fromVersion , toVersion ) {
122151 const reversedMigrationArray = migrations . reverse ( )
123152 for ( let migration of reversedMigrationArray ) {
0 commit comments