mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 06:59:31 +01:00
core: make item migration fall through all db versions
this was not exactly a bug but it can cause a lot of unintended behaviour. Previously, you'd have to manually specify which version the item migration should jump to. This was buggy and poorly designed. This change makes the item iterate over all the db migrations one by one automatically. For example: An item at version 5.2 will go through: - 5.3 - 5.4 - and so on
This commit is contained in:
committed by
Abdullah Atta
parent
9701a3d660
commit
c09715d053
@@ -17,10 +17,9 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { migrations } from "../../migrations";
|
import { migrateItem } from "../../migrations";
|
||||||
import SparkMD5 from "spark-md5";
|
import SparkMD5 from "spark-md5";
|
||||||
import setManipulator from "../../utils/set";
|
import setManipulator from "../../utils/set";
|
||||||
import { CURRENT_DATABASE_VERSION } from "../../common";
|
|
||||||
import { logger } from "../../logger";
|
import { logger } from "../../logger";
|
||||||
|
|
||||||
class Merger {
|
class Merger {
|
||||||
@@ -136,19 +135,7 @@ class Merger {
|
|||||||
deserialized.type = type;
|
deserialized.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!migrations[version]) {
|
return migrateItem(deserialized, version, type, this._db);
|
||||||
throw new Error(
|
|
||||||
version > CURRENT_DATABASE_VERSION
|
|
||||||
? `Cannot migrate item to v${version}. Please update your client to the latest version.`
|
|
||||||
: `Could not migrate item to v${version}. Please report this bug to the developers.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const migrate = migrations[version][type];
|
|
||||||
if (migrate) {
|
|
||||||
return await migrate(deserialized, this._db);
|
|
||||||
}
|
|
||||||
return deserialized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _deserialize(item, migrate = true) {
|
async _deserialize(item, migrate = true) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { migrations } from "../migrations";
|
import { migrateItem } from "../migrations";
|
||||||
|
|
||||||
class Migrator {
|
class Migrator {
|
||||||
async migrate(db, collections, get, version) {
|
async migrate(db, collections, get, version) {
|
||||||
@@ -40,8 +40,12 @@ class Migrator {
|
|||||||
item.type = "tiptap";
|
item.type = "tiptap";
|
||||||
}
|
}
|
||||||
|
|
||||||
const migrate = migrations[version][item.type || collection.type];
|
item = await migrateItem(
|
||||||
if (migrate) item = await migrate(item, db);
|
item,
|
||||||
|
version,
|
||||||
|
item.type || collection.type,
|
||||||
|
db
|
||||||
|
);
|
||||||
|
|
||||||
if (collection.dbCollection.merge) {
|
if (collection.dbCollection.merge) {
|
||||||
await collection.dbCollection.merge(item);
|
await collection.dbCollection.merge(item);
|
||||||
|
|||||||
@@ -19,88 +19,108 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
import { parseHTML } from "./utils/html-parser";
|
import { parseHTML } from "./utils/html-parser";
|
||||||
import { decodeHTML5 } from "entities";
|
import { decodeHTML5 } from "entities";
|
||||||
|
import { CURRENT_DATABASE_VERSION } from "./common";
|
||||||
|
|
||||||
export const migrations = {
|
const migrations = [
|
||||||
5.0: {},
|
{ version: 5.0, types: {} },
|
||||||
5.1: {},
|
{ version: 5.1, types: {} },
|
||||||
5.2: {
|
{
|
||||||
note: replaceDateEditedWithDateModified(),
|
version: 5.2,
|
||||||
notebook: (item) => {
|
types: {
|
||||||
item = replaceDateEditedWithDateModified()(item);
|
note: replaceDateEditedWithDateModified(false),
|
||||||
return migrations["5.6"].notebook(item);
|
notebook: replaceDateEditedWithDateModified(false),
|
||||||
},
|
tag: replaceDateEditedWithDateModified(true),
|
||||||
tag: replaceDateEditedWithDateModified(true),
|
attachment: replaceDateEditedWithDateModified(true),
|
||||||
attachment: replaceDateEditedWithDateModified(true),
|
trash: replaceDateEditedWithDateModified(),
|
||||||
trash: replaceDateEditedWithDateModified(),
|
tiny: (item) => {
|
||||||
tiny: (item) => {
|
item = replaceDateEditedWithDateModified(false)(item);
|
||||||
item = replaceDateEditedWithDateModified()(item);
|
|
||||||
|
|
||||||
if (!item.data || item.data.iv) return migrations["5.3"].tiny(item);
|
if (!item.data || item.data.iv) return item;
|
||||||
|
|
||||||
item.data = removeToxClassFromChecklist(wrapTablesWithDiv(item.data));
|
item.data = removeToxClassFromChecklist(wrapTablesWithDiv(item.data));
|
||||||
return migrations["5.3"].tiny(item);
|
return item;
|
||||||
},
|
},
|
||||||
settings: (item) => {
|
settings: replaceDateEditedWithDateModified(true)
|
||||||
item = replaceDateEditedWithDateModified(true)(item);
|
|
||||||
return migrations["5.6"].settings(item);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
5.3: {
|
{
|
||||||
tiny: (item) => {
|
version: 5.3,
|
||||||
if (!item.data || item.data.iv) return migrations["5.4"].tiny(item);
|
types: {
|
||||||
item.data = decodeWrappedTableHtml(item.data);
|
tiny: (item) => {
|
||||||
return migrations["5.4"].tiny(item);
|
if (!item.data || item.data.iv) return item;
|
||||||
}
|
item.data = decodeWrappedTableHtml(item.data);
|
||||||
},
|
return item;
|
||||||
5.4: {
|
|
||||||
tiny: (item) => {
|
|
||||||
if (!item.data || item.data.iv) return item;
|
|
||||||
item.type = "tiptap";
|
|
||||||
item.data = tinyToTiptap(item.data);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
5.5: {},
|
|
||||||
5.6: {
|
|
||||||
notebook: (item) => {
|
|
||||||
if (!item.topics) return item;
|
|
||||||
|
|
||||||
item.topics = item.topics.map((topic) => {
|
|
||||||
delete topic.notes;
|
|
||||||
return topic;
|
|
||||||
});
|
|
||||||
return item;
|
|
||||||
},
|
|
||||||
settings: async (item, db) => {
|
|
||||||
if (!item.pins) return item;
|
|
||||||
|
|
||||||
for (const pin of item.pins) {
|
|
||||||
if (!pin.data) continue;
|
|
||||||
|
|
||||||
await db.shortcuts.add({
|
|
||||||
item: {
|
|
||||||
type: pin.type,
|
|
||||||
id: pin.data.id,
|
|
||||||
notebookId: pin.data.notebookId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
delete item.pins;
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
5.7: {
|
{
|
||||||
note: false,
|
version: 5.4,
|
||||||
shortcut: false,
|
types: {
|
||||||
notebook: false,
|
tiny: (item) => {
|
||||||
tag: false,
|
if (!item.data || item.data.iv) return item;
|
||||||
attachment: false,
|
item.type = "tiptap";
|
||||||
trash: false,
|
item.data = tinyToTiptap(item.data);
|
||||||
tiny: false,
|
return item;
|
||||||
tiptap: false,
|
}
|
||||||
settings: false
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 5.5,
|
||||||
|
types: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 5.6,
|
||||||
|
types: {
|
||||||
|
notebook: (item) => {
|
||||||
|
if (!item.topics) return item;
|
||||||
|
|
||||||
|
item.topics = item.topics.map((topic) => {
|
||||||
|
delete topic.notes;
|
||||||
|
return topic;
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
settings: async (item, db) => {
|
||||||
|
if (!item.pins) return item;
|
||||||
|
|
||||||
|
for (const pin of item.pins) {
|
||||||
|
if (!pin.data) continue;
|
||||||
|
await db.shortcuts.add({
|
||||||
|
item: {
|
||||||
|
type: pin.type,
|
||||||
|
id: pin.data.id,
|
||||||
|
notebookId: pin.data.notebookId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
delete item.pins;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ version: 5.7, types: {} }
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function migrateItem(item, version, type, database) {
|
||||||
|
let migrationStartIndex = migrations.findIndex((m) => m.version === version);
|
||||||
|
if (migrationStartIndex <= -1) {
|
||||||
|
throw new Error(
|
||||||
|
version > CURRENT_DATABASE_VERSION
|
||||||
|
? `Please update the app to the latest version.`
|
||||||
|
: `You seem to be on a very outdated version. Please update the app to the latest version.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
for (; migrationStartIndex < migrations.length; ++migrationStartIndex) {
|
||||||
|
const migration = migrations[migrationStartIndex];
|
||||||
|
if (migration.version === CURRENT_DATABASE_VERSION) break;
|
||||||
|
|
||||||
|
const itemMigrator = migration.types[type];
|
||||||
|
if (!itemMigrator) continue;
|
||||||
|
item = await itemMigrator(item, database);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
function replaceDateEditedWithDateModified(removeDateEditedProperty = false) {
|
function replaceDateEditedWithDateModified(removeDateEditedProperty = false) {
|
||||||
return function (item) {
|
return function (item) {
|
||||||
|
|||||||
Reference in New Issue
Block a user