2019-11-27 21:41:03 +05:00
|
|
|
import Storage from "../helpers/storage";
|
2019-11-29 21:28:31 +05:00
|
|
|
import fuzzysearch from "fuzzysearch";
|
|
|
|
|
import ff from "fast-filter";
|
2019-12-01 00:13:59 +05:00
|
|
|
import { extractValues } from "../utils";
|
2019-11-27 21:41:03 +05:00
|
|
|
|
2019-11-27 21:58:41 +05:00
|
|
|
const KEYS = {
|
2019-12-04 15:08:01 +05:00
|
|
|
notes: "notes",
|
|
|
|
|
notebooks: "notebooks"
|
2019-11-27 21:58:41 +05:00
|
|
|
};
|
|
|
|
|
|
2019-11-27 21:41:03 +05:00
|
|
|
class Database {
|
|
|
|
|
constructor(storage) {
|
|
|
|
|
this.storage = new Storage(storage);
|
|
|
|
|
this.notes = {};
|
2019-12-04 15:08:01 +05:00
|
|
|
this.notebooks = {};
|
2019-12-04 17:16:21 +05:00
|
|
|
|
|
|
|
|
// fill data
|
2019-12-04 17:21:07 +05:00
|
|
|
for (let key of extractValues(KEYS)) {
|
|
|
|
|
this.storage.read(key).then(data => (this[key] = data || {}));
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
2019-11-27 21:41:03 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-12-04 17:16:21 +05:00
|
|
|
* Get all notes
|
2019-11-27 21:41:03 +05:00
|
|
|
*/
|
2019-12-04 18:27:34 +05:00
|
|
|
getNotes() {
|
2019-12-01 00:13:59 +05:00
|
|
|
return extractValues(this.notes);
|
2019-11-27 21:41:03 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-12-04 17:16:21 +05:00
|
|
|
* Adds or updates a note
|
2019-11-27 21:41:03 +05:00
|
|
|
* @param {object} note The note to add or update
|
|
|
|
|
*/
|
|
|
|
|
async addNote(note) {
|
2019-12-05 15:58:11 +05:00
|
|
|
if (!note || (!note.title && !note.content)) return undefined;
|
2019-11-27 21:41:03 +05:00
|
|
|
|
|
|
|
|
let timestamp = note.dateCreated || Date.now();
|
|
|
|
|
//add or update a note into the database
|
|
|
|
|
let title =
|
|
|
|
|
note.title ||
|
|
|
|
|
note.content.text
|
|
|
|
|
.split(" ")
|
|
|
|
|
.slice(0, 3)
|
|
|
|
|
.join(" ");
|
|
|
|
|
this.notes[timestamp] = {
|
|
|
|
|
title,
|
|
|
|
|
content: note.content,
|
|
|
|
|
pinned: note.pinned || false,
|
|
|
|
|
tags: note.tags || [],
|
|
|
|
|
notebooks: note.notebooks || [],
|
|
|
|
|
colors: note.colors || [],
|
|
|
|
|
favorite: note.favorite || false,
|
2019-12-01 00:01:09 +05:00
|
|
|
headline: note.content.text.substring(0, 150) + "...",
|
2019-11-27 21:41:03 +05:00
|
|
|
length: note.content.text.length,
|
|
|
|
|
dateEditted: Date.now(),
|
|
|
|
|
dateCreated: timestamp
|
|
|
|
|
};
|
2019-11-27 21:58:41 +05:00
|
|
|
await this.storage.write(KEYS.notes, this.notes);
|
2019-11-27 21:41:03 +05:00
|
|
|
return timestamp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-12-04 17:16:21 +05:00
|
|
|
* Deletes one or more notes
|
2019-11-27 21:41:03 +05:00
|
|
|
* @param {array} notes the notes to be deleted
|
|
|
|
|
*/
|
|
|
|
|
async deleteNotes(notes) {
|
2019-12-05 15:58:11 +05:00
|
|
|
await deleteItems.call(this, notes, KEYS.notes);
|
2019-11-27 21:41:03 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-12-04 17:16:21 +05:00
|
|
|
* Gets a note
|
2019-11-27 21:41:03 +05:00
|
|
|
* @param {string} id the id of the note (must be a timestamp)
|
|
|
|
|
*/
|
|
|
|
|
getNote(id) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return getItem.call(this, id, KEYS.notes);
|
2019-11-27 21:41:03 +05:00
|
|
|
}
|
|
|
|
|
|
2019-11-29 21:28:31 +05:00
|
|
|
/**
|
2019-12-04 17:16:21 +05:00
|
|
|
* Searches all notes with the given query
|
2019-11-29 21:28:31 +05:00
|
|
|
* @param {string} query the search query
|
2019-12-04 17:16:21 +05:00
|
|
|
* @returns An array containing the filtered notes
|
2019-11-29 21:28:31 +05:00
|
|
|
*/
|
2019-12-04 18:27:34 +05:00
|
|
|
searchNotes(query) {
|
2019-12-03 03:20:01 +05:00
|
|
|
if (!query) return [];
|
2019-11-29 21:28:31 +05:00
|
|
|
return ff(
|
2019-12-04 17:16:21 +05:00
|
|
|
extractValues(this.notes),
|
2019-12-01 00:13:59 +05:00
|
|
|
v => fuzzysearch(query, v.title + " " + v.content.text),
|
2019-11-29 21:28:31 +05:00
|
|
|
this
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-04 17:16:21 +05:00
|
|
|
/**
|
|
|
|
|
* Get all notebooks
|
|
|
|
|
* @returns An array containing all the notebooks
|
|
|
|
|
*/
|
2019-12-04 18:27:34 +05:00
|
|
|
getNotebooks() {
|
2019-12-04 15:08:01 +05:00
|
|
|
return extractValues(this.notebooks);
|
|
|
|
|
}
|
2019-12-04 17:16:21 +05:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a notebook
|
|
|
|
|
* @param {object} notebook The notebook to add
|
|
|
|
|
* @returns The ID of the added notebook
|
|
|
|
|
*/
|
2019-12-04 15:08:01 +05:00
|
|
|
async addNotebook(notebook) {
|
|
|
|
|
if (!notebook || !notebook.title) return;
|
|
|
|
|
const id = notebook.dateCreated || Date.now();
|
|
|
|
|
let topics = {};
|
2019-12-04 18:27:34 +05:00
|
|
|
if (notebook.topics) {
|
|
|
|
|
for (let topic of notebook.topics) {
|
|
|
|
|
topics[topic] = [];
|
|
|
|
|
}
|
2019-12-04 15:08:01 +05:00
|
|
|
}
|
|
|
|
|
this.notebooks[id] = {
|
|
|
|
|
title: notebook.title,
|
|
|
|
|
description: notebook.description,
|
2019-12-04 18:27:34 +05:00
|
|
|
dateCreated: id,
|
2019-12-04 15:08:01 +05:00
|
|
|
pinned: notebook.pinned || false,
|
|
|
|
|
favorite: notebook.favorite || false,
|
|
|
|
|
topics,
|
|
|
|
|
totalNotes: 0,
|
|
|
|
|
tags: [],
|
|
|
|
|
colors: []
|
|
|
|
|
};
|
|
|
|
|
await this.storage.write(KEYS.notebooks, this.notebooks);
|
|
|
|
|
return id;
|
|
|
|
|
}
|
2019-11-27 21:41:03 +05:00
|
|
|
|
2019-12-04 17:16:21 +05:00
|
|
|
/**
|
|
|
|
|
* Add a topic to the notebook
|
|
|
|
|
* @param {number} notebookId The ID of notebook
|
|
|
|
|
* @param {string} topic The topic to add
|
|
|
|
|
*/
|
|
|
|
|
addTopicToNotebook(notebookId, topic) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return notebookTopicFn.call(
|
|
|
|
|
this,
|
2019-12-04 17:16:21 +05:00
|
|
|
notebookId,
|
|
|
|
|
topic,
|
2019-12-04 18:27:34 +05:00
|
|
|
notebook => ((notebook.topics[topic] = []), true)
|
2019-12-04 17:16:21 +05:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete a topic from the notebook
|
|
|
|
|
* @param {number} notebookId The ID of the notebook
|
|
|
|
|
* @param {string} topic The topic to delete
|
|
|
|
|
*/
|
|
|
|
|
deleteTopicFromNotebook(notebookId, topic) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return notebookTopicFn.call(this, notebookId, topic, notebook => {
|
2019-12-04 18:27:34 +05:00
|
|
|
if (!notebook.topics[topic]) return false;
|
|
|
|
|
delete notebook.topics[topic];
|
|
|
|
|
return true;
|
|
|
|
|
});
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a note to a topic in a notebook
|
|
|
|
|
* @param {number} notebookId The ID of the notebook
|
|
|
|
|
* @param {string} topic The topic to add note to
|
|
|
|
|
* @param {number} noteId The ID of the note
|
|
|
|
|
*/
|
|
|
|
|
addNoteToTopic(notebookId, topic, noteId) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return notebookTopicFn.call(this, notebookId, topic, notebook => {
|
2019-12-04 18:27:34 +05:00
|
|
|
if (!notebook.topics.hasOwnProperty(topic)) return false;
|
|
|
|
|
let nbTopic = notebook.topics[topic];
|
|
|
|
|
notebook.topics[topic][nbTopic.length] = noteId;
|
|
|
|
|
return true;
|
2019-12-04 17:16:21 +05:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete a note from a topic in a notebook
|
|
|
|
|
* @param {number} notebookId The ID of the notebook
|
|
|
|
|
* @param {string} topic The topic to delete note from
|
|
|
|
|
* @param {number} noteId The ID of the note
|
|
|
|
|
*/
|
|
|
|
|
deleteNoteFromTopic(notebookId, topic, noteId) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return notebookTopicFn.call(this, notebookId, topic, notebook => {
|
2019-12-04 18:27:34 +05:00
|
|
|
if (!notebook.topics[topic]) return false;
|
|
|
|
|
let nbTopic = notebook.topics[topic];
|
|
|
|
|
let index = nbTopic.indexOf(noteId);
|
2019-12-04 17:16:21 +05:00
|
|
|
if (index <= -1) return;
|
2019-12-04 18:27:34 +05:00
|
|
|
notebook.topics[topic].splice(index, 1);
|
|
|
|
|
return true;
|
2019-12-04 17:16:21 +05:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get all the notes in a topic
|
|
|
|
|
* @param {number} notebookId The ID of the notebook
|
|
|
|
|
* @param {string} topic The topic
|
|
|
|
|
* @returns An array containing the topic notes
|
|
|
|
|
*/
|
|
|
|
|
getTopic(notebookId, topic) {
|
|
|
|
|
if (!notebookId || !topic || !this.notebooks[notebookId]) return;
|
|
|
|
|
let notebook = this.notebooks[notebookId];
|
|
|
|
|
if (!notebook.topics[topic]) return;
|
2019-12-04 17:21:07 +05:00
|
|
|
let nbTopic = notebook.topics[topic];
|
|
|
|
|
if (nbTopic.length <= 0) return [];
|
|
|
|
|
return nbTopic.map(note => this.getNote(note));
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a notebook
|
|
|
|
|
* @param {number} id The ID of the notebook
|
|
|
|
|
* @returns The notebook
|
|
|
|
|
*/
|
|
|
|
|
getNotebook(id) {
|
2019-12-05 15:58:11 +05:00
|
|
|
return getItem.call(this, id, KEYS.notebooks);
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete notebooks
|
|
|
|
|
* @param {array} notebooks The notebooks to delete
|
|
|
|
|
*/
|
|
|
|
|
async deleteNotebooks(notebooks) {
|
2019-12-05 15:58:11 +05:00
|
|
|
await deleteItems.call(this, notebooks, KEYS.notebooks);
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
2019-12-05 15:58:11 +05:00
|
|
|
}
|
2019-12-04 17:16:21 +05:00
|
|
|
|
2019-12-05 15:58:11 +05:00
|
|
|
export default Database;
|
2019-12-04 17:16:21 +05:00
|
|
|
|
2019-12-05 15:58:11 +05:00
|
|
|
async function deleteItems(items, key) {
|
|
|
|
|
if (!items || items.length <= 0 || !this[key] || this[key].length <= 0)
|
|
|
|
|
return; //TODO add test
|
|
|
|
|
for (let item of items) {
|
|
|
|
|
if (this[key].hasOwnProperty(item.dateCreated)) {
|
|
|
|
|
delete this[key][item.dateCreated];
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
|
|
|
|
}
|
2019-12-05 15:58:11 +05:00
|
|
|
await this.storage.write(key, this[key]);
|
|
|
|
|
}
|
2019-12-04 17:16:21 +05:00
|
|
|
|
2019-12-05 15:58:11 +05:00
|
|
|
function notebookTopicFn(notebookId, topic, fn) {
|
|
|
|
|
if (!notebookId || !topic || !this.notebooks[notebookId]) return;
|
|
|
|
|
let notebook = this.notebooks[notebookId];
|
|
|
|
|
if (fn(notebook)) {
|
|
|
|
|
this.notes[notebookId] = notebook;
|
|
|
|
|
return this.storage.write(KEYS.notebooks, this.notebooks);
|
2019-12-04 17:16:21 +05:00
|
|
|
}
|
2019-12-05 15:58:11 +05:00
|
|
|
//TODO add test
|
|
|
|
|
return Promise.resolve();
|
2019-11-27 21:41:03 +05:00
|
|
|
}
|
|
|
|
|
|
2019-12-05 15:58:11 +05:00
|
|
|
function getItem(id, key) {
|
|
|
|
|
if (this[key].hasOwnProperty(id)) {
|
|
|
|
|
return this[key][id];
|
|
|
|
|
}
|
|
|
|
|
}
|