core: add collection to hold all item<->item references

This commit is contained in:
Abdullah Atta
2022-11-17 14:11:22 +05:00
committed by Abdullah Atta
parent a8f1fbf6a1
commit baa06ebd6e
6 changed files with 164 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ import Pricing from "./pricing";
import { logger } from "../logger";
import Shortcuts from "../collections/shortcuts";
import Reminders from "../collections/reminders";
import Relations from "../collections/relations";
/**
* @type {EventSource}
@@ -146,6 +147,8 @@ class Database {
this.shortcuts = await Shortcuts.new(this, "shortcuts");
/**@type {Reminders} */
this.reminders = await Reminders.new(this, "reminders");
/**@type {Relations} */
this.relations = await Relations.new(this, "relations");
this.trash = new Trash(this);

View File

@@ -86,6 +86,10 @@ class Migrations {
index: () => this._db.reminders.raw,
dbCollection: this._db.reminders
},
{
index: () => this._db.relations.raw,
dbCollection: this._db.relations
},
{
index: () => this._db.noteHistory.sessionContent.all(),
dbCollection: this._db.noteHistory

View File

@@ -44,6 +44,7 @@ class Collector {
content: await this._db.content.all(),
attachment: this._db.attachments.syncable,
reminder: this._db.reminders.raw,
relation: this._db.relations.raw,
settings: [this._db.settings.raw]
};

View File

@@ -50,6 +50,10 @@ class Merger {
get: (id) => this._db.reminders.reminder(id),
set: (item) => this._db.reminders.merge(item)
},
relation: {
get: (id) => this._db.relations.relation(id),
set: (item) => this._db.relations.merge(item)
},
notebook: {
threshold: 1000,
get: (id) => this._db.notebooks.notebook(id),

View File

@@ -0,0 +1,148 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import getId from "../utils/id";
import Collection from "./collection";
/**
* @typedef {{
* id: string;
* type: string;
* }} ItemReference
*
* @typedef {{
* id: string;
* type: string;
* from: ItemReference;
* to: ItemReference;
* dateCreated: number;
* dateModified: number;
* }} Relation
*/
export default class Relations extends Collection {
async merge(relation) {
if (!relation) return;
await this._collection.addItem(relation);
}
/**
*
* @param {ItemReference} from
* @param {ItemReference} to
*/
async add(from, to) {
if (
this.all.find(
(a) =>
compareItemReference(a.from, from) && compareItemReference(a.to, to)
)
)
return;
const relation = {
id: getId(),
type: "relation",
dateCreated: Date.now(),
dateModified: Date.now(),
from: { id: from.id, type: from.type },
to: { id: to.id, type: to.type }
};
await this._collection.addItem(relation);
}
/**
*
* @param {ItemReference} reference
* @param {string} type
*/
from(reference, type) {
const relations = this.all.filter(
(a) => compareItemReference(a.from, reference) && a.to.type === type
);
return this.resolve(relations, "to");
}
/**
*
* @param {ItemReference} reference
* @param {string} type
*/
to(reference, type) {
const relations = this.all.filter(
(a) => compareItemReference(a.to, reference) && a.from.type === type
);
return this.resolve(relations, "from");
}
get raw() {
return this._collection.getRaw();
}
/**
* @return {Relation[]}
*/
get all() {
return this._collection.getItems();
}
/**
* @return {Relation}
*/
relation(id) {
return this._collection.getItem(id);
}
async remove(...ids) {
for (const id of ids) {
await this._collection.removeItem(id);
}
}
/**
* @param {Relation[]} relations
* @param {"from" | "to"} resolveType
* @private
*/
async resolve(relations, resolveType) {
const items = [];
for (const relation of relations) {
const reference = resolveType === "from" ? relation.from : relation.to;
let item = null;
switch (reference.type) {
case "reminder":
item = this._db.reminders.reminder(reference.id);
break;
}
if (!item) await this.remove(relation.id);
}
return items;
}
}
/**
*
* @param {ItemReference} a
* @param {ItemReference} b
*/
function compareItemReference(a, b) {
return a.id === b.id && a.type === b.type;
}

View File

@@ -179,6 +179,10 @@ export default class Backup {
index: () => data["reminders"],
dbCollection: this._db.reminders
},
{
index: () => data["relations"],
dbCollection: this._db.relations
},
{
index: () => data["notehistory"],
dbCollection: this._db.noteHistory,