created repository object to access entities

This commit is contained in:
azivner 2018-01-29 23:17:44 -05:00
parent 9a091408e3
commit 6fa6891496
12 changed files with 104 additions and 95 deletions

View File

@ -56,7 +56,7 @@ app.use((req, res, next) => {
// error handler // error handler
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
log.error(err.message); log.info(err);
res.status(err.status || 500); res.status(err.status || 500);
res.send({ res.send({

View File

@ -4,7 +4,7 @@ const Entity = require('./entity');
class Attribute extends Entity { class Attribute extends Entity {
async getNote() { async getNote() {
return this.sql.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); return this.repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]);
} }
} }

View File

@ -1,8 +1,12 @@
"use strict"; "use strict";
const utils = require('../services/utils');
class Entity { class Entity {
constructor(sql, row) { constructor(repository, row) {
this.sql = sql; utils.assertArguments(repository, row)
this.repository = repository;
for (const key in row) { for (const key in row) {
this[key] = row[key]; this[key] = row[key];

View File

@ -3,28 +3,32 @@
const Entity = require('./entity'); const Entity = require('./entity');
class Note extends Entity { class Note extends Entity {
constructor(sql, row) { constructor(repository, row) {
super(sql, row); super(repository, row);
if (this.type === "code" && this.mime === "application/json") { if (this.isJson()) {
this.jsonContent = JSON.parse(this.content); this.jsonContent = JSON.parse(this.content);
} }
} }
isJson() {
return this.type === "code" && this.mime === "application/json";
}
async getAttributes() { async getAttributes() {
return this.sql.getEntities("SELECT * FROM attributes WHERE noteId = ?", [this.noteId]); return this.repository.getEntities("SELECT * FROM attributes WHERE noteId = ?", [this.noteId]);
} }
async getAttribute(name) { async getAttribute(name) {
return this.sql.getEntity("SELECT * FROM attributes WHERE noteId = ? AND name = ?", [this.noteId, name]); return this.repository.getEntity("SELECT * FROM attributes WHERE noteId = ? AND name = ?", [this.noteId, name]);
} }
async getRevisions() { async getRevisions() {
return this.sql.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]); return this.repository.getEntities("SELECT * FROM note_revisions WHERE noteId = ?", [this.noteId]);
} }
async getTrees() { async getTrees() {
return this.sql.getEntities("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); return this.repository.getEntities("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
} }
} }

View File

@ -4,7 +4,7 @@ const Entity = require('./entity');
class NoteRevision extends Entity { class NoteRevision extends Entity {
async getNote() { async getNote() {
return this.sql.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); return this.repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]);
} }
} }

View File

@ -4,11 +4,11 @@ const Entity = require('./entity');
class NoteTree extends Entity { class NoteTree extends Entity {
async getNote() { async getNote() {
return this.sql.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]); return this.repository.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND noteId = ?", [this.noteId]);
} }
async getParentNote() { async getParentNote() {
return this.sql.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND parentNoteId = ?", [this.parentNoteId]); return this.repository.getEntity("SELECT * FROM note_tree WHERE isDeleted = 0 AND parentNoteId = ?", [this.parentNoteId]);
} }
} }

View File

@ -4,11 +4,10 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const auth = require('../../services/auth'); const auth = require('../../services/auth');
const wrap = require('express-promise-wrap').wrap; const wrap = require('express-promise-wrap').wrap;
const sql = require('../../services/sql');
const notes = require('../../services/notes'); const notes = require('../../services/notes');
const protected_session = require('../../services/protected_session');
const attributes = require('../../services/attributes'); const attributes = require('../../services/attributes');
const script = require('../../services/script'); const script = require('../../services/script');
const Repository = require('../../services/repository');
router.post('/exec/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { router.post('/exec/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
@ -33,9 +32,11 @@ router.get('/startup', auth.checkApiAuth, wrap(async (req, res, next) => {
router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteId = req.params.noteId; const noteId = req.params.noteId;
const noteScript = (await notes.getNoteById(noteId, req)).content; const repository = new Repository(req);
const subTreeScripts = await getSubTreeScripts(noteId, [noteId], req); const noteScript = (await repository.getNote(noteId)).content;
const subTreeScripts = await getSubTreeScripts(noteId, [noteId], repository);
res.send(subTreeScripts + noteScript); res.send(subTreeScripts + noteScript);
})); }));
@ -48,15 +49,14 @@ async function getNoteWithSubtreeScript(noteId, req) {
return subTreeScripts + noteScript; return subTreeScripts + noteScript;
} }
async function getSubTreeScripts(parentId, includedNoteIds, dataKey) { async function getSubTreeScripts(parentId, includedNoteIds, repository) {
const children = await sql.getRows(`SELECT notes.noteId, notes.title, notes.content, notes.isProtected, notes.mime const children = await repository.getEntities(`
SELECT notes.*
FROM notes JOIN note_tree USING(noteId) FROM notes JOIN note_tree USING(noteId)
WHERE note_tree.isDeleted = 0 AND notes.isDeleted = 0 WHERE note_tree.isDeleted = 0 AND notes.isDeleted = 0
AND note_tree.parentNoteId = ? AND notes.type = 'code' AND note_tree.parentNoteId = ? AND notes.type = 'code'
AND (notes.mime = 'application/javascript' OR notes.mime = 'text/html')`, [parentId]); AND (notes.mime = 'application/javascript' OR notes.mime = 'text/html')`, [parentId]);
protected_session.decryptNotes(dataKey, children);
let script = "\r\n"; let script = "\r\n";
for (const child of children) { for (const child of children) {
@ -66,7 +66,7 @@ async function getSubTreeScripts(parentId, includedNoteIds, dataKey) {
includedNoteIds.push(child.noteId); includedNoteIds.push(child.noteId);
script += await getSubTreeScripts(child.noteId, includedNoteIds, dataKey); script += await getSubTreeScripts(child.noteId, includedNoteIds, repository);
if (child.mime === 'application/javascript') { if (child.mime === 'application/javascript') {
child.content = '<script>' + child.content + '</script>'; child.content = '<script>' + child.content + '</script>';

View File

@ -3,7 +3,7 @@
const sql = require('./sql'); const sql = require('./sql');
const utils = require('./utils'); const utils = require('./utils');
const sync_table = require('./sync_table'); const sync_table = require('./sync_table');
const protected_session = require('./protected_session'); const Repository = require('./repository');
async function getNoteAttributeMap(noteId) { async function getNoteAttributeMap(noteId) {
return await sql.getMap(`SELECT name, value FROM attributes WHERE noteId = ?`, [noteId]); return await sql.getMap(`SELECT name, value FROM attributes WHERE noteId = ?`, [noteId]);
@ -15,21 +15,19 @@ async function getNoteIdWithAttribute(name, value) {
} }
async function getNotesWithAttribute(dataKey, name, value) { async function getNotesWithAttribute(dataKey, name, value) {
const repository = new Repository(dataKey);
let notes; let notes;
if (value !== undefined) { if (value !== undefined) {
notes = await sql.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId) notes = await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)
WHERE notes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]); WHERE notes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
} }
else { else {
notes = await sql.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId) notes = await repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)
WHERE notes.isDeleted = 0 AND attributes.name = ?`, [name]); WHERE notes.isDeleted = 0 AND attributes.name = ?`, [name]);
} }
for (const note of notes) {
protected_session.decryptNote(dataKey, note);
}
return notes; return notes;
} }

View File

@ -5,21 +5,6 @@ const sync_table = require('./sync_table');
const attributes = require('./attributes'); const attributes = require('./attributes');
const protected_session = require('./protected_session'); const protected_session = require('./protected_session');
async function getNoteById(noteId, dataKey) {
const note = await sql.getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]);
protected_session.decryptNote(dataKey, note);
return note;
}
async function getJsonNoteById(noteId, dataKey) {
const note = await getNoteById(noteId, dataKey);
note.data = JSON.parse(note.content);
return note;
}
async function updateJsonNote(noteId, data) { async function updateJsonNote(noteId, data) {
const ret = await createNewNote(noteId, { const ret = await createNewNote(noteId, {
title: name, title: name,
@ -329,7 +314,6 @@ async function deleteNote(noteTreeId, sourceId) {
} }
module.exports = { module.exports = {
getNoteById,
createNewNote, createNewNote,
updateNote, updateNote,
deleteNote, deleteNote,

View File

@ -0,0 +1,62 @@
const sql = require('./sql');
const protected_session = require('./protected_session');
const Note = require('../entities/note');
const NoteRevision = require('../entities/note_revision');
const NoteTree = require('../entities/note_tree');
const Attribute = require('../entities/attribute');
class Repository {
constructor(dataKey) {
this.dataKey = protected_session.getDataKey(dataKey);
}
async getEntities(query, params = []) {
const rows = await sql.getRows(query, params);
for (const row of rows) {
row.dataKey = this.dataKey;
}
return rows.map(row => this.createEntityFromRow(row));
}
async getEntity(query, params = []) {
const row = await sql.getRowOrNull(query, params);
if (!row) {
return null;
}
row.dataKey = this.dataKey;
return this.createEntityFromRow(row);
}
async getNote(noteId) {
return await this.getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]);
}
createEntityFromRow(row) {
let entity;
if (row.attributeId) {
entity = new Attribute(this, row);
}
else if (row.noteRevisionId) {
entity = new NoteRevision(this, row);
}
else if (row.noteTreeId) {
entity = new NoteTree(this, row);
}
else if (row.noteId) {
entity = new Note(this, row);
}
else {
throw new Error('Unknown entity type for row: ' + JSON.stringify(row));
}
return entity;
}
}
module.exports = Repository;

View File

@ -5,17 +5,19 @@ const attributes = require('./attributes');
const date_notes = require('./date_notes'); const date_notes = require('./date_notes');
const sql = require('./sql'); const sql = require('./sql');
const sync_table = require('./sync_table'); const sync_table = require('./sync_table');
const Repository = require('./repository');
function ScriptContext(noteId, dataKey) { function ScriptContext(noteId, dataKey) {
this.scriptNoteId = noteId; this.scriptNoteId = noteId;
this.dataKey = protected_session.getDataKey(dataKey); this.dataKey = protected_session.getDataKey(dataKey);
this.repository = new Repository(dataKey);
function serializePayload(payload) { function serializePayload(payload) {
return JSON.stringify(payload, null, '\t'); return JSON.stringify(payload, null, '\t');
} }
this.getNoteById = async function(noteId) { this.getNoteById = async function(noteId) {
return notes.getNoteById(noteId, this.dataKey); return this.repository.getNote(noteId);
}; };
this.getNotesWithAttribute = async function (attrName, attrValue) { this.getNotesWithAttribute = async function (attrName, attrValue) {
@ -60,7 +62,7 @@ function ScriptContext(noteId, dataKey) {
}; };
this.updateNote = async function (note) { this.updateNote = async function (note) {
if (note.type === 'code' && note.mime === 'application/json') { if (note.isJson()) {
note.content = serializePayload(note.jsonContent); note.content = serializePayload(note.jsonContent);
} }

View File

@ -6,10 +6,6 @@ const fs = require('fs');
const sqlite = require('sqlite'); const sqlite = require('sqlite');
const app_info = require('./app_info'); const app_info = require('./app_info');
const resource_dir = require('./resource_dir'); const resource_dir = require('./resource_dir');
const Note = require('../entities/note');
const NoteRevision = require('../entities/note_revision');
const NoteTree = require('../entities/note_tree');
const Attribute = require('../entities/attribute');
async function createConnection() { async function createConnection() {
return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise}); return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise});
@ -137,45 +133,6 @@ async function getRows(query, params = []) {
return await wrap(async db => db.all(query, ...params)); return await wrap(async db => db.all(query, ...params));
} }
async function getEntities(query, params = []) {
const rows = await getRows(query, params);
return rows.map(createEntityFromRow);
}
async function getEntity(query, params = []) {
const row = await getRowOrNull(query, params);
if (!row) {
return null;
}
return createEntityFromRow(row);
}
function createEntityFromRow(row) {
let entity;
let sql = module.exports;
if (row.attributeId) {
entity = new Attribute(sql, row);
}
else if (row.noteRevisionId) {
entity = new NoteRevision(sql, row);
}
else if (row.noteTreeId) {
entity = new NoteTree(sql, row);
}
else if (row.noteId) {
entity = new Note(sql, row);
}
else {
throw new Error('Unknown entity type for row: ' + JSON.stringify(row));
}
return entity;
}
async function getMap(query, params = []) { async function getMap(query, params = []) {
const map = {}; const map = {};
const results = await getRows(query, params); const results = await getRows(query, params);
@ -309,8 +266,6 @@ module.exports = {
getRow, getRow,
getRowOrNull, getRowOrNull,
getRows, getRows,
getEntities,
getEntity,
getMap, getMap,
getColumn, getColumn,
execute, execute,