diff --git a/db/migrations/0137__links_to_attributes.sql b/db/migrations/0137__links_to_attributes.sql new file mode 100644 index 000000000..294debe34 --- /dev/null +++ b/db/migrations/0137__links_to_attributes.sql @@ -0,0 +1,10 @@ +UPDATE links SET type = 'internal-link' WHERE type = 'hyper'; +UPDATE links SET type = 'image-link' WHERE type = 'image'; +UPDATE links SET type = 'relation-map-link' WHERE type = 'relation-map'; + +INSERT INTO attributes (attributeId, noteId, type, name, value, position, utcDateCreated, utcDateModified, isDeleted, hash, isInheritable) +SELECT linkId, noteId, 'relation', type, targetNoteId, 0, utcDateCreated, utcDateModified, isDeleted, hash, 0 FROM links; + +UPDATE sync SET entityName = 'attributes' WHERE entityName = 'links'; + +DROP TABLE links; \ No newline at end of file diff --git a/src/entities/entity_constructor.js b/src/entities/entity_constructor.js index b7ee4b313..45e0e332a 100644 --- a/src/entities/entity_constructor.js +++ b/src/entities/entity_constructor.js @@ -1,6 +1,5 @@ const Note = require('../entities/note'); const NoteRevision = require('../entities/note_revision'); -const Link = require('../entities/link'); const Branch = require('../entities/branch'); const Attribute = require('../entities/attribute'); const RecentNote = require('../entities/recent_note'); @@ -16,7 +15,6 @@ const ENTITY_NAME_TO_ENTITY = { "recent_notes": RecentNote, "options": Option, "api_tokens": ApiToken, - "links": Link }; function getEntityFromEntityName(entityName) { @@ -36,9 +34,6 @@ function createEntityFromRow(row) { else if (row.noteRevisionId) { entity = new NoteRevision(row); } - else if (row.linkId) { - entity = new Link(row); - } else if (row.branchId && row.notePath) { entity = new RecentNote(row); } diff --git a/src/entities/link.js b/src/entities/link.js deleted file mode 100644 index b9c832903..000000000 --- a/src/entities/link.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; - -const Entity = require('./entity'); -const repository = require('../services/repository'); -const dateUtils = require('../services/date_utils'); - -/** - * This class represents link from one note to another in the form of hyperlink or image reference. Note that - * this is different concept than attribute/relation. - * - * @param {string} linkId - * @param {string} noteId - * @param {string} targetNoteId - * @param {string} type - * @param {boolean} isDeleted - * @param {string} utcDateModified - * @param {string} utcDateCreated - * - * @extends Entity - */ -class Link extends Entity { - static get entityName() { return "links"; } - static get primaryKeyName() { return "linkId"; } - static get hashedProperties() { return ["linkId", "noteId", "targetNoteId", "type", "isDeleted", "utcDateCreated", "utcDateModified"]; } - - async getNote() { - return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.noteId]); - } - - async getTargetNote() { - return await repository.getEntity("SELECT * FROM notes WHERE noteId = ?", [this.targetNoteId]); - } - - beforeSaving() { - if (!this.isDeleted) { - this.isDeleted = false; - } - - if (!this.utcDateCreated) { - this.utcDateCreated = dateUtils.utcNowDateTime(); - } - - super.beforeSaving(); - - if (this.isChanged) { - this.utcDateModified = dateUtils.utcNowDateTime(); - } - } -} - -module.exports = Link; \ No newline at end of file diff --git a/src/entities/note.js b/src/entities/note.js index 860888929..39b3cbe9f 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -628,10 +628,17 @@ class Note extends Entity { /** * Get list of links coming out of this note. * - * @returns {Promise} + * @deprecated - not intended for general use + * @returns {Promise} */ async getLinks() { - return await repository.getEntities("SELECT * FROM links WHERE noteId = ? AND isDeleted = 0", [this.noteId]); + return await repository.getEntities(` + SELECT * + FROM attributes + WHERE noteId = ? AND + isDeleted = 0 AND + type = 'relation' AND + name IN ('internal-link', 'image-link', 'relation-map-link')`, [this.noteId]); } /** diff --git a/src/public/javascripts/entities/link.js b/src/public/javascripts/entities/link.js new file mode 100644 index 000000000..89e7ec380 --- /dev/null +++ b/src/public/javascripts/entities/link.js @@ -0,0 +1,33 @@ +class Link { + constructor(treeCache, row) { + this.treeCache = treeCache; + /** @param {string} linkId */ + this.linkId = row.linkId; + /** @param {string} noteId */ + this.noteId = row.noteId; + /** @param {string} type */ + this.type = row.type; + /** @param {string} targetNoteId */ + this.targetNoteId = row.targetNoteId; + /** @param {string} utcDateCreated */ + this.utcDateCreated = row.utcDateCreated; + /** @param {string} utcDateModified */ + this.utcDateModified = row.utcDateModified; + } + + /** @returns {NoteShort} */ + async getNote() { + return await this.treeCache.getNote(this.noteId); + } + + /** @returns {NoteShort} */ + async getTargetNote() { + return await this.treeCache.getNote(this.targetNoteId); + } + + get toString() { + return `Link(linkId=${this.linkId}, type=${this.type}, note=${this.noteId}, targetNoteId=${this.targetNoteId})`; + } +} + +export default Link; \ No newline at end of file diff --git a/src/public/javascripts/entities/note_short.js b/src/public/javascripts/entities/note_short.js index 2c983bd67..dccf14850 100644 --- a/src/public/javascripts/entities/note_short.js +++ b/src/public/javascripts/entities/note_short.js @@ -1,4 +1,6 @@ import server from '../services/server.js'; +import Attribute from './attribute.js'; +import Link from './link.js'; const LABEL = 'label'; const LABEL_DEFINITION = 'label-definition'; @@ -84,7 +86,8 @@ class NoteShort { */ async getAttributes(name) { if (!this.attributeCache) { - this.attributeCache = await server.get('notes/' + this.noteId + '/attributes'); + this.attributeCache = (await server.get('notes/' + this.noteId + '/attributes')) + .map(attrRow => new Attribute(this.treeCache, attrRow)); } if (name) { @@ -227,6 +230,14 @@ class NoteShort { this.attributeCache = null; } + /** + * @return {Promise} + */ + async getLinks() { + return (await server.get('notes/' + this.noteId + '/links')) + .map(linkRow => new Link(this.treeCache, linkRow)); + } + get toString() { return `Note(noteId=${this.noteId}, title=${this.title})`; } diff --git a/src/public/javascripts/widgets/link_map.js b/src/public/javascripts/widgets/link_map.js index 625270a8c..2bef87030 100644 --- a/src/public/javascripts/widgets/link_map.js +++ b/src/public/javascripts/widgets/link_map.js @@ -58,9 +58,9 @@ class LinkMapWidget extends StandardWidget { const linkTypes = [ "hyper", "image", "relation", "relation-map" ]; const maxNotes = 50; - const noteId = this.ctx.note.noteId; + const currentNoteId = this.ctx.note.noteId; - const links = await server.post(`notes/${noteId}/link-map`, { + const links = await server.post(`notes/${currentNoteId}/link-map`, { linkTypes, maxNotes, maxDepth: 1 @@ -69,7 +69,7 @@ class LinkMapWidget extends StandardWidget { const noteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId))); if (noteIds.size === 0) { - noteIds.add(noteId); + noteIds.add(currentNoteId); } // preload all notes @@ -104,7 +104,7 @@ class LinkMapWidget extends StandardWidget { $noteBox.append($("").addClass("title").append($link)); }); - if (noteId === noteId) { + if (noteId === currentNoteId) { $noteBox.addClass("link-map-active-note"); } diff --git a/src/public/javascripts/widgets/what_links_here.js b/src/public/javascripts/widgets/what_links_here.js new file mode 100644 index 000000000..322718013 --- /dev/null +++ b/src/public/javascripts/widgets/what_links_here.js @@ -0,0 +1,31 @@ +import StandardWidget from "./standard_widget.js"; + +class WhatLinksHereWidget extends StandardWidget { + getWidgetTitle() { return "What links here"; } + + async doRenderBody() { + + + const $noteId = this.$body.find(".note-info-note-id"); + const $dateCreated = this.$body.find(".note-info-date-created"); + const $dateModified = this.$body.find(".note-info-date-modified"); + const $type = this.$body.find(".note-info-type"); + const $mime = this.$body.find(".note-info-mime"); + + const note = this.ctx.note; + + $noteId.text(note.noteId); + $dateCreated.text(note.dateCreated); + $dateModified.text(note.dateModified); + $type.text(note.type); + $mime.text(note.mime); + } + + syncDataReceived(syncData) { + if (syncData.find(sd => sd.entityName === 'notes' && sd.entityId === this.ctx.note.noteId)) { + this.doRenderBody(); + } + } +} + +export default WhatLinksHereWidget; \ No newline at end of file diff --git a/src/public/stylesheets/link_map.css b/src/public/stylesheets/link_map.css index 8e917bc27..86a8cafb1 100644 --- a/src/public/stylesheets/link_map.css +++ b/src/public/stylesheets/link_map.css @@ -39,5 +39,4 @@ .link-map-active-note { background-color: var(--more-accented-background-color) !important; - border-width: 3px !important; } \ No newline at end of file diff --git a/src/routes/api/clipper.js b/src/routes/api/clipper.js index 07122d3c4..4a3904c2c 100644 --- a/src/routes/api/clipper.js +++ b/src/routes/api/clipper.js @@ -9,7 +9,7 @@ const messagingService = require('../../services/messaging'); const log = require('../../services/log'); const utils = require('../../services/utils'); const path = require('path'); -const Link = require('../../entities/link'); +const Attribute = require('../../entities/attribute'); async function findClippingNote(todayNote, pageUrl) { const notes = await todayNote.getDescendantNotesWithLabel('pageUrl', pageUrl); @@ -84,10 +84,11 @@ async function addImagesToNote(images, note, content) { const {note: imageNote, url} = await imageService.saveImage(buffer, filename, note.noteId, true); - await new Link({ + await new Attribute({ noteId: note.noteId, - targetNoteId: imageNote.noteId, - type: 'image' + type: 'relation', + value: imageNote.noteId, + name: 'image-link' }).save(); console.log(`Replacing ${imageId} with ${url}`); diff --git a/src/routes/api/link_map.js b/src/routes/api/link_map.js index abfedb4e8..4ea882f23 100644 --- a/src/routes/api/link_map.js +++ b/src/routes/api/link_map.js @@ -2,38 +2,34 @@ const sql = require('../../services/sql'); -async function getLinks(noteIds, linkTypes) { +async function getRelations(noteIds, relationNames) { return (await sql.getManyRows(` - SELECT noteId, targetNoteId, type - FROM links - WHERE (noteId IN (???) OR targetNoteId IN (???)) - AND isDeleted = 0 - UNION - SELECT noteId, value, 'relation' + SELECT noteId, name, value AS targetNoteId FROM attributes WHERE (noteId IN (???) OR value IN (???)) AND type = 'relation' AND isDeleted = 0 - `, Array.from(noteIds))).filter(l => linkTypes.includes(l.type)); + `, Array.from(noteIds))).filter(l => relationNames.includes(l.name)); } async function getLinkMap(req) { const {noteId} = req.params; - const {linkTypes, maxNotes, maxDepth} = req.body; + const {relationNames, maxNotes, maxDepth} = req.body; let noteIds = new Set([noteId]); - let links = []; + let relations; let depth = 0; while (true) { - links = await getLinks(noteIds, linkTypes); + relations = await getRelations(noteIds, relationNames); if (depth === maxDepth) { break; } - const newNoteIds = new Set(links.map(l => l.noteId).concat(links.map(l => l.targetNoteId))); + const newNoteIds = new Set(relations.map(rel => rel.noteId) + .concat(relations.map(rel => rel.targetNoteId))); if (newNoteIds.size === noteIds.size) { // no new note discovered, no need to search any further @@ -51,9 +47,9 @@ async function getLinkMap(req) { } // keep only links coming from and targetting some note in the noteIds set - links = links.filter(l => noteIds.has(l.noteId) && noteIds.has(l.targetNoteId)); + relations = relations.filter(rel => noteIds.has(rel.noteId) && noteIds.has(rel.targetNoteId)); - return links; + return relations; } module.exports = { diff --git a/src/routes/api/links.js b/src/routes/api/links.js new file mode 100644 index 000000000..04a2bab36 --- /dev/null +++ b/src/routes/api/links.js @@ -0,0 +1,28 @@ +"use strict"; + +const repository = require('../../services/repository'); + +async function getLinks(req) { + const note = await repository.getNote(req.params.noteId); + + if (!note) { + return [404, `Note ${req.params.noteId} not found`]; + } + + return await note.getLinks(); +} + +async function getIncomingLinks(req) { + const note = await repository.getNote(req.params.noteId); + + if (!note) { + return [404, `Note ${req.params.noteId} not found`]; + } + + note.getTargetRelations() +} + +module.exports = { + getLinks, + getIncomingLinks +}; \ No newline at end of file diff --git a/src/routes/api/notes.js b/src/routes/api/notes.js index 72b8654db..c1298d2cf 100644 --- a/src/routes/api/notes.js +++ b/src/routes/api/notes.js @@ -114,8 +114,7 @@ async function getRelationMap(req) { noteTitles: {}, relations: [], // relation name => inverse relation name - inverseRelations: {}, - links: [] + inverseRelations: {} }; if (noteIds.length === 0) { @@ -145,16 +144,6 @@ async function getRelationMap(req) { } } - resp.links = (await repository.getEntities(`SELECT * FROM links WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds)) - .filter(link => noteIds.includes(link.targetNoteId)) - .map(link => { - return { - linkId: link.linkId, - sourceNoteId: link.noteId, - targetNoteId: link.targetNoteId - } - }); - return resp; } diff --git a/src/routes/routes.js b/src/routes/routes.js index dce51be9c..8792e5197 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -33,6 +33,7 @@ const filesRoute = require('./api/file_upload'); const searchRoute = require('./api/search'); const dateNotesRoute = require('./api/date_notes'); const linkMapRoute = require('./api/link_map'); +const linksRoute = require('./api/links'); const clipperRoute = require('./api/clipper'); const log = require('../services/log'); @@ -158,6 +159,8 @@ function register(app) { apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute); apiRoute(POST, '/api/notes/:noteId/link-map', linkMapRoute.getLinkMap); + apiRoute(GET, '/api/notes/:noteId/links', linksRoute.getLinks); + apiRoute(GET, '/api/notes/:noteId/incoming-links', linksRoute.getIncomingLinks); apiRoute(GET, '/api/date-notes/date/:date', dateNotesRoute.getDateNote); apiRoute(GET, '/api/date-notes/month/:month', dateNotesRoute.getMonthNote); diff --git a/src/services/app_info.js b/src/services/app_info.js index 5bf647553..2fe2f4f19 100644 --- a/src/services/app_info.js +++ b/src/services/app_info.js @@ -4,8 +4,8 @@ const build = require('./build'); const packageJson = require('../../package'); const {TRILIUM_DATA_DIR} = require('./data_dir'); -const APP_DB_VERSION = 136; -const SYNC_VERSION = 9; +const APP_DB_VERSION = 137; +const SYNC_VERSION = 10; const CLIPPER_PROTOCOL_VERSION = "1.0"; module.exports = { diff --git a/src/services/content_hash.js b/src/services/content_hash.js index 69b0d9745..c89322817 100644 --- a/src/services/content_hash.js +++ b/src/services/content_hash.js @@ -12,7 +12,6 @@ const Attribute = require('../entities/attribute'); const NoteRevision = require('../entities/note_revision'); const RecentNote = require('../entities/recent_note'); const Option = require('../entities/option'); -const Link = require('../entities/link'); async function getHash(tableName, primaryKeyName, whereBranch) { // subselect is necessary to have correct ordering in GROUP_CONCAT @@ -40,7 +39,6 @@ async function getHashes() { options: await getHash(Option.entityName, Option.primaryKeyName, "isSynced = 1"), attributes: await getHash(Attribute.entityName, Attribute.primaryKeyName), api_tokens: await getHash(ApiToken.entityName, ApiToken.primaryKeyName), - links: await getHash(Link.entityName, Link.primaryKeyName) }; const elapseTimeMs = Date.now() - startTime.getTime(); diff --git a/src/services/export/tar.js b/src/services/export/tar.js index e2aa1dd28..2704ad4e3 100644 --- a/src/services/export/tar.js +++ b/src/services/export/tar.js @@ -115,12 +115,6 @@ async function exportToTar(exportContext, branch, format, res) { isInheritable: attribute.isInheritable, position: attribute.position }; - }), - links: (await note.getLinks()).map(link => { - return { - type: link.type, - targetNoteId: link.targetNoteId - } }) }; @@ -220,9 +214,8 @@ async function exportToTar(exportContext, branch, format, res) { }; for (const noteMeta of Object.values(noteIdToMeta)) { - // filter out relations and links which are not inside this export + // filter out relations which are not inside this export noteMeta.attributes = noteMeta.attributes.filter(attr => attr.type !== 'relation' || attr.value in noteIdToMeta); - noteMeta.links = noteMeta.links.filter(link => link.targetNoteId in noteIdToMeta); } if (!metaFile.files[0]) { // corner case of disabled export for exported note diff --git a/src/services/import/tar.js b/src/services/import/tar.js index c13e6651d..be1a38316 100644 --- a/src/services/import/tar.js +++ b/src/services/import/tar.js @@ -1,7 +1,6 @@ "use strict"; const Attribute = require('../../entities/attribute'); -const Link = require('../../entities/link'); const utils = require('../../services/utils'); const log = require('../../services/log'); const repository = require('../../services/repository'); @@ -26,7 +25,6 @@ async function importTar(importContext, fileBuffer, importRootNote) { // maps from original noteId (in tar file) to newly generated noteId const noteIdMap = {}; const attributes = []; - const links = []; // path => noteId const createdPaths = { '/': importRootNote.noteId, '\\': importRootNote.noteId }; const mdReader = new commonmark.Parser(); @@ -146,7 +144,7 @@ async function importTar(importContext, fileBuffer, importRootNote) { return { type, mime }; } - async function saveAttributesAndLinks(note, noteMeta) { + async function saveAttributes(note, noteMeta) { if (!noteMeta) { return; } @@ -169,13 +167,6 @@ async function importTar(importContext, fileBuffer, importRootNote) { attributes.push(attr); } - - for (const link of noteMeta.links) { - link.noteId = note.noteId; - link.targetNoteId = getNewNoteId(link.targetNoteId); - - links.push(link); - } } async function saveDirectory(filePath) { @@ -200,7 +191,7 @@ async function importTar(importContext, fileBuffer, importRootNote) { isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), })); - await saveAttributesAndLinks(note, noteMeta); + await saveAttributes(note, noteMeta); if (!firstNote) { firstNote = note; @@ -246,9 +237,11 @@ async function importTar(importContext, fileBuffer, importRootNote) { content = content.toString("UTF-8"); if (noteMeta) { + const internalLinks = (noteMeta.attributes || []).find(attr => attr.type === 'relation' && attr.name === 'internal-link'); + // this will replace all internal links ( and ) inside the body // links pointing outside the export will be broken and changed (ctx.getNewNoteId() will still assign new noteId) - for (const link of noteMeta.links || []) { + for (const link of internalLinks) { // no need to escape the regexp find string since it's a noteId which doesn't contain any special characters content = content.replace(new RegExp(link.targetNoteId, "g"), getNewNoteId(link.targetNoteId)); } @@ -278,7 +271,7 @@ async function importTar(importContext, fileBuffer, importRootNote) { isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(), })); - await saveAttributesAndLinks(note, noteMeta); + await saveAttributes(note, noteMeta); if (!noteMeta && (type === 'file' || type === 'image')) { attributes.push({ @@ -379,15 +372,6 @@ async function importTar(importContext, fileBuffer, importRootNote) { } } - for (const link of links) { - if (link.targetNoteId in createdNoteIds) { - await new Link(link).save(); - } - else { - log.info("Link not imported since target note doesn't exist: " + JSON.stringify(link)); - } - } - resolve(firstNote); }); diff --git a/src/services/notes.js b/src/services/notes.js index 25bbf7e28..25eb1a336 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -8,7 +8,6 @@ const eventService = require('./events'); const repository = require('./repository'); const cls = require('../services/cls'); const Note = require('../entities/note'); -const Link = require('../entities/link'); const NoteRevision = require('../entities/note_revision'); const Branch = require('../entities/branch'); const Attribute = require('../entities/attribute'); @@ -215,8 +214,8 @@ function findImageLinks(content, foundLinks) { while (match = re.exec(content)) { foundLinks.push({ - type: 'image', - targetNoteId: match[1] + type: 'image-link', + value: match[1] }); } @@ -225,14 +224,14 @@ function findImageLinks(content, foundLinks) { return content.replace(/src="[^"]*\/api\/images\//g, 'src="api/images/'); } -function findHyperLinks(content, foundLinks) { +function findInternalLinks(content, foundLinks) { const re = /href="[^"]*#root[a-zA-Z0-9\/]*\/([a-zA-Z0-9]+)\/?"/g; let match; while (match = re.exec(content)) { foundLinks.push({ - type: 'hyper', - targetNoteId: match[1] + name: 'internal-link', + value: match[1] }); } @@ -245,8 +244,8 @@ function findRelationMapLinks(content, foundLinks) { for (const note of obj.notes) { foundLinks.push({ - type: 'relation-map', - targetNoteId: note.noteId + type: 'relation-map-link', + value: note.noteId }) } } @@ -260,7 +259,7 @@ async function saveLinks(note, content) { if (note.type === 'text') { content = findImageLinks(content, foundLinks); - content = findHyperLinks(content, foundLinks); + content = findInternalLinks(content, foundLinks); } else if (note.type === 'relation-map') { findRelationMapLinks(content, foundLinks); @@ -273,14 +272,15 @@ async function saveLinks(note, content) { for (const foundLink of foundLinks) { const existingLink = existingLinks.find(existingLink => - existingLink.targetNoteId === foundLink.targetNoteId - && existingLink.type === foundLink.type); + existingLink.value === foundLink.value + && existingLink.name === foundLink.name); if (!existingLink) { - await new Link({ + await new Attribute({ noteId: note.noteId, - targetNoteId: foundLink.targetNoteId, - type: foundLink.type + type: 'relation', + name: foundLink.name, + value: foundLink.targetNoteId, }).save(); } else if (existingLink.isDeleted) { @@ -292,8 +292,8 @@ async function saveLinks(note, content) { // marking links as deleted if they are not present on the page anymore const unusedLinks = existingLinks.filter(existingLink => !foundLinks.some(foundLink => - existingLink.targetNoteId === foundLink.targetNoteId - && existingLink.type === foundLink.type)); + existingLink.value === foundLink.value + && existingLink.name === foundLink.name)); for (const unusedLink of unusedLinks) { unusedLink.isDeleted = true; @@ -415,11 +415,6 @@ async function deleteNote(branch) { await relation.save(); } - for (const link of await note.getLinks()) { - link.isDeleted = true; - await link.save(); - } - for (const link of await note.getTargetLinks()) { link.isDeleted = true; await link.save(); diff --git a/src/services/sync.js b/src/services/sync.js index 28cfdc3af..1803f90c7 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -249,8 +249,7 @@ const primaryKeys = { "recent_notes": "noteId", "api_tokens": "apiTokenId", "options": "name", - "attributes": "attributeId", - "links": "linkId" + "attributes": "attributeId" }; async function getEntityRow(entityName, entityId) { diff --git a/src/services/sync_table.js b/src/services/sync_table.js index f5465e234..03b0356d5 100644 --- a/src/services/sync_table.js +++ b/src/services/sync_table.js @@ -32,10 +32,6 @@ async function addRecentNoteSync(noteId, sourceId) { await addEntitySync("recent_notes", noteId, sourceId); } -async function addLinkSync(linkId, sourceId) { - await addEntitySync("links", linkId, sourceId); -} - async function addAttributeSync(attributeId, sourceId) { await addEntitySync("attributes", attributeId, sourceId); } @@ -101,7 +97,6 @@ async function fillAllSyncRows() { await fillSyncRows("recent_notes", "noteId"); await fillSyncRows("attributes", "attributeId"); await fillSyncRows("api_tokens", "apiTokenId"); - await fillSyncRows("links", "linkId"); await fillSyncRows("options", "name", 'isSynced = 1'); } @@ -115,7 +110,6 @@ module.exports = { addRecentNoteSync, addAttributeSync, addApiTokenSync, - addLinkSync, addEntitySync, fillAllSyncRows }; \ No newline at end of file diff --git a/src/services/sync_update.js b/src/services/sync_update.js index 548675357..5779bbf34 100644 --- a/src/services/sync_update.js +++ b/src/services/sync_update.js @@ -28,9 +28,6 @@ async function updateEntity(sync, entity, sourceId) { else if (entityName === 'recent_notes') { await updateRecentNotes(entity, sourceId); } - else if (entityName === 'links') { - await updateLink(entity, sourceId); - } else if (entityName === 'attributes') { await updateAttribute(entity, sourceId); } @@ -159,20 +156,6 @@ async function updateRecentNotes(entity, sourceId) { } } -async function updateLink(entity, sourceId) { - const origLink = await sql.getRow("SELECT * FROM links WHERE linkId = ?", [entity.linkId]); - - if (!origLink || origLink.utcDateModified <= entity.utcDateModified) { - await sql.transactional(async () => { - await sql.replace("links", entity); - - await syncTableService.addLinkSync(entity.linkId, sourceId); - }); - - log.info("Update/sync link " + entity.linkId); - } -} - async function updateAttribute(entity, sourceId) { const origAttribute = await sql.getRow("SELECT * FROM attributes WHERE attributeId = ?", [entity.attributeId]);