diff --git a/packages/core/__tests__/notebooks.test.js b/packages/core/__tests__/notebooks.test.js index bc8c8ad95..8067e24ef 100644 --- a/packages/core/__tests__/notebooks.test.js +++ b/packages/core/__tests__/notebooks.test.js @@ -1,4 +1,9 @@ -import { StorageInterface, notebookTest, TEST_NOTEBOOK } from "./utils"; +import { + StorageInterface, + notebookTest, + TEST_NOTEBOOK, + TEST_NOTE +} from "./utils"; beforeEach(async () => { StorageInterface.clear(); @@ -54,3 +59,17 @@ test("unfavorite a notebook", () => let notebook = db.notebooks.get(id); expect(notebook.favorite).toBe(false); })); + +test("delete a notebook", () => + notebookTest().then(async ({ db, id }) => { + let noteId = await db.notes.add(TEST_NOTE); + await db.notebooks + .topics(id) + .topic("General") + .add(noteId); + let note = await db.notes.get(noteId); + expect(note.notebook.id).toBe(id); + await db.notebooks.delete(id); + note = await db.notes.get(noteId); + expect(note.notebook.id).toBeUndefined(); + })); diff --git a/packages/core/__tests__/notes.test.js b/packages/core/__tests__/notes.test.js index 456a201b3..09f1ae5bd 100644 --- a/packages/core/__tests__/notes.test.js +++ b/packages/core/__tests__/notes.test.js @@ -4,7 +4,8 @@ import { noteTest, groupedTest, LONG_TEXT, - TEST_NOTE + TEST_NOTE, + TEST_NOTEBOOK } from "./utils"; beforeEach(async () => { @@ -23,7 +24,6 @@ test("add invalid note", () => test("add note", () => noteTest().then(async ({ db, id }) => { - expect(id).toBeDefined(); let note = db.notes.get(id); expect(note).toBeDefined(); expect(note.content.text).toStrictEqual(TEST_NOTE.content.text); @@ -31,17 +31,22 @@ test("add note", () => test("get delta of note", () => noteTest().then(async ({ db, id }) => { - expect(id).toBeDefined(); let delta = await db.notes.delta(id); expect(delta).toStrictEqual(TEST_NOTE.content.delta); })); test("delete note", () => noteTest().then(async ({ db, id }) => { - expect(id).toBeDefined(); + let notebookId = await db.notebooks.add(TEST_NOTEBOOK); + let topic = await db.notebooks + .topics(notebookId) + .topic("General") + .add(id); + expect(topic.all.findIndex(v => v.id === id)).toBeGreaterThan(-1); await db.notes.delete(id); let note = db.notes.get(id); expect(note).toBeUndefined(); + expect(topic.all.findIndex(v => v.id === id)).toBe(-1); })); test("get all notes", () => diff --git a/packages/core/collections/notebooks.js b/packages/core/collections/notebooks.js index 52a5e4501..a8abccdce 100644 --- a/packages/core/collections/notebooks.js +++ b/packages/core/collections/notebooks.js @@ -86,7 +86,16 @@ export default class Notebooks { return this.collection.getItem(id); } - delete(...ids) {} + async delete(...ids) { + for (let id of ids) { + let notebook = this.get(id); + if (!notebook) continue; + await this.collection.transaction(() => + this.topics(id).delete(...notebook.topics) + ); + await this.collection.removeItem(id); + } + } filter(query) { if (!query) return []; diff --git a/packages/core/collections/notes.js b/packages/core/collections/notes.js index 32e11c59f..5609898bc 100644 --- a/packages/core/collections/notes.js +++ b/packages/core/collections/notes.js @@ -161,24 +161,17 @@ export default class Notes { } async delete(...ids) { - if (!ids || ids.length <= 0) { - return false; - } - for (let id of ids) { let item = this.get(id); if (!id) continue; - /* TODO if ( - item.notebook.hasOwnProperty("topic") && - !(await this.deleteNoteFromTopic( - item.notebook.id, - item.notebook.topic, - item.dateCreated - )) - ) { - continue; + if (item.notebook && item.notebook.id && item.notebook.topic) { + await this.collection.transaction(() => + this.notebooks + .topics(item.notebook.id) + .topic(item.notebook.topic) + .delete(id) + ); } - */ for (let tag of item.tags) { await this.tagsCollection.remove(tag); } @@ -219,11 +212,7 @@ export default class Notes { let topic = this.notebooks.topics(to.id).topic(to.topic); if (!topic) throw new Error("No such topic exists."); await topic.transaction(async () => { - for (let id of noteIds) { - let note = this.get(id); - if (!note) continue; - await topic.add(id); - } + await topic.add(...noteIds); }); } diff --git a/packages/core/collections/topics.js b/packages/core/collections/topics.js index e507dcedb..60c2bfd91 100644 --- a/packages/core/collections/topics.js +++ b/packages/core/collections/topics.js @@ -42,6 +42,9 @@ export default class Topics { t => t.title === topic.title || topic ); if (index <= -1) continue; + topic = notebook.topics[index]; + let t = this.topic(topic); + await t.transaction(() => t.delete(...topic.notes), false); notebook.topics.splice(index, 1); } await this.notebooks.add({ @@ -63,51 +66,55 @@ class Topic { this.transactionOpen = false; } - transaction(ops) { + transaction(ops, saveAfter = true) { this.transactionOpen = true; - return ops().then(() => { + ops().then(() => { this.transactionOpen = false; }); + if (!saveAfter) return this; + return this.save(); } has(noteId) { return this.topic.notes.findIndex(n => n === noteId) > -1; } - async add(noteId) { - let note = this.topics.notes.get(noteId); - if (this.has(noteId) || !note) return this; + async add(...noteIds) { + for (let noteId of noteIds) { + let note = this.topics.notes.get(noteId); + if (this.has(noteId) || !note) return this; - this.topic.notes.push(noteId); + this.topic.notes.push(noteId); - if (note.notebook && note.notebook.id && note.notebook.topic) { - if ( - note.notebook.id === this.topics.notebookId && - note.notebook.topic === this.topic.title - ) - return this; - await this.topics.notebooks - .topics(note.notebook.id) - .topic(note.notebook.topic) - .delete(note.id); + if (note.notebook && note.notebook.id && note.notebook.topic) { + if ( + note.notebook.id === this.topics.notebookId && + note.notebook.topic === this.topic.title + ) + return this; + await this.topics.notebooks + .topics(note.notebook.id) + .topic(note.notebook.topic) + .delete(note.id); + } + await this.topics.notes.add({ + id: noteId, + notebook: { id: this.topics.notebookId, topic: this.topic.title } + }); } - - await this.topics.notes.add({ - id: noteId, - notebook: { id: this.topics.notebookId, topic: this.topic.title } - }); - return await this.save(); } - async delete(noteId) { - if (!this.has(noteId)) return this; - let index = this.topic.notes.findIndex(n => n === noteId); - this.topic.notes.splice(index, 1); - await this.topics.notes.add({ - id: noteId, - notebook: {} - }); + async delete(...noteIds) { + for (let noteId of noteIds) { + if (!this.has(noteId)) return this; + let index = this.topic.notes.findIndex(n => n === noteId); + this.topic.notes.splice(index, 1); + await this.topics.notes.add({ + id: noteId, + notebook: {} + }); + } return await this.save(); } diff --git a/packages/core/database/cached-collection.js b/packages/core/database/cached-collection.js index e6654d5a4..f9f9a0a25 100644 --- a/packages/core/database/cached-collection.js +++ b/packages/core/database/cached-collection.js @@ -4,6 +4,7 @@ export default class CachedCollection { constructor(context, type) { this.map = new Map(); this.indexer = new Indexer(context, type); + this.transactionOpen = false; } async init() { @@ -13,7 +14,17 @@ export default class CachedCollection { } } + /** + * + * @param {Promise} ops + */ + transaction(ops) { + this.transactionOpen = true; + return ops().then(() => Promise.resolve((this.transactionOpen = false))); + } + async addItem(item) { + if (this.transactionOpen) return; if (!item.id) throw new Error("The item must contain the id field."); let exists = this.map.has(item.id); @@ -24,6 +35,7 @@ export default class CachedCollection { } async updateItem(item) { + if (this.transactionOpen) return; if (!item.id) throw new Error("The item must contain the id field."); this.map.set(item.id, item); @@ -31,6 +43,7 @@ export default class CachedCollection { } async removeItem(id) { + if (this.transactionOpen) return; if (this.map.delete(id)) { this.indexer.remove(id); await this.indexer.deindex(id);