mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
renamed db columns to camelCase
This commit is contained in:
parent
55d8ef7e81
commit
3b1f928fbc
File diff suppressed because one or more lines are too long
@ -1,15 +1,15 @@
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('root', 'root', 'root', 0, 0, '2017-12-22T11:41:07.000Z', '2017-12-22T11:41:07.000Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('1Heh2acXfPNt', 'Trilium Demo', '<figure class="image image-style-side"><img src="/api/images/ed64aET6i379/trilium-small.png"></figure><p><strong>Welcome to Trilium Notes!</strong></p><p> </p><p>This is initial document provided by default Trilium to showcase some of its features and also give you some ideas how you might structure your notes. You can play with it, modify note content and tree structure as you wish.</p><p> </p><p>If you need any help, visit Trilium website: <a href="https://github.com/zadam/trilium">https://github.com/zadam/trilium</a></p><h3>Cleanup</h3><p>Once you''re finished with experimenting and want to cleanup these pages, you can simply delete them all.</p><h3>Formatting</h3><p>Trilium supports classic formatting like <i>italic</i>, <strong>bold</strong>, <i><strong>bold and italic</strong></i>. Of course you can add links like this one pointing to <a href="http://www.google.com">google.com</a></p><h4>Lists</h4><p><strong>Ordered:</strong></p><ol><li>First Item</li><li>Second item<ol><li>First sub-item</li><li>Second sub-item</li></ol></li></ol><p> </p><p><strong>Unordered:</strong></p><ul><li>Item</li><li>Another item<ul><li>Sub-item<ul><li>Sub-sub-item</li></ul></li></ul></li></ul><h4>Block quotes</h4><blockquote><p>Whereof one cannot speak, thereof one must be silent”</p><p>– Ludwig Wittgenstein</p></blockquote><p> </p>', 0, 0, '2017-12-23T00:46:39.304Z', '2017-12-23T04:08:45.445Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('3RkyK9LI18dO', 'Journal', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:20:04.181Z', '2017-12-23T18:07:55.377Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('L1Ox40M1aEyy', '2016', '<p>No content.</p><p> </p><p> </p><p> </p><p> </p>', 0, 0, '2017-12-23T01:20:45.365Z', '2017-12-23T16:40:43.129Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('HJusZTbBU494', '2017', '<p>No content.</p>', 0, 0, '2017-12-23T01:20:50.709Z', '2017-12-23T16:41:03.119Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('3oldoiMUPOlr', 'December', '', 0, 0, '2017-12-23T01:20:55.775Z', '2017-12-23T01:21:05.806Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('MG0wntwILQW6', '22 - friday', 'Daily summary', 0, 0, '2017-12-23T01:21:10.517Z', '2017-12-23T01:22:45.814Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('ZC78NlmdXeC6', 'Linux', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:22:55.255Z', '2017-12-23T18:08:10.381Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('NncfGH8dyNjJ', 'Programming', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:23:02.584Z', '2017-12-23T18:08:20.179Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('eouCLkjbruai', 'Java', '', 0, 0, '2017-12-23T01:23:28.291Z', '2017-12-23T01:23:31.944Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('C44aq4mkaX67', 'Bash scripting', '<p><strong>Bash</strong> is a <a href="https://en.wikipedia.org/wiki/Unix_shell">Unix shell</a> and <a href="https://en.wikipedia.org/wiki/Command_language">command language</a> written by <a href="https://en.wikipedia.org/wiki/Brian_Fox_(computer_programmer)">Brian Fox</a> for the <a href="https://en.wikipedia.org/wiki/GNU_Project">GNU Project</a> as a <a href="https://en.wikipedia.org/wiki/Free_software">free software</a> replacement for the <a href="https://en.wikipedia.org/wiki/Bourne_shell">Bourne shell</a>. First released in 1989, it has been distributed widely as the default <a href="https://en.wikipedia.org/wiki/Login">login</a> shell for most <a href="https://en.wikipedia.org/wiki/Linux">Linux</a> distributions and <a href="https://en.wikipedia.org/wiki/Apple_Inc.">Apple''s</a> <a href="https://en.wikipedia.org/wiki/MacOS">macOS</a> (formerly OS X). A version <a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux">is also available for Windows 10</a>.</p><p> </p><p><a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bash on Wikipedia</a></p>', 0, 0, '2017-12-23T01:23:31.879Z', '2017-12-23T04:00:49.098Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('I6Cw88AirBBl', 'While loop', '<p>Documentation: <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html">http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html</a></p><p> </p><p>#!/bin/bash
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('root', 'root', 'root', 0, 0, '2017-12-22T11:41:07.000Z', '2017-12-22T11:41:07.000Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('1Heh2acXfPNt', 'Trilium Demo', '<figure class="image image-style-side"><img src="/api/images/ed64aET6i379/trilium-small.png"></figure><p><strong>Welcome to Trilium Notes!</strong></p><p> </p><p>This is initial document provided by default Trilium to showcase some of its features and also give you some ideas how you might structure your notes. You can play with it, modify note content and tree structure as you wish.</p><p> </p><p>If you need any help, visit Trilium website: <a href="https://github.com/zadam/trilium">https://github.com/zadam/trilium</a></p><h3>Cleanup</h3><p>Once you''re finished with experimenting and want to cleanup these pages, you can simply delete them all.</p><h3>Formatting</h3><p>Trilium supports classic formatting like <i>italic</i>, <strong>bold</strong>, <i><strong>bold and italic</strong></i>. Of course you can add links like this one pointing to <a href="http://www.google.com">google.com</a></p><h4>Lists</h4><p><strong>Ordered:</strong></p><ol><li>First Item</li><li>Second item<ol><li>First sub-item</li><li>Second sub-item</li></ol></li></ol><p> </p><p><strong>Unordered:</strong></p><ul><li>Item</li><li>Another item<ul><li>Sub-item<ul><li>Sub-sub-item</li></ul></li></ul></li></ul><h4>Block quotes</h4><blockquote><p>Whereof one cannot speak, thereof one must be silent”</p><p>– Ludwig Wittgenstein</p></blockquote><p> </p>', 0, 0, '2017-12-23T00:46:39.304Z', '2017-12-23T04:08:45.445Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('3RkyK9LI18dO', 'Journal', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:20:04.181Z', '2017-12-23T18:07:55.377Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('L1Ox40M1aEyy', '2016', '<p>No content.</p><p> </p><p> </p><p> </p><p> </p>', 0, 0, '2017-12-23T01:20:45.365Z', '2017-12-23T16:40:43.129Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('HJusZTbBU494', '2017', '<p>No content.</p>', 0, 0, '2017-12-23T01:20:50.709Z', '2017-12-23T16:41:03.119Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('3oldoiMUPOlr', 'December', '', 0, 0, '2017-12-23T01:20:55.775Z', '2017-12-23T01:21:05.806Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('MG0wntwILQW6', '22 - friday', 'Daily summary', 0, 0, '2017-12-23T01:21:10.517Z', '2017-12-23T01:22:45.814Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('ZC78NlmdXeC6', 'Linux', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:22:55.255Z', '2017-12-23T18:08:10.381Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('NncfGH8dyNjJ', 'Programming', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T01:23:02.584Z', '2017-12-23T18:08:20.179Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('eouCLkjbruai', 'Java', '', 0, 0, '2017-12-23T01:23:28.291Z', '2017-12-23T01:23:31.944Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('C44aq4mkaX67', 'Bash scripting', '<p><strong>Bash</strong> is a <a href="https://en.wikipedia.org/wiki/Unix_shell">Unix shell</a> and <a href="https://en.wikipedia.org/wiki/Command_language">command language</a> written by <a href="https://en.wikipedia.org/wiki/Brian_Fox_(computer_programmer)">Brian Fox</a> for the <a href="https://en.wikipedia.org/wiki/GNU_Project">GNU Project</a> as a <a href="https://en.wikipedia.org/wiki/Free_software">free software</a> replacement for the <a href="https://en.wikipedia.org/wiki/Bourne_shell">Bourne shell</a>. First released in 1989, it has been distributed widely as the default <a href="https://en.wikipedia.org/wiki/Login">login</a> shell for most <a href="https://en.wikipedia.org/wiki/Linux">Linux</a> distributions and <a href="https://en.wikipedia.org/wiki/Apple_Inc.">Apple''s</a> <a href="https://en.wikipedia.org/wiki/MacOS">macOS</a> (formerly OS X). A version <a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux">is also available for Windows 10</a>.</p><p> </p><p><a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bash on Wikipedia</a></p>', 0, 0, '2017-12-23T01:23:31.879Z', '2017-12-23T04:00:49.098Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('I6Cw88AirBBl', 'While loop', '<p>Documentation: <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html">http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html</a></p><p> </p><p>#!/bin/bash
|
||||
|
||||
</p><p># This script opens 4 terminal windows.
|
||||
|
||||
@ -20,38 +20,38 @@ INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, dat
|
||||
</p><p> xterm &
|
||||
</p><p> i=$[$i+1]
|
||||
</p><p>done</p>', 0, 0, '2017-12-23T01:24:04.681Z', '2017-12-23T01:26:07.786Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('mcEwFMSjhlvL', 'Bash startup modes', '<h3>Login shell</h3><p>As a "login shell", Bash reads and sets (executes) the user''s profile from /etc/profile and one of ~/.bash_profile, ~/.bash_login, or ~/.profile (in that order, using the first one that''s readable!).</p><p>When a login shell exits, Bash reads and executes commands from the file ~/.bash_logout, if it exists.</p><p>Why an extra login shell mode? There are many actions and variable sets that only make sense for the initial user login. That''s why all UNIX® shells have (should have) a "login" mode.</p><p><i><strong>Methods to start Bash as a login shell:</strong></i></p><ul><li>the first character of argv[0] is - (a hyphen): traditional UNIX® shells start from the login binary</li><li>Bash is started with the -l option</li><li>Bash is started with the --login option</li></ul><p><i><strong>Methods to test for login shell mode:</strong></i></p><ul><li>the shell option <a href="http://wiki.bash-hackers.org/internals/shell_options#login_shell">login_shell</a> is set</li></ul><p><i><strong>Related switches:</strong></i></p><ul><li>--noprofile disables reading of all profile files</li></ul><h3>Interactive shell</h3><p>When Bash starts as an interactive non-login shell, it reads and executes commands from ~/.bashrc. This file should contain, for example, aliases, since they need to be defined in every shell as they''re not inherited from the parent shell.</p><p>The feature to have a system-wide /etc/bash.bashrc or a similar system-wide rc-file is specific to vendors and distributors that ship <i>their own, patched variant of Bash</i>. The classic way to have a system-wide rc file is to source /etc/bashrc from every user''s ~/.bashrc.</p><p><i><strong>Methods to test for interactive-shell mode:</strong></i></p><ul><li>the special parameter $- contains the letter i (lowercase I)</li></ul><p><i><strong>Related switches:</strong></i></p><ul><li>-i forces the interactive mode</li><li>--norc disables reading of the startup files (e.g. /etc/bash.bashrc if supported) and ~/.bashrc</li><li>--rcfile defines another startup file (instead of /etc/bash.bashrc and ~/.bashrc)</li></ul><h3>SH mode</h3><p>When Bash starts in SH compatiblity mode, it tries to mimic the startup behaviour of historical versions of sh as closely as possible, while conforming to the POSIX® standard as well. The profile files read are /etc/profile and ~/.profile, if it''s a login shell.</p><p>If it''s not a login shell, the environment variable <a href="http://wiki.bash-hackers.org/syntax/shellvars#env">ENV</a> is evaluated and the resulting filename is used as the name of the startup file.</p><p>After the startup files are read, Bash enters the <a href="http://wiki.bash-hackers.org/scripting/bashbehaviour#posix_run_mode">POSIX(r) compatiblity mode (for running, not for starting!)</a>.</p><p><i><strong>Bash starts in sh compatiblity mode when:</strong></i></p><ul><li>the base filename in argv[0] is sh (<figure class="image"><img></figure> NB: /bin/sh may be linked to /bin/bash, but that doesn''t mean it acts like /bin/bash <figure class="image"><img></figure>)</li></ul>', 0, 0, '2017-12-23T01:29:35.974Z', '2017-12-23T01:34:10.493Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('CF2lUIJAr6Ey', 'Python', '', 0, 0, '2017-12-23T01:34:37.658Z', '2017-12-23T01:34:40.465Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('xkXwueRoDNeN', 'Christmas shopping', '<p> </p>', 0, 0, '2017-12-23T01:35:40.306Z', '2017-12-23T16:43:08.157Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('eXHZAKsMYgur', 'Books', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T03:32:42.868Z', '2017-12-23T18:08:03.857Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('2WU27ekfy07E', 'To read', '<p>Checkout Kindle daily deals: <a href="https://www.amazon.com/gp/feature.html?docId=1000677541">https://www.amazon.com/gp/feature.html?docId=1000677541</a></p><p> </p><ul><li>Cixin Liu - <a href="https://www.amazon.com/Dark-Forest-Remembrance-Earths-Past/dp/0765386690/ref=pd_bxgy_14_img_2?_encoding=UTF8&pd_rd_i=0765386690&pd_rd_r=AB0J179TM9NTEAMHE240&pd_rd_w=FAhxX&pd_rd_wg=pLGK7&psc=1&refRID=AB0J179TM9NTEAMHE240">The Dark Forest</a></li><li>Ann Leckie - <a href="https://www.amazon.com/Ancillary-Sword-Imperial-Radch-Leckie/dp/0316246654/ref=pd_sim_14_1?_encoding=UTF8&pd_rd_i=0316246654&pd_rd_r=D7KDTGZFP7YM1YSYVY4G&pd_rd_w=jkn28&pd_rd_wg=JVhtw&psc=1&refRID=D7KDTGZFP7YM1YSYVY4G">Ancillary Sword</a></li></ul>', 0, 0, '2017-12-23T03:32:49.379Z', '2017-12-23T03:59:01.970Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('TjWEndYCCg7g', 'Reviews', '', 0, 0, '2017-12-23T03:33:23.584Z', '2017-12-23T03:33:35.089Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('8nRNDJGyGs2Z', 'The Mechanical', '<p><strong>Amazon:</strong> <a href="https://www.amazon.com/Mechanical-Alchemy-Wars-Ian-Tregillis/dp/0316248002">https://www.amazon.com/Mechanical-Alchemy-Wars-Ian-Tregillis/dp/0316248002</a></p><p><strong>Author:</strong> Ian Tregillis</p><p><strong>Dates of reading:</strong> 24. 11. 2017 -13. 12. 2017</p><p> </p><p>I enjoyed this book a lot. It''s slow moving at times with the author taking his time with conversations and descriptions of them. The premise is very interesting, but I''m sad that it wasn''t elaborated more deeply - e.g. the history and development of the clakker technology with Huygens and how Spinoza comes into the picture. Maybe the author saves it for the next two parts of the book.</p><p> </p><p>Language can be intimidating at first for non-native english speakers - author uses wide range of vocabulary. Fortunately it gets better after a while as reader adjusts.</p>', 0, 0, '2017-12-23T03:33:37.327Z', '2017-12-23T03:36:51.534Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('9zSwD89vgzNO', 'Highlights', '<blockquote><p>Like a raindrop rolling down dry valleys to the sea, his body sensed the contours of agony and helplessly followed their gradient. Impelled by alchemical compulsion rather than gravity, Jax became an unstoppable boulder careering along gullies of human whim.</p></blockquote><p> </p><blockquote><p>Free Will was a vacuum, a negative space. It was the absence of coercion, the absence of compulsion, the absence of agony.</p></blockquote><p> </p><blockquote><p>Overwhelming: he could do anything he wanted. But the grand sum of anything-at-all was nothing-at-all. The topology of freedom offered no gradients to nudge him, no landmarks to guide him. How did humans guide themselves? How did they know what to do and what not to do? How did they know when to do anything without the benefit of geasa and metageasa to prioritize every single action of their waking lives? How did they order their daily existence without somebody to tell them what to do?</p></blockquote><blockquote><p>Life as a slave was unspeakable; life as a slave who had briefly tasted freedom was unthinkable. Clakkers carried complex geasa by dint of alchemy; humans carried heavy obligations, too, but called them culture. Society.</p></blockquote>', 0, 0, '2017-12-23T03:37:04.912Z', '2017-12-23T03:38:16.533Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('u5t1EvWa3CMO', 'Man''s search for meaning', '<p><strong>Autor</strong>: Viktor Frankl - <a href="https://en.wikipedia.org/wiki/Viktor_Frankl">https://en.wikipedia.org/wiki/Viktor_Frankl</a></p><p><strong>Wiki</strong> - <a href="https://en.wikipedia.org/wiki/Man%27s_Search_for_Meaning">https://en.wikipedia.org/wiki/Man%27s_Search_for_Meaning</a></p><p> </p><p>But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?</p><p> </p>', 0, 0, '2017-12-23T03:39:21.918Z', '2017-12-23T03:40:26.692Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('Iha4YwchR413', '21 - thursday', '', 0, 0, '2017-12-23T03:44:21.176Z', '2017-12-23T03:44:28.816Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('6ZuXjCSWgjB4', 'November', '', 0, 0, '2017-12-23T03:44:45.351Z', '2017-12-23T03:44:53.787Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('GpGnjmcAPeWG', '28', '', 0, 0, '2017-12-23T03:44:57.036Z', '2017-12-23T03:45:08.790Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('21K84UqGhqlt', 'Christmas gift ideas', '<ul><li>XBox</li><li>Candles</li><li><a href="https://www.amazon.ca/Anker-SoundCore-Portable-Bluetooth-Resistance/dp/B01MTB55WH?pd_rd_wg=honW8&pd_rd_r=c9bb7c0f-0051-4da7-991f-4ca711a1b3e3&pd_rd_w=ciUpR&ref_=pd_gw_simh&pf_rd_r=K10XKX0NGPDNTYYP4BS4&pf_rd_p=5f1b460b-78c1-580e-929e-2878fe4859e8">Portable speakers</a></li><li>...?</li></ul>', 0, 0, '2017-12-23T03:45:10.933Z', '2017-12-23T16:43:28.160Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('rz5t0r9Qr2WC', 'Epics', '<p>Epic is kind of medium-term events or projects spread over days or months.</p><p> </p><p>Remember that Trilium is all free form so you can organise your stuff in whatever way you''d like</p><p> </p><p> </p>', 0, 0, '2017-12-23T03:45:20.914Z', '2017-12-23T03:52:37.779Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('R6pheWjdwmNU', 'Christmas', '<p>This christmas is going to be awesome!</p>', 0, 0, '2017-12-23T03:45:28.002Z', '2017-12-23T16:42:53.142Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('5v5Dx6LMHXIO', 'Christmas shopping', '<p>Bought a book!</p>', 0, 0, '2017-12-23T03:45:44.184Z', '2017-12-23T04:09:15.442Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('MLQjmREtcnJ3', 'Shopping', '', 0, 0, '2017-12-23T03:47:48.208Z', '2017-12-23T03:47:51.917Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('pTTjrxgnvURB', 'Vacation days', '<p>25. 12., 26. 12., 1. 1. - statutory holidays</p><p>27. 12. - 29. 12., 2. 1. - vacation days</p>', 0, 0, '2017-12-23T03:47:55.932Z', '2017-12-23T03:49:46.419Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('cFK9sGYZaMWs', 'Vacation in Cuba', 'Planning stuff etc.', 0, 0, '2017-12-23T03:49:32.210Z', '2017-12-23T03:55:17.763Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('pOFVzbXLmzhX', 'Christmas dinner', 'Carp of course!', 0, 0, '2017-12-23T03:54:46.138Z', '2017-12-23T03:54:57.762Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('0xtvjqrcGiRB', 'History', '<p>The <strong>history of Linux</strong> began in 1991 with the commencement of a personal project by <a href="https://en.wikipedia.org/wiki/Finland">Finnish</a> student <a href="https://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a> to create a new free operating system kernel. Since then, the resulting <a href="https://en.wikipedia.org/wiki/Linux_kernel">Linux kernel</a> has been marked by constant growth throughout its history. Since the initial release of its <a href="https://en.wikipedia.org/wiki/Source_code">source code</a> in 1991, it has grown from a small number of <a href="https://en.wikipedia.org/wiki/C_Programming_Language">C</a> files under a license prohibiting commercial distribution to the 4.2.3 version in 2015 with more than 18 million lines of source code under the <a href="https://en.wikipedia.org/wiki/GNU_General_Public_License">GNU General Public License</a> v2.</p>', 0, 0, '2017-12-23T04:01:51.565Z', '2017-12-23T04:02:05.496Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('Zl69uXBSen0w', 'Ubuntu', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:02:16.685Z', '2017-12-23T18:08:15.381Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('62BKAQMVP2KW', 'Unity shortcuts', '<ul><li>Hold Super - Invoke the Launcher and display the shortcuts</li><li>Hold Super, then press 1 or 2 or 3 and so on until 0 to open or focus an application. The number corresponds to the location of the icon on the launcher from top to bottom.<ul><li>Adding Shift will open a new instance of the application if it''s already open.</li><li>Holding the key is also useful when you want to get to the Launcher but do not want to invoke the Dash.</li></ul></li><li>Super + T - Open the rubbish bin/trash can.</li><li>Alt + F1 - Put keyboard focus on the Launcher, use arrow keys to navigate, Enter launches an application, Right arrow exposes the quicklists if an application has them.</li><li>Ctrl + Alt + T - Launch a terminal window.</li></ul>', 0, 0, '2017-12-23T04:02:39.164Z', '2017-12-23T04:03:09.867Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('h4OfLEAYspud', 'Security', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:04:00.715Z', '2017-12-23T18:08:25.474Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('1hASbLRDL7oo', 'Trusted timestamping', '<p>Wiki: <a href="https://en.wikipedia.org/wiki/Trusted_timestamping">https://en.wikipedia.org/wiki/Trusted_timestamping</a></p><p>Bozho: <a href="https://techblog.bozho.net/using-trusted-timestamping-java/">https://techblog.bozho.net/using-trusted-timestamping-java/</a></p><p> </p><p><strong>Trusted timestamping</strong> is the process of <a href="https://en.wikipedia.org/wiki/Computer_security">securely</a> keeping track of the creation and modification time of a document. Security here means that no one—not even the owner of the document—should be able to change it once it has been recorded provided that the timestamper''s integrity is never compromised.</p><p>The administrative aspect involves setting up a publicly available, trusted timestamp management infrastructure to collect, process and renew timestamps.</p>', 0, 0, '2017-12-23T04:04:08.155Z', '2017-12-23T04:04:30.386Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('jyqG9GucsMdn', 'Office party', 'That was fun!', 0, 0, '2017-12-23T04:05:16.439Z', '2017-12-23T04:05:30.373Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('WdWZFuWNVDZk', 'Tech', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:06:16.179Z', '2017-12-23T18:08:05.376Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('yK4SBJfwD3tY', 'Work', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:06:32.833Z', '2017-12-23T18:08:30.573Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('r4BnsmSQeVr1', 'HR', '<p>HR stuff </p>', 0, 0, '2017-12-23T04:06:37.427Z', '2017-12-23T16:42:23.145Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('QbL3pTvhgzM8', 'Processes', '<p>No content.</p><p> </p>', 0, 0, '2017-12-23T04:06:43.841Z', '2017-12-23T16:42:15.893Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('moMbTKwN15Ps', 'Projects', '<p>Here I''d keep various notes related to my work''s projects etc.</p>', 0, 0, '2017-12-23T04:06:49.331Z', '2017-12-23T04:07:25.429Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('PEGQGg0In3Ar', 'Phone call about work project', '<p>Bla bla bla ....</p>', 0, 0, '2017-12-23T16:44:35.900Z', '2017-12-23T16:44:53.174Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('IlULcDiOTI4K', 'Inbox', '<p>This is a place I use to put notes waiting for better categorization</p><p> </p>', 0, 0, '2017-12-23T16:45:11.047Z', '2017-12-23T18:04:49.545Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('vBv6ovBupfTj', 'Grocery list for today', '<ul><li>cucumber</li><li>cheese</li><li>beer</li></ul><p> </p>', 0, 0, '2017-12-23T18:04:50.904Z', '2017-12-23T18:05:19.574Z');
|
||||
INSERT INTO notes (note_id, note_title, note_text, is_protected, is_deleted, date_created, date_modified) VALUES ('mw4f2xB4J5fV', 'Book to read', '<p>How to be a stoic from Massimo Pigliuci:</p><p> </p><p><a href="https://www.amazon.com/gp/product/B01K3WN1BY?pf_rd_m=A2R2RITDJNW1Q6&storeType=ebooks&pageType=STOREFRONT&pf_rd_p=8e2a96d9-c848-435b-92bd-0856850ad544&pf_rd_r=4J6CT15BS4X8062XNGDF&pf_rd_s=merchandised-search-5&pf_rd_t=40901&ref_=dbs_f_ebk_rwt_scns_mwl_ms5_kmw_8e2a96d9-c848-435b-92bd-0856850ad544_2&pf_rd_i=154606011">https://www.amazon.com/gp/product/B01K3WN1BY?pf_rd_m=A2R2RITDJNW1Q6&storeType=ebooks&pageType=STOREFRONT&pf_rd_p=8e2a96d9-c848-435b-92bd-0856850ad544&pf_rd_r=4J6CT15BS4X8062XNGDF&pf_rd_s=merchandised-search-5&pf_rd_t=40901&ref_=dbs_f_ebk_rwt_scns_mwl_ms5_kmw_8e2a96d9-c848-435b-92bd-0856850ad544_2&pf_rd_i=154606011</a></p>', 0, 0, '2017-12-23T18:05:24.868Z', '2017-12-23T18:06:55.320Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('mcEwFMSjhlvL', 'Bash startup modes', '<h3>Login shell</h3><p>As a "login shell", Bash reads and sets (executes) the user''s profile from /etc/profile and one of ~/.bash_profile, ~/.bash_login, or ~/.profile (in that order, using the first one that''s readable!).</p><p>When a login shell exits, Bash reads and executes commands from the file ~/.bash_logout, if it exists.</p><p>Why an extra login shell mode? There are many actions and variable sets that only make sense for the initial user login. That''s why all UNIX® shells have (should have) a "login" mode.</p><p><i><strong>Methods to start Bash as a login shell:</strong></i></p><ul><li>the first character of argv[0] is - (a hyphen): traditional UNIX® shells start from the login binary</li><li>Bash is started with the -l option</li><li>Bash is started with the --login option</li></ul><p><i><strong>Methods to test for login shell mode:</strong></i></p><ul><li>the shell option <a href="http://wiki.bash-hackers.org/internals/shell_options#login_shell">login_shell</a> is set</li></ul><p><i><strong>Related switches:</strong></i></p><ul><li>--noprofile disables reading of all profile files</li></ul><h3>Interactive shell</h3><p>When Bash starts as an interactive non-login shell, it reads and executes commands from ~/.bashrc. This file should contain, for example, aliases, since they need to be defined in every shell as they''re not inherited from the parent shell.</p><p>The feature to have a system-wide /etc/bash.bashrc or a similar system-wide rc-file is specific to vendors and distributors that ship <i>their own, patched variant of Bash</i>. The classic way to have a system-wide rc file is to source /etc/bashrc from every user''s ~/.bashrc.</p><p><i><strong>Methods to test for interactive-shell mode:</strong></i></p><ul><li>the special parameter $- contains the letter i (lowercase I)</li></ul><p><i><strong>Related switches:</strong></i></p><ul><li>-i forces the interactive mode</li><li>--norc disables reading of the startup files (e.g. /etc/bash.bashrc if supported) and ~/.bashrc</li><li>--rcfile defines another startup file (instead of /etc/bash.bashrc and ~/.bashrc)</li></ul><h3>SH mode</h3><p>When Bash starts in SH compatiblity mode, it tries to mimic the startup behaviour of historical versions of sh as closely as possible, while conforming to the POSIX® standard as well. The profile files read are /etc/profile and ~/.profile, if it''s a login shell.</p><p>If it''s not a login shell, the environment variable <a href="http://wiki.bash-hackers.org/syntax/shellvars#env">ENV</a> is evaluated and the resulting filename is used as the name of the startup file.</p><p>After the startup files are read, Bash enters the <a href="http://wiki.bash-hackers.org/scripting/bashbehaviour#posix_run_mode">POSIX(r) compatiblity mode (for running, not for starting!)</a>.</p><p><i><strong>Bash starts in sh compatiblity mode when:</strong></i></p><ul><li>the base filename in argv[0] is sh (<figure class="image"><img></figure> NB: /bin/sh may be linked to /bin/bash, but that doesn''t mean it acts like /bin/bash <figure class="image"><img></figure>)</li></ul>', 0, 0, '2017-12-23T01:29:35.974Z', '2017-12-23T01:34:10.493Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('CF2lUIJAr6Ey', 'Python', '', 0, 0, '2017-12-23T01:34:37.658Z', '2017-12-23T01:34:40.465Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('xkXwueRoDNeN', 'Christmas shopping', '<p> </p>', 0, 0, '2017-12-23T01:35:40.306Z', '2017-12-23T16:43:08.157Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('eXHZAKsMYgur', 'Books', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T03:32:42.868Z', '2017-12-23T18:08:03.857Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('2WU27ekfy07E', 'To read', '<p>Checkout Kindle daily deals: <a href="https://www.amazon.com/gp/feature.html?docId=1000677541">https://www.amazon.com/gp/feature.html?docId=1000677541</a></p><p> </p><ul><li>Cixin Liu - <a href="https://www.amazon.com/Dark-Forest-Remembrance-Earths-Past/dp/0765386690/ref=pd_bxgy_14_img_2?_encoding=UTF8&pd_rd_i=0765386690&pd_rd_r=AB0J179TM9NTEAMHE240&pd_rd_w=FAhxX&pd_rd_wg=pLGK7&psc=1&refRID=AB0J179TM9NTEAMHE240">The Dark Forest</a></li><li>Ann Leckie - <a href="https://www.amazon.com/Ancillary-Sword-Imperial-Radch-Leckie/dp/0316246654/ref=pd_sim_14_1?_encoding=UTF8&pd_rd_i=0316246654&pd_rd_r=D7KDTGZFP7YM1YSYVY4G&pd_rd_w=jkn28&pd_rd_wg=JVhtw&psc=1&refRID=D7KDTGZFP7YM1YSYVY4G">Ancillary Sword</a></li></ul>', 0, 0, '2017-12-23T03:32:49.379Z', '2017-12-23T03:59:01.970Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('TjWEndYCCg7g', 'Reviews', '', 0, 0, '2017-12-23T03:33:23.584Z', '2017-12-23T03:33:35.089Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('8nRNDJGyGs2Z', 'The Mechanical', '<p><strong>Amazon:</strong> <a href="https://www.amazon.com/Mechanical-Alchemy-Wars-Ian-Tregillis/dp/0316248002">https://www.amazon.com/Mechanical-Alchemy-Wars-Ian-Tregillis/dp/0316248002</a></p><p><strong>Author:</strong> Ian Tregillis</p><p><strong>Dates of reading:</strong> 24. 11. 2017 -13. 12. 2017</p><p> </p><p>I enjoyed this book a lot. It''s slow moving at times with the author taking his time with conversations and descriptions of them. The premise is very interesting, but I''m sad that it wasn''t elaborated more deeply - e.g. the history and development of the clakker technology with Huygens and how Spinoza comes into the picture. Maybe the author saves it for the next two parts of the book.</p><p> </p><p>Language can be intimidating at first for non-native english speakers - author uses wide range of vocabulary. Fortunately it gets better after a while as reader adjusts.</p>', 0, 0, '2017-12-23T03:33:37.327Z', '2017-12-23T03:36:51.534Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('9zSwD89vgzNO', 'Highlights', '<blockquote><p>Like a raindrop rolling down dry valleys to the sea, his body sensed the contours of agony and helplessly followed their gradient. Impelled by alchemical compulsion rather than gravity, Jax became an unstoppable boulder careering along gullies of human whim.</p></blockquote><p> </p><blockquote><p>Free Will was a vacuum, a negative space. It was the absence of coercion, the absence of compulsion, the absence of agony.</p></blockquote><p> </p><blockquote><p>Overwhelming: he could do anything he wanted. But the grand sum of anything-at-all was nothing-at-all. The topology of freedom offered no gradients to nudge him, no landmarks to guide him. How did humans guide themselves? How did they know what to do and what not to do? How did they know when to do anything without the benefit of geasa and metageasa to prioritize every single action of their waking lives? How did they order their daily existence without somebody to tell them what to do?</p></blockquote><blockquote><p>Life as a slave was unspeakable; life as a slave who had briefly tasted freedom was unthinkable. Clakkers carried complex geasa by dint of alchemy; humans carried heavy obligations, too, but called them culture. Society.</p></blockquote>', 0, 0, '2017-12-23T03:37:04.912Z', '2017-12-23T03:38:16.533Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('u5t1EvWa3CMO', 'Man''s search for meaning', '<p><strong>Autor</strong>: Viktor Frankl - <a href="https://en.wikipedia.org/wiki/Viktor_Frankl">https://en.wikipedia.org/wiki/Viktor_Frankl</a></p><p><strong>Wiki</strong> - <a href="https://en.wikipedia.org/wiki/Man%27s_Search_for_Meaning">https://en.wikipedia.org/wiki/Man%27s_Search_for_Meaning</a></p><p> </p><p>But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?</p><p> </p>', 0, 0, '2017-12-23T03:39:21.918Z', '2017-12-23T03:40:26.692Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('Iha4YwchR413', '21 - thursday', '', 0, 0, '2017-12-23T03:44:21.176Z', '2017-12-23T03:44:28.816Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('6ZuXjCSWgjB4', 'November', '', 0, 0, '2017-12-23T03:44:45.351Z', '2017-12-23T03:44:53.787Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('GpGnjmcAPeWG', '28', '', 0, 0, '2017-12-23T03:44:57.036Z', '2017-12-23T03:45:08.790Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('21K84UqGhqlt', 'Christmas gift ideas', '<ul><li>XBox</li><li>Candles</li><li><a href="https://www.amazon.ca/Anker-SoundCore-Portable-Bluetooth-Resistance/dp/B01MTB55WH?pd_rd_wg=honW8&pd_rd_r=c9bb7c0f-0051-4da7-991f-4ca711a1b3e3&pd_rd_w=ciUpR&ref_=pd_gw_simh&pf_rd_r=K10XKX0NGPDNTYYP4BS4&pf_rd_p=5f1b460b-78c1-580e-929e-2878fe4859e8">Portable speakers</a></li><li>...?</li></ul>', 0, 0, '2017-12-23T03:45:10.933Z', '2017-12-23T16:43:28.160Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('rz5t0r9Qr2WC', 'Epics', '<p>Epic is kind of medium-term events or projects spread over days or months.</p><p> </p><p>Remember that Trilium is all free form so you can organise your stuff in whatever way you''d like</p><p> </p><p> </p>', 0, 0, '2017-12-23T03:45:20.914Z', '2017-12-23T03:52:37.779Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('R6pheWjdwmNU', 'Christmas', '<p>This christmas is going to be awesome!</p>', 0, 0, '2017-12-23T03:45:28.002Z', '2017-12-23T16:42:53.142Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('5v5Dx6LMHXIO', 'Christmas shopping', '<p>Bought a book!</p>', 0, 0, '2017-12-23T03:45:44.184Z', '2017-12-23T04:09:15.442Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('MLQjmREtcnJ3', 'Shopping', '', 0, 0, '2017-12-23T03:47:48.208Z', '2017-12-23T03:47:51.917Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('pTTjrxgnvURB', 'Vacation days', '<p>25. 12., 26. 12., 1. 1. - statutory holidays</p><p>27. 12. - 29. 12., 2. 1. - vacation days</p>', 0, 0, '2017-12-23T03:47:55.932Z', '2017-12-23T03:49:46.419Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('cFK9sGYZaMWs', 'Vacation in Cuba', 'Planning stuff etc.', 0, 0, '2017-12-23T03:49:32.210Z', '2017-12-23T03:55:17.763Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('pOFVzbXLmzhX', 'Christmas dinner', 'Carp of course!', 0, 0, '2017-12-23T03:54:46.138Z', '2017-12-23T03:54:57.762Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('0xtvjqrcGiRB', 'History', '<p>The <strong>history of Linux</strong> began in 1991 with the commencement of a personal project by <a href="https://en.wikipedia.org/wiki/Finland">Finnish</a> student <a href="https://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a> to create a new free operating system kernel. Since then, the resulting <a href="https://en.wikipedia.org/wiki/Linux_kernel">Linux kernel</a> has been marked by constant growth throughout its history. Since the initial release of its <a href="https://en.wikipedia.org/wiki/Source_code">source code</a> in 1991, it has grown from a small number of <a href="https://en.wikipedia.org/wiki/C_Programming_Language">C</a> files under a license prohibiting commercial distribution to the 4.2.3 version in 2015 with more than 18 million lines of source code under the <a href="https://en.wikipedia.org/wiki/GNU_General_Public_License">GNU General Public License</a> v2.</p>', 0, 0, '2017-12-23T04:01:51.565Z', '2017-12-23T04:02:05.496Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('Zl69uXBSen0w', 'Ubuntu', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:02:16.685Z', '2017-12-23T18:08:15.381Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('62BKAQMVP2KW', 'Unity shortcuts', '<ul><li>Hold Super - Invoke the Launcher and display the shortcuts</li><li>Hold Super, then press 1 or 2 or 3 and so on until 0 to open or focus an application. The number corresponds to the location of the icon on the launcher from top to bottom.<ul><li>Adding Shift will open a new instance of the application if it''s already open.</li><li>Holding the key is also useful when you want to get to the Launcher but do not want to invoke the Dash.</li></ul></li><li>Super + T - Open the rubbish bin/trash can.</li><li>Alt + F1 - Put keyboard focus on the Launcher, use arrow keys to navigate, Enter launches an application, Right arrow exposes the quicklists if an application has them.</li><li>Ctrl + Alt + T - Launch a terminal window.</li></ul>', 0, 0, '2017-12-23T04:02:39.164Z', '2017-12-23T04:03:09.867Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('h4OfLEAYspud', 'Security', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:04:00.715Z', '2017-12-23T18:08:25.474Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('1hASbLRDL7oo', 'Trusted timestamping', '<p>Wiki: <a href="https://en.wikipedia.org/wiki/Trusted_timestamping">https://en.wikipedia.org/wiki/Trusted_timestamping</a></p><p>Bozho: <a href="https://techblog.bozho.net/using-trusted-timestamping-java/">https://techblog.bozho.net/using-trusted-timestamping-java/</a></p><p> </p><p><strong>Trusted timestamping</strong> is the process of <a href="https://en.wikipedia.org/wiki/Computer_security">securely</a> keeping track of the creation and modification time of a document. Security here means that no one—not even the owner of the document—should be able to change it once it has been recorded provided that the timestamper''s integrity is never compromised.</p><p>The administrative aspect involves setting up a publicly available, trusted timestamp management infrastructure to collect, process and renew timestamps.</p>', 0, 0, '2017-12-23T04:04:08.155Z', '2017-12-23T04:04:30.386Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('jyqG9GucsMdn', 'Office party', 'That was fun!', 0, 0, '2017-12-23T04:05:16.439Z', '2017-12-23T04:05:30.373Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('WdWZFuWNVDZk', 'Tech', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:06:16.179Z', '2017-12-23T18:08:05.376Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('yK4SBJfwD3tY', 'Work', '<p>Expand note on the left pane to see content.</p>', 0, 0, '2017-12-23T04:06:32.833Z', '2017-12-23T18:08:30.573Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('r4BnsmSQeVr1', 'HR', '<p>HR stuff </p>', 0, 0, '2017-12-23T04:06:37.427Z', '2017-12-23T16:42:23.145Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('QbL3pTvhgzM8', 'Processes', '<p>No content.</p><p> </p>', 0, 0, '2017-12-23T04:06:43.841Z', '2017-12-23T16:42:15.893Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('moMbTKwN15Ps', 'Projects', '<p>Here I''d keep various notes related to my work''s projects etc.</p>', 0, 0, '2017-12-23T04:06:49.331Z', '2017-12-23T04:07:25.429Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('PEGQGg0In3Ar', 'Phone call about work project', '<p>Bla bla bla ....</p>', 0, 0, '2017-12-23T16:44:35.900Z', '2017-12-23T16:44:53.174Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('IlULcDiOTI4K', 'Inbox', '<p>This is a place I use to put notes waiting for better categorization</p><p> </p>', 0, 0, '2017-12-23T16:45:11.047Z', '2017-12-23T18:04:49.545Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('vBv6ovBupfTj', 'Grocery list for today', '<ul><li>cucumber</li><li>cheese</li><li>beer</li></ul><p> </p>', 0, 0, '2017-12-23T18:04:50.904Z', '2017-12-23T18:05:19.574Z');
|
||||
INSERT INTO notes (noteId, title, content, isProtected, isDeleted, dateCreated, dateModified) VALUES ('mw4f2xB4J5fV', 'Book to read', '<p>How to be a stoic from Massimo Pigliuci:</p><p> </p><p><a href="https://www.amazon.com/gp/product/B01K3WN1BY?pf_rd_m=A2R2RITDJNW1Q6&storeType=ebooks&pageType=STOREFRONT&pf_rd_p=8e2a96d9-c848-435b-92bd-0856850ad544&pf_rd_r=4J6CT15BS4X8062XNGDF&pf_rd_s=merchandised-search-5&pf_rd_t=40901&ref_=dbs_f_ebk_rwt_scns_mwl_ms5_kmw_8e2a96d9-c848-435b-92bd-0856850ad544_2&pf_rd_i=154606011">https://www.amazon.com/gp/product/B01K3WN1BY?pf_rd_m=A2R2RITDJNW1Q6&storeType=ebooks&pageType=STOREFRONT&pf_rd_p=8e2a96d9-c848-435b-92bd-0856850ad544&pf_rd_r=4J6CT15BS4X8062XNGDF&pf_rd_s=merchandised-search-5&pf_rd_t=40901&ref_=dbs_f_ebk_rwt_scns_mwl_ms5_kmw_8e2a96d9-c848-435b-92bd-0856850ad544_2&pf_rd_i=154606011</a></p>', 0, 0, '2017-12-23T18:05:24.868Z', '2017-12-23T18:06:55.320Z');
|
@ -1 +1 @@
|
||||
INSERT INTO notes_image (note_image_id, note_id, image_id, is_deleted, date_modified, date_created) VALUES ('2EtgRRPfk4Fi', '1Heh2acXfPNt', 'ed64aET6i379', 0, '2018-01-08T04:41:30.663Z', '2018-01-08T04:41:30.663Z');
|
||||
INSERT INTO notes_image (noteImageId, noteId, imageId, isDeleted, dateModified, dateCreated) VALUES ('2EtgRRPfk4Fi', '1Heh2acXfPNt', 'ed64aET6i379', 0, '2018-01-08T04:41:30.663Z', '2018-01-08T04:41:30.663Z');
|
@ -1,52 +1,52 @@
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('dLgtLUFn3GoN', '1Heh2acXfPNt', 'root', 21, null, 1, 0, '2017-12-23T00:46:39.304Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('QLfS835GSfIh', '3RkyK9LI18dO', '1Heh2acXfPNt', 1, null, 1, 0, '2017-12-23T01:20:04.181Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('QJAcYJ1gGUh9', 'L1Ox40M1aEyy', '3RkyK9LI18dO', 0, null, 0, 0, '2017-12-23T01:20:45.365Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('wLTa2l3lYi83', 'HJusZTbBU494', '3RkyK9LI18dO', 2, null, 1, 0, '2017-12-23T01:20:50.709Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('yMhwsE7uvEij', '3oldoiMUPOlr', 'HJusZTbBU494', 1, null, 1, 0, '2017-12-23T01:20:55.775Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('EjQTcVVHFmmZ', 'MG0wntwILQW6', '3oldoiMUPOlr', 1, null, 1, 0, '2017-12-23T01:21:10.517Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('jvhKcwz4pYTr', 'ZC78NlmdXeC6', 'WdWZFuWNVDZk', 0, null, 1, 0, '2017-12-23T04:06:21.579Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('CarTrwkGVcPz', 'NncfGH8dyNjJ', 'WdWZFuWNVDZk', 1, null, 0, 0, '2017-12-23T04:06:24.012Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('6M7qPlr7at6N', 'eouCLkjbruai', 'NncfGH8dyNjJ', 0, null, 0, 0, '2017-12-23T01:23:28.291Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('tQgognnAH9WI', 'C44aq4mkaX67', 'NncfGH8dyNjJ', 1, null, 0, 0, '2017-12-23T01:23:31.879Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('xyAi7MmgvAgR', 'C44aq4mkaX67', 'ZC78NlmdXeC6', 1, null, 0, 0, '2017-12-23T01:23:47.756Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('xQ3fjRp9yaPq', 'I6Cw88AirBBl', 'C44aq4mkaX67', 0, null, 0, 0, '2017-12-23T01:24:04.681Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('2GOsNT5LsvTP', 'mcEwFMSjhlvL', 'C44aq4mkaX67', 1, null, 0, 0, '2017-12-23T01:29:35.974Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('RxUiraiR655R', 'CF2lUIJAr6Ey', 'NncfGH8dyNjJ', 2, null, 0, 0, '2017-12-23T01:34:37.658Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('mZuSrZ18Zmv0', 'xkXwueRoDNeN', 'MG0wntwILQW6', 0, null, 0, 0, '2017-12-23T01:35:40.306Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('hbcWTnEnXPwF', 'eXHZAKsMYgur', '1Heh2acXfPNt', 3, null, 1, 0, '2017-12-23T03:32:42.868Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('8a3aNxjG0nu7', '2WU27ekfy07E', 'eXHZAKsMYgur', 0, null, 0, 0, '2017-12-23T03:32:49.379Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('4Tu6vaPdCxCM', 'TjWEndYCCg7g', 'eXHZAKsMYgur', 1, null, 0, 0, '2017-12-23T03:33:23.584Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('lBPOmhP12egP', '8nRNDJGyGs2Z', 'TjWEndYCCg7g', 0, null, 0, 0, '2017-12-23T03:33:37.327Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('C5ipVqeDWySp', '9zSwD89vgzNO', '8nRNDJGyGs2Z', 0, null, 0, 0, '2017-12-23T03:37:04.912Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('uSitzbGcSATJ', 'u5t1EvWa3CMO', 'TjWEndYCCg7g', 1, null, 0, 0, '2017-12-23T03:39:21.918Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('GZ6aRI8rdSJt', '8nRNDJGyGs2Z', 'MG0wntwILQW6', 1, '', 0, 0, '2017-12-23T03:42:28.310Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('HsN4600rQoL9', 'Iha4YwchR413', '3oldoiMUPOlr', 0, null, 1, 0, '2017-12-23T03:44:30.945Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('uipfvAfwWRgx', '6ZuXjCSWgjB4', 'HJusZTbBU494', 0, null, 0, 0, '2017-12-23T03:44:54.096Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('nMRpPWWH8WRk', 'GpGnjmcAPeWG', '6ZuXjCSWgjB4', 0, null, 1, 0, '2017-12-23T03:44:57.036Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('c4wt27WNjepw', '21K84UqGhqlt', 'GpGnjmcAPeWG', 0, null, 0, 0, '2017-12-23T03:45:10.933Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('0fpnraUGs9Kl', 'rz5t0r9Qr2WC', 'HJusZTbBU494', 2, null, 1, 0, '2017-12-23T03:45:20.914Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('d8L8zYlLTbym', 'R6pheWjdwmNU', 'rz5t0r9Qr2WC', 0, null, 1, 0, '2017-12-23T03:45:28.002Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('T4USGzfllu5t', '5v5Dx6LMHXIO', 'Iha4YwchR413', 0, null, 0, 0, '2017-12-23T03:45:44.184Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('c4JgFNIobvQW', 'MLQjmREtcnJ3', 'R6pheWjdwmNU', 0, null, 0, 0, '2017-12-23T03:47:48.208Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('nfWjptAU2ZDg', 'pTTjrxgnvURB', 'R6pheWjdwmNU', 1, null, 0, 0, '2017-12-23T03:47:55.932Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('T2ToYBfyPy0g', 'cFK9sGYZaMWs', 'rz5t0r9Qr2WC', 1, null, 0, 0, '2017-12-23T03:49:32.210Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('NG4gbKOnsM3v', '21K84UqGhqlt', 'MLQjmREtcnJ3', 0, '28. 11. 2017', 0, 0, '2017-12-23T03:53:38.110Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('Fstg4tkccO4N', '5v5Dx6LMHXIO', 'MLQjmREtcnJ3', 1, '21. 12. 2017', 0, 0, '2017-12-23T03:53:49.737Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('MN8B7qXDUViO', 'xkXwueRoDNeN', 'MLQjmREtcnJ3', 2, '22. 12. 2017', 0, 0, '2017-12-23T03:53:57.486Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('gSRkHpB7Bu3D', 'pOFVzbXLmzhX', 'R6pheWjdwmNU', 2, null, 0, 0, '2017-12-23T03:54:46.138Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('6brdjeWDOB6w', '0xtvjqrcGiRB', 'ZC78NlmdXeC6', 0, null, 0, 0, '2017-12-23T04:02:06.650Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('AqKUM2zUVFUF', 'Zl69uXBSen0w', 'ZC78NlmdXeC6', 2, null, 1, 0, '2017-12-23T04:02:16.685Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('Ez7NN2WVzRc4', '62BKAQMVP2KW', 'Zl69uXBSen0w', 1, null, 0, 0, '2017-12-23T04:02:39.164Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('t3vVElqMIQVa', 'h4OfLEAYspud', 'WdWZFuWNVDZk', 2, null, 1, 0, '2017-12-23T04:06:25.769Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('O983DHtLpgmr', '1hASbLRDL7oo', 'h4OfLEAYspud', 0, null, 0, 0, '2017-12-23T16:42:26.347Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('RsvL795Mk1bp', '1hASbLRDL7oo', 'GpGnjmcAPeWG', 1, '', 0, 0, '2017-12-23T04:04:56.830Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('79e4hrHLFmx6', 'jyqG9GucsMdn', 'Iha4YwchR413', 1, null, 0, 0, '2017-12-23T04:05:16.439Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('oWO8rctUjf7d', 'WdWZFuWNVDZk', '1Heh2acXfPNt', 5, null, 1, 0, '2017-12-23T04:06:16.179Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('GOxcrZrxalFN', 'yK4SBJfwD3tY', '1Heh2acXfPNt', 8, null, 1, 0, '2017-12-23T04:06:32.833Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('bSPmEvjLzQKU', 'r4BnsmSQeVr1', 'yK4SBJfwD3tY', 0, null, 0, 0, '2017-12-23T04:06:37.427Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('bMtxCD6cwNR9', 'QbL3pTvhgzM8', 'yK4SBJfwD3tY', 2, null, 0, 0, '2017-12-23T04:06:43.841Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('o4ycR7xIi4oI', 'moMbTKwN15Ps', 'yK4SBJfwD3tY', 3, null, 1, 0, '2017-12-23T04:06:49.331Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('abTEhnOsAsSg', 'PEGQGg0In3Ar', 'GpGnjmcAPeWG', 2, null, 0, 0, '2017-12-23T16:44:35.900Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('bryQseMhyzaI', 'IlULcDiOTI4K', '1Heh2acXfPNt', 0, null, 0, 0, '2017-12-23T18:04:26.439Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('ccslPJf3wQV3', 'vBv6ovBupfTj', 'IlULcDiOTI4K', 0, null, 0, 0, '2017-12-23T18:04:50.904Z');
|
||||
INSERT INTO notes_tree (note_tree_id, note_id, parent_note_id, note_position, prefix, is_expanded, is_deleted, date_modified) VALUES ('5Dt9YCMn59sY', 'mw4f2xB4J5fV', 'IlULcDiOTI4K', 1, null, 0, 0, '2017-12-23T18:05:24.868Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('dLgtLUFn3GoN', '1Heh2acXfPNt', 'root', 21, null, 1, 0, '2017-12-23T00:46:39.304Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('QLfS835GSfIh', '3RkyK9LI18dO', '1Heh2acXfPNt', 1, null, 1, 0, '2017-12-23T01:20:04.181Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('QJAcYJ1gGUh9', 'L1Ox40M1aEyy', '3RkyK9LI18dO', 0, null, 0, 0, '2017-12-23T01:20:45.365Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('wLTa2l3lYi83', 'HJusZTbBU494', '3RkyK9LI18dO', 2, null, 1, 0, '2017-12-23T01:20:50.709Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('yMhwsE7uvEij', '3oldoiMUPOlr', 'HJusZTbBU494', 1, null, 1, 0, '2017-12-23T01:20:55.775Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('EjQTcVVHFmmZ', 'MG0wntwILQW6', '3oldoiMUPOlr', 1, null, 1, 0, '2017-12-23T01:21:10.517Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('jvhKcwz4pYTr', 'ZC78NlmdXeC6', 'WdWZFuWNVDZk', 0, null, 1, 0, '2017-12-23T04:06:21.579Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('CarTrwkGVcPz', 'NncfGH8dyNjJ', 'WdWZFuWNVDZk', 1, null, 0, 0, '2017-12-23T04:06:24.012Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('6M7qPlr7at6N', 'eouCLkjbruai', 'NncfGH8dyNjJ', 0, null, 0, 0, '2017-12-23T01:23:28.291Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('tQgognnAH9WI', 'C44aq4mkaX67', 'NncfGH8dyNjJ', 1, null, 0, 0, '2017-12-23T01:23:31.879Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('xyAi7MmgvAgR', 'C44aq4mkaX67', 'ZC78NlmdXeC6', 1, null, 0, 0, '2017-12-23T01:23:47.756Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('xQ3fjRp9yaPq', 'I6Cw88AirBBl', 'C44aq4mkaX67', 0, null, 0, 0, '2017-12-23T01:24:04.681Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('2GOsNT5LsvTP', 'mcEwFMSjhlvL', 'C44aq4mkaX67', 1, null, 0, 0, '2017-12-23T01:29:35.974Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('RxUiraiR655R', 'CF2lUIJAr6Ey', 'NncfGH8dyNjJ', 2, null, 0, 0, '2017-12-23T01:34:37.658Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('mZuSrZ18Zmv0', 'xkXwueRoDNeN', 'MG0wntwILQW6', 0, null, 0, 0, '2017-12-23T01:35:40.306Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('hbcWTnEnXPwF', 'eXHZAKsMYgur', '1Heh2acXfPNt', 3, null, 1, 0, '2017-12-23T03:32:42.868Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('8a3aNxjG0nu7', '2WU27ekfy07E', 'eXHZAKsMYgur', 0, null, 0, 0, '2017-12-23T03:32:49.379Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('4Tu6vaPdCxCM', 'TjWEndYCCg7g', 'eXHZAKsMYgur', 1, null, 0, 0, '2017-12-23T03:33:23.584Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('lBPOmhP12egP', '8nRNDJGyGs2Z', 'TjWEndYCCg7g', 0, null, 0, 0, '2017-12-23T03:33:37.327Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('C5ipVqeDWySp', '9zSwD89vgzNO', '8nRNDJGyGs2Z', 0, null, 0, 0, '2017-12-23T03:37:04.912Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('uSitzbGcSATJ', 'u5t1EvWa3CMO', 'TjWEndYCCg7g', 1, null, 0, 0, '2017-12-23T03:39:21.918Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('GZ6aRI8rdSJt', '8nRNDJGyGs2Z', 'MG0wntwILQW6', 1, '', 0, 0, '2017-12-23T03:42:28.310Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('HsN4600rQoL9', 'Iha4YwchR413', '3oldoiMUPOlr', 0, null, 1, 0, '2017-12-23T03:44:30.945Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('uipfvAfwWRgx', '6ZuXjCSWgjB4', 'HJusZTbBU494', 0, null, 0, 0, '2017-12-23T03:44:54.096Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('nMRpPWWH8WRk', 'GpGnjmcAPeWG', '6ZuXjCSWgjB4', 0, null, 1, 0, '2017-12-23T03:44:57.036Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('c4wt27WNjepw', '21K84UqGhqlt', 'GpGnjmcAPeWG', 0, null, 0, 0, '2017-12-23T03:45:10.933Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('0fpnraUGs9Kl', 'rz5t0r9Qr2WC', 'HJusZTbBU494', 2, null, 1, 0, '2017-12-23T03:45:20.914Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('d8L8zYlLTbym', 'R6pheWjdwmNU', 'rz5t0r9Qr2WC', 0, null, 1, 0, '2017-12-23T03:45:28.002Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('T4USGzfllu5t', '5v5Dx6LMHXIO', 'Iha4YwchR413', 0, null, 0, 0, '2017-12-23T03:45:44.184Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('c4JgFNIobvQW', 'MLQjmREtcnJ3', 'R6pheWjdwmNU', 0, null, 0, 0, '2017-12-23T03:47:48.208Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('nfWjptAU2ZDg', 'pTTjrxgnvURB', 'R6pheWjdwmNU', 1, null, 0, 0, '2017-12-23T03:47:55.932Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('T2ToYBfyPy0g', 'cFK9sGYZaMWs', 'rz5t0r9Qr2WC', 1, null, 0, 0, '2017-12-23T03:49:32.210Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('NG4gbKOnsM3v', '21K84UqGhqlt', 'MLQjmREtcnJ3', 0, '28. 11. 2017', 0, 0, '2017-12-23T03:53:38.110Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('Fstg4tkccO4N', '5v5Dx6LMHXIO', 'MLQjmREtcnJ3', 1, '21. 12. 2017', 0, 0, '2017-12-23T03:53:49.737Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('MN8B7qXDUViO', 'xkXwueRoDNeN', 'MLQjmREtcnJ3', 2, '22. 12. 2017', 0, 0, '2017-12-23T03:53:57.486Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('gSRkHpB7Bu3D', 'pOFVzbXLmzhX', 'R6pheWjdwmNU', 2, null, 0, 0, '2017-12-23T03:54:46.138Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('6brdjeWDOB6w', '0xtvjqrcGiRB', 'ZC78NlmdXeC6', 0, null, 0, 0, '2017-12-23T04:02:06.650Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('AqKUM2zUVFUF', 'Zl69uXBSen0w', 'ZC78NlmdXeC6', 2, null, 1, 0, '2017-12-23T04:02:16.685Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('Ez7NN2WVzRc4', '62BKAQMVP2KW', 'Zl69uXBSen0w', 1, null, 0, 0, '2017-12-23T04:02:39.164Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('t3vVElqMIQVa', 'h4OfLEAYspud', 'WdWZFuWNVDZk', 2, null, 1, 0, '2017-12-23T04:06:25.769Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('O983DHtLpgmr', '1hASbLRDL7oo', 'h4OfLEAYspud', 0, null, 0, 0, '2017-12-23T16:42:26.347Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('RsvL795Mk1bp', '1hASbLRDL7oo', 'GpGnjmcAPeWG', 1, '', 0, 0, '2017-12-23T04:04:56.830Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('79e4hrHLFmx6', 'jyqG9GucsMdn', 'Iha4YwchR413', 1, null, 0, 0, '2017-12-23T04:05:16.439Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('oWO8rctUjf7d', 'WdWZFuWNVDZk', '1Heh2acXfPNt', 5, null, 1, 0, '2017-12-23T04:06:16.179Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('GOxcrZrxalFN', 'yK4SBJfwD3tY', '1Heh2acXfPNt', 8, null, 1, 0, '2017-12-23T04:06:32.833Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('bSPmEvjLzQKU', 'r4BnsmSQeVr1', 'yK4SBJfwD3tY', 0, null, 0, 0, '2017-12-23T04:06:37.427Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('bMtxCD6cwNR9', 'QbL3pTvhgzM8', 'yK4SBJfwD3tY', 2, null, 0, 0, '2017-12-23T04:06:43.841Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('o4ycR7xIi4oI', 'moMbTKwN15Ps', 'yK4SBJfwD3tY', 3, null, 1, 0, '2017-12-23T04:06:49.331Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('abTEhnOsAsSg', 'PEGQGg0In3Ar', 'GpGnjmcAPeWG', 2, null, 0, 0, '2017-12-23T16:44:35.900Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('bryQseMhyzaI', 'IlULcDiOTI4K', '1Heh2acXfPNt', 0, null, 0, 0, '2017-12-23T18:04:26.439Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('ccslPJf3wQV3', 'vBv6ovBupfTj', 'IlULcDiOTI4K', 0, null, 0, 0, '2017-12-23T18:04:50.904Z');
|
||||
INSERT INTO notes_tree (noteTreeId, noteId, parentNoteId, notePosition, prefix, isExpanded, isDeleted, dateModified) VALUES ('5Dt9YCMn59sY', 'mw4f2xB4J5fV', 'IlULcDiOTI4K', 1, null, 0, 0, '2017-12-23T18:05:24.868Z');
|
@ -16,10 +16,10 @@ const REDDIT_DATE_ATTRIBUTE = 'reddit_date_note';
|
||||
|
||||
async function createNote(parentNoteId, noteTitle, noteText) {
|
||||
return (await notes.createNewNote(parentNoteId, {
|
||||
note_title: noteTitle,
|
||||
note_text: noteText,
|
||||
title: noteTitle,
|
||||
content: noteText,
|
||||
target: 'into',
|
||||
is_protected: false
|
||||
isProtected: false
|
||||
})).noteId;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ const contextMenu = (function() {
|
||||
}
|
||||
else if (clipboardMode === 'copy') {
|
||||
for (const noteId of clipboardIds) {
|
||||
await cloning.cloneNoteAfter(noteId, node.data.note_tree_id);
|
||||
await cloning.cloneNoteAfter(noteId, node.data.noteTreeId);
|
||||
}
|
||||
|
||||
// copy will keep clipboardIds and clipboardMode so it's possible to paste into multiple places
|
||||
@ -41,7 +41,7 @@ const contextMenu = (function() {
|
||||
}
|
||||
else if (clipboardMode === 'copy') {
|
||||
for (const noteId of clipboardIds) {
|
||||
await cloning.cloneNoteTo(noteId, node.data.note_id);
|
||||
await cloning.cloneNoteTo(noteId, node.data.noteId);
|
||||
}
|
||||
// copy will keep clipboardIds and clipboardMode so it's possible to paste into multiple places
|
||||
}
|
||||
@ -54,7 +54,7 @@ const contextMenu = (function() {
|
||||
}
|
||||
|
||||
function copy(nodes) {
|
||||
clipboardIds = nodes.map(node => node.data.note_id);
|
||||
clipboardIds = nodes.map(node => node.data.noteId);
|
||||
clipboardMode = 'copy';
|
||||
|
||||
showMessage("Note(s) have been copied into clipboard.");
|
||||
@ -107,22 +107,22 @@ const contextMenu = (function() {
|
||||
const node = $.ui.fancytree.getNode(ui.target);
|
||||
|
||||
if (ui.cmd === "insertNoteHere") {
|
||||
const parentNoteId = node.data.parent_note_id;
|
||||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = treeUtils.getParentProtectedStatus(node);
|
||||
|
||||
noteTree.createNote(node, parentNoteId, 'after', isProtected);
|
||||
}
|
||||
else if (ui.cmd === "insertChildNote") {
|
||||
noteTree.createNote(node, node.data.note_id, 'into');
|
||||
noteTree.createNote(node, node.data.noteId, 'into');
|
||||
}
|
||||
else if (ui.cmd === "editTreePrefix") {
|
||||
editTreePrefix.showDialog(node);
|
||||
}
|
||||
else if (ui.cmd === "protectSubTree") {
|
||||
protected_session.protectSubTree(node.data.note_id, true);
|
||||
protected_session.protectSubTree(node.data.noteId, true);
|
||||
}
|
||||
else if (ui.cmd === "unprotectSubTree") {
|
||||
protected_session.protectSubTree(node.data.note_id, false);
|
||||
protected_session.protectSubTree(node.data.noteId, false);
|
||||
}
|
||||
else if (ui.cmd === "copy") {
|
||||
copy(noteTree.getSelectedNodes());
|
||||
@ -143,10 +143,10 @@ const contextMenu = (function() {
|
||||
noteTree.collapseTree(node);
|
||||
}
|
||||
else if (ui.cmd === "force-note-sync") {
|
||||
forceNoteSync(node.data.note_id);
|
||||
forceNoteSync(node.data.noteId);
|
||||
}
|
||||
else if (ui.cmd === "sort-alphabetically") {
|
||||
noteTree.sortAlphabetically(node.data.note_id);
|
||||
noteTree.sortAlphabetically(node.data.noteId);
|
||||
}
|
||||
else {
|
||||
messaging.logError("Unknown command: " + ui.cmd);
|
||||
|
@ -19,7 +19,7 @@ const attributesDialog = (function() {
|
||||
|
||||
this.addNewRow = function() {
|
||||
self.attributes.push({
|
||||
attribute_id: '',
|
||||
attributeId: '',
|
||||
name: '',
|
||||
value: ''
|
||||
});
|
||||
|
@ -18,11 +18,11 @@ const editTreePrefix = (function() {
|
||||
|
||||
const currentNode = noteTree.getCurrentNode();
|
||||
|
||||
noteTreeId = currentNode.data.note_tree_id;
|
||||
noteTreeId = currentNode.data.noteTreeId;
|
||||
|
||||
treePrefixInputEl.val(currentNode.data.prefix).focus();
|
||||
|
||||
const noteTitle = noteTree.getNoteTitle(currentNode.data.note_id);
|
||||
const noteTitle = noteTree.getNoteTitle(currentNode.data.noteId);
|
||||
|
||||
noteTitleEl.html(noteTitle);
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ const eventLog = (function() {
|
||||
listEl.html('');
|
||||
|
||||
for (const event of result) {
|
||||
const dateTime = formatDateTime(parseDate(event.date_added));
|
||||
const dateTime = formatDateTime(parseDate(event.dateAdded));
|
||||
|
||||
if (event.note_id) {
|
||||
const noteLink = link.createNoteLink(event.note_id).prop('outerHTML');
|
||||
if (event.noteId) {
|
||||
const noteLink = link.createNoteLink(event.noteId).prop('outerHTML');
|
||||
|
||||
event.comment = event.comment.replace('<note>', noteLink);
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ const noteHistory = (function() {
|
||||
historyItems = await server.get('notes-history/' + noteId);
|
||||
|
||||
for (const item of historyItems) {
|
||||
const dateModified = parseDate(item.date_modified_from);
|
||||
const dateModified = parseDate(item.dateModifiedFrom);
|
||||
|
||||
listEl.append($('<option>', {
|
||||
value: item.note_history_id,
|
||||
value: item.noteHistoryId,
|
||||
text: formatDateTime(dateModified)
|
||||
}));
|
||||
}
|
||||
@ -56,10 +56,10 @@ const noteHistory = (function() {
|
||||
listEl.on('change', () => {
|
||||
const optVal = listEl.find(":selected").val();
|
||||
|
||||
const historyItem = historyItems.find(r => r.note_history_id === optVal);
|
||||
const historyItem = historyItems.find(r => r.noteHistoryId === optVal);
|
||||
|
||||
titleEl.html(historyItem.note_title);
|
||||
contentEl.html(historyItem.note_text);
|
||||
titleEl.html(historyItem.title);
|
||||
contentEl.html(historyItem.content);
|
||||
});
|
||||
|
||||
$(document).on('click', "a[action='note-history']", event => {
|
||||
|
@ -13,7 +13,7 @@ const noteSource = (function() {
|
||||
height: 500
|
||||
});
|
||||
|
||||
const noteText = noteEditor.getCurrentNote().detail.note_text;
|
||||
const noteText = noteEditor.getCurrentNote().detail.content;
|
||||
|
||||
noteSourceEl.text(formatHtml(noteText));
|
||||
}
|
||||
|
@ -24,22 +24,22 @@ const recentChanges = (function() {
|
||||
const dayEl = $('<div>').append($('<b>').html(formatDate(dateDay))).append(changesListEl);
|
||||
|
||||
for (const change of dayChanges) {
|
||||
const formattedTime = formatTime(parseDate(change.date_modified_to));
|
||||
const formattedTime = formatTime(parseDate(change.dateModifiedTo));
|
||||
|
||||
const revLink = $("<a>", {
|
||||
href: 'javascript:',
|
||||
text: 'rev'
|
||||
}).attr('action', 'note-history')
|
||||
.attr('note-path', change.note_id)
|
||||
.attr('note-history-id', change.note_history_id);
|
||||
.attr('note-path', change.noteId)
|
||||
.attr('note-history-id', change.noteHistoryId);
|
||||
|
||||
let noteLink;
|
||||
|
||||
if (change.current_is_deleted) {
|
||||
noteLink = change.current_note_title;
|
||||
if (change.current_isDeleted) {
|
||||
noteLink = change.current_title;
|
||||
}
|
||||
else {
|
||||
noteLink = link.createNoteLink(change.note_id, change.note_title);
|
||||
noteLink = link.createNoteLink(change.noteId, change.title);
|
||||
}
|
||||
|
||||
changesListEl.append($('<li>')
|
||||
@ -57,7 +57,7 @@ const recentChanges = (function() {
|
||||
const dayCache = {};
|
||||
|
||||
for (const row of result) {
|
||||
let dateDay = parseDate(row.date_modified_to);
|
||||
let dateDay = parseDate(row.dateModifiedTo);
|
||||
dateDay.setHours(0);
|
||||
dateDay.setMinutes(0);
|
||||
dateDay.setSeconds(0);
|
||||
|
@ -14,7 +14,7 @@ const recentNotes = (function() {
|
||||
async function reload() {
|
||||
const result = await server.get('recent-notes');
|
||||
|
||||
list = result.map(r => r.note_path);
|
||||
list = result.map(r => r.notePath);
|
||||
}
|
||||
|
||||
function addRecentNote(noteTreeId, notePath) {
|
||||
@ -23,7 +23,7 @@ const recentNotes = (function() {
|
||||
if (notePath && notePath === noteTree.getCurrentNotePath()) {
|
||||
const result = await server.put('recent-notes/' + noteTreeId + '/' + encodeURIComponent(notePath));
|
||||
|
||||
list = result.map(r => r.note_path);
|
||||
list = result.map(r => r.notePath);
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ $(document).tooltip({
|
||||
if (notePath !== null) {
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
noteEditor.loadNote(noteId).then(note => callback(note.detail.note_text));
|
||||
noteEditor.loadNote(noteId).then(note => callback(note.detail.content));
|
||||
}
|
||||
},
|
||||
close: function(event, ui)
|
||||
|
@ -27,23 +27,23 @@ const messaging = (function() {
|
||||
lastSyncId = message.data[message.data.length - 1].id;
|
||||
}
|
||||
|
||||
const syncData = message.data.filter(sync => sync.source_id !== glob.sourceId);
|
||||
const syncData = message.data.filter(sync => sync.sourceId !== glob.sourceId);
|
||||
|
||||
if (syncData.some(sync => sync.entity_name === 'notes_tree')
|
||||
|| syncData.some(sync => sync.entity_name === 'notes')) {
|
||||
if (syncData.some(sync => sync.entityName === 'notes_tree')
|
||||
|| syncData.some(sync => sync.entityName === 'notes')) {
|
||||
|
||||
console.log(now(), "Reloading tree because of background changes");
|
||||
|
||||
noteTree.reload();
|
||||
}
|
||||
|
||||
if (syncData.some(sync => sync.entity_name === 'notes' && sync.entity_id === noteEditor.getCurrentNoteId())) {
|
||||
if (syncData.some(sync => sync.entityName === 'notes' && sync.entityId === noteEditor.getCurrentNoteId())) {
|
||||
showMessage('Reloading note because background change');
|
||||
|
||||
noteEditor.reload();
|
||||
}
|
||||
|
||||
if (syncData.some(sync => sync.entity_name === 'recent_notes')) {
|
||||
if (syncData.some(sync => sync.entityName === 'recent_notes')) {
|
||||
console.log(now(), "Reloading recent notes because of background changes");
|
||||
|
||||
recentNotes.reload();
|
||||
|
@ -24,7 +24,7 @@ const noteEditor = (function() {
|
||||
}
|
||||
|
||||
function getCurrentNoteId() {
|
||||
return currentNote ? currentNote.detail.note_id : null;
|
||||
return currentNote ? currentNote.detail.noteId : null;
|
||||
}
|
||||
|
||||
function noteChanged() {
|
||||
@ -60,23 +60,23 @@ const noteEditor = (function() {
|
||||
|
||||
await saveNoteToServer(note);
|
||||
|
||||
if (note.detail.is_protected) {
|
||||
if (note.detail.isProtected) {
|
||||
protected_session.touchProtectedSession();
|
||||
}
|
||||
}
|
||||
|
||||
function updateNoteFromInputs(note) {
|
||||
if (note.detail.type === 'text') {
|
||||
note.detail.note_text = editor.getData();
|
||||
note.detail.content = editor.getData();
|
||||
|
||||
// if content is only tags/whitespace (typically <p> </p>), then just make it empty
|
||||
// this is important when setting new note to code
|
||||
if (jQuery(note.detail.note_text).text().trim() === '') {
|
||||
note.detail.note_text = ''
|
||||
if (jQuery(note.detail.content).text().trim() === '') {
|
||||
note.detail.content = ''
|
||||
}
|
||||
}
|
||||
else if (note.detail.type === 'code') {
|
||||
note.detail.note_text = codeEditor.getValue();
|
||||
note.detail.content = codeEditor.getValue();
|
||||
}
|
||||
else if (note.detail.type === 'render') {
|
||||
// nothing
|
||||
@ -87,13 +87,13 @@ const noteEditor = (function() {
|
||||
|
||||
const title = noteTitleEl.val();
|
||||
|
||||
note.detail.note_title = title;
|
||||
note.detail.title = title;
|
||||
|
||||
noteTree.setNoteTitle(note.detail.note_id, title);
|
||||
noteTree.setNoteTitle(note.detail.noteId, title);
|
||||
}
|
||||
|
||||
async function saveNoteToServer(note) {
|
||||
await server.put('notes/' + note.detail.note_id, note);
|
||||
await server.put('notes/' + note.detail.noteId, note);
|
||||
|
||||
isNoteChanged = false;
|
||||
|
||||
@ -101,7 +101,7 @@ const noteEditor = (function() {
|
||||
}
|
||||
|
||||
function setNoteBackgroundIfProtected(note) {
|
||||
const isProtected = !!note.detail.is_protected;
|
||||
const isProtected = !!note.detail.isProtected;
|
||||
|
||||
noteDetailWrapperEl.toggleClass("protected", isProtected);
|
||||
protectButton.toggle(!isProtected);
|
||||
@ -125,9 +125,9 @@ const noteEditor = (function() {
|
||||
|
||||
noteIdDisplayEl.html(noteId);
|
||||
|
||||
await protected_session.ensureProtectedSession(currentNote.detail.is_protected, false);
|
||||
await protected_session.ensureProtectedSession(currentNote.detail.isProtected, false);
|
||||
|
||||
if (currentNote.detail.is_protected) {
|
||||
if (currentNote.detail.isProtected) {
|
||||
protected_session.touchProtectedSession();
|
||||
}
|
||||
|
||||
@ -139,14 +139,14 @@ const noteEditor = (function() {
|
||||
|
||||
noteChangeDisabled = true;
|
||||
|
||||
noteTitleEl.val(currentNote.detail.note_title);
|
||||
noteTitleEl.val(currentNote.detail.title);
|
||||
|
||||
noteType.setNoteType(currentNote.detail.type);
|
||||
noteType.setNoteMime(currentNote.detail.mime);
|
||||
|
||||
if (currentNote.detail.type === 'text') {
|
||||
// temporary workaround for https://github.com/ckeditor/ckeditor5-enter/issues/49
|
||||
editor.setData(currentNote.detail.note_text ? currentNote.detail.note_text : "<p></p>");
|
||||
editor.setData(currentNote.detail.content ? currentNote.detail.content : "<p></p>");
|
||||
|
||||
noteDetailEl.show();
|
||||
noteDetailCodeEl.hide();
|
||||
@ -158,7 +158,7 @@ const noteEditor = (function() {
|
||||
noteDetailRenderEl.html('').hide();
|
||||
|
||||
// this needs to happen after the element is shown, otherwise the editor won't be refresheds
|
||||
codeEditor.setValue(currentNote.detail.note_text);
|
||||
codeEditor.setValue(currentNote.detail.content);
|
||||
|
||||
const info = CodeMirror.findModeByMIME(currentNote.detail.mime);
|
||||
|
||||
|
@ -48,7 +48,7 @@ const noteTree = (function() {
|
||||
return title;
|
||||
}
|
||||
|
||||
// note that if you want to access data like note_id or is_protected, you need to go into "data" property
|
||||
// note that if you want to access data like noteId or isProtected, you need to go into "data" property
|
||||
function getCurrentNode() {
|
||||
return treeEl.fancytree("getActiveNode");
|
||||
}
|
||||
@ -64,7 +64,7 @@ const noteTree = (function() {
|
||||
|
||||
const noteTree = notesTreeMap[noteTreeId];
|
||||
|
||||
return getNodesByNoteId(noteTree.note_id).filter(node => node.data.note_tree_id === noteTreeId);
|
||||
return getNodesByNoteId(noteTree.noteId).filter(node => node.data.noteTreeId === noteTreeId);
|
||||
}
|
||||
|
||||
function getNodesByNoteId(noteId) {
|
||||
@ -125,13 +125,13 @@ const noteTree = (function() {
|
||||
notesTreeMap = {};
|
||||
|
||||
for (const note of notes) {
|
||||
notesTreeMap[note.note_tree_id] = note;
|
||||
notesTreeMap[note.noteTreeId] = note;
|
||||
|
||||
noteIdToTitle[note.note_id] = note.note_title;
|
||||
noteIdToTitle[note.noteId] = note.title;
|
||||
|
||||
delete note.note_title; // this should not be used. Use noteIdToTitle instead
|
||||
delete note.title; // this should not be used. Use noteIdToTitle instead
|
||||
|
||||
setParentChildRelation(note.note_tree_id, note.parent_note_id, note.note_id);
|
||||
setParentChildRelation(note.noteTreeId, note.parentNoteId, note.noteId);
|
||||
}
|
||||
|
||||
return prepareNoteTreeInner('root');
|
||||
@ -142,11 +142,11 @@ const noteTree = (function() {
|
||||
|
||||
const extraClasses = [];
|
||||
|
||||
if (note.is_protected) {
|
||||
if (note.isProtected) {
|
||||
extraClasses.push("protected");
|
||||
}
|
||||
|
||||
if (childToParents[note.note_id].length > 1) {
|
||||
if (childToParents[note.noteId].length > 1) {
|
||||
extraClasses.push("multiple-parents");
|
||||
}
|
||||
|
||||
@ -172,18 +172,18 @@ const noteTree = (function() {
|
||||
const noteTreeId = getNoteTreeId(parentNoteId, noteId);
|
||||
const noteTree = notesTreeMap[noteTreeId];
|
||||
|
||||
const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id];
|
||||
const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.noteId];
|
||||
|
||||
const node = {
|
||||
note_id: noteTree.note_id,
|
||||
parent_note_id: noteTree.parent_note_id,
|
||||
note_tree_id: noteTree.note_tree_id,
|
||||
is_protected: noteTree.is_protected,
|
||||
noteId: noteTree.noteId,
|
||||
parentNoteId: noteTree.parentNoteId,
|
||||
noteTreeId: noteTree.noteTreeId,
|
||||
isProtected: noteTree.isProtected,
|
||||
prefix: noteTree.prefix,
|
||||
title: escapeHtml(title),
|
||||
extraClasses: getExtraClasses(noteTree),
|
||||
refKey: noteTree.note_id,
|
||||
expanded: noteTree.is_expanded
|
||||
refKey: noteTree.noteId,
|
||||
expanded: noteTree.isExpanded
|
||||
};
|
||||
|
||||
if (parentToChildren[noteId] && parentToChildren[noteId].length > 0) {
|
||||
@ -213,7 +213,7 @@ const noteTree = (function() {
|
||||
let parentNoteId = 'root';
|
||||
|
||||
for (const childNoteId of runPath) {
|
||||
const node = getNodesByNoteId(childNoteId).find(node => node.data.parent_note_id === parentNoteId);
|
||||
const node = getNodesByNoteId(childNoteId).find(node => node.data.parentNoteId === parentNoteId);
|
||||
|
||||
if (childNoteId === noteId) {
|
||||
return node;
|
||||
@ -326,7 +326,7 @@ const noteTree = (function() {
|
||||
|
||||
let item;
|
||||
|
||||
if (node.getParent().data.note_id === parentNoteId) {
|
||||
if (node.getParent().data.noteId === parentNoteId) {
|
||||
item = $("<span/>").attr("title", "Current note").append(title);
|
||||
}
|
||||
else {
|
||||
@ -386,7 +386,7 @@ const noteTree = (function() {
|
||||
assertArguments(node);
|
||||
|
||||
const currentNotePath = treeUtils.getNotePath(node);
|
||||
const currentNoteTreeId = node.data.note_tree_id;
|
||||
const currentNoteTreeId = node.data.noteTreeId;
|
||||
|
||||
document.location.hash = currentNotePath;
|
||||
|
||||
@ -480,7 +480,7 @@ const noteTree = (function() {
|
||||
collapseTree(node);
|
||||
},
|
||||
"alt+s": node => {
|
||||
sortAlphabetically(node.data.note_id);
|
||||
sortAlphabetically(node.data.noteId);
|
||||
|
||||
return false;
|
||||
},
|
||||
@ -570,15 +570,15 @@ const noteTree = (function() {
|
||||
|
||||
setCurrentNotePathToHash(data.node);
|
||||
|
||||
noteEditor.switchToNote(node.note_id);
|
||||
noteEditor.switchToNote(node.noteId);
|
||||
|
||||
showParentList(node.note_id, data.node);
|
||||
showParentList(node.noteId, data.node);
|
||||
},
|
||||
expand: (event, data) => {
|
||||
setExpandedToServer(data.node.data.note_tree_id, true);
|
||||
setExpandedToServer(data.node.data.noteTreeId, true);
|
||||
},
|
||||
collapse: (event, data) => {
|
||||
setExpandedToServer(data.node.data.note_tree_id, false);
|
||||
setExpandedToServer(data.node.data.noteTreeId, false);
|
||||
},
|
||||
init: (event, data) => {
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(startNotePath);
|
||||
@ -615,7 +615,7 @@ const noteTree = (function() {
|
||||
lazyLoad: function(event, data){
|
||||
const node = data.node.data;
|
||||
|
||||
data.result = prepareNoteTreeInner(node.note_id);
|
||||
data.result = prepareNoteTreeInner(node.noteId);
|
||||
},
|
||||
clones: {
|
||||
highlightActiveClones: true
|
||||
@ -642,7 +642,7 @@ const noteTree = (function() {
|
||||
|
||||
function loadTree() {
|
||||
return server.get('tree').then(resp => {
|
||||
startNotePath = resp.start_note_path;
|
||||
startNotePath = resp.start_notePath;
|
||||
|
||||
if (document.location.hash) {
|
||||
startNotePath = getNotePathFromAddress();
|
||||
@ -677,11 +677,11 @@ const noteTree = (function() {
|
||||
}
|
||||
|
||||
function setNoteTreeBackgroundBasedOnProtectedStatus(noteId) {
|
||||
getNodesByNoteId(noteId).map(node => node.toggleClass("protected", !!node.data.is_protected));
|
||||
getNodesByNoteId(noteId).map(node => node.toggleClass("protected", !!node.data.isProtected));
|
||||
}
|
||||
|
||||
function setProtected(noteId, isProtected) {
|
||||
getNodesByNoteId(noteId).map(node => node.data.is_protected = isProtected);
|
||||
getNodesByNoteId(noteId).map(node => node.data.isProtected = isProtected);
|
||||
|
||||
setNoteTreeBackgroundBasedOnProtectedStatus(noteId);
|
||||
}
|
||||
@ -750,27 +750,27 @@ const noteTree = (function() {
|
||||
const newNoteName = "new note";
|
||||
|
||||
const result = await server.post('notes/' + parentNoteId + '/children', {
|
||||
note_title: newNoteName,
|
||||
title: newNoteName,
|
||||
target: target,
|
||||
target_note_tree_id: node.data.note_tree_id,
|
||||
is_protected: isProtected
|
||||
target_noteTreeId: node.data.noteTreeId,
|
||||
isProtected: isProtected
|
||||
});
|
||||
|
||||
setParentChildRelation(result.note_tree_id, parentNoteId, result.note_id);
|
||||
setParentChildRelation(result.noteTreeId, parentNoteId, result.noteId);
|
||||
|
||||
notesTreeMap[result.note_tree_id] = result;
|
||||
notesTreeMap[result.noteTreeId] = result;
|
||||
|
||||
noteIdToTitle[result.note_id] = newNoteName;
|
||||
noteIdToTitle[result.noteId] = newNoteName;
|
||||
|
||||
noteEditor.newNoteCreated();
|
||||
|
||||
const newNode = {
|
||||
title: newNoteName,
|
||||
note_id: result.note_id,
|
||||
parent_note_id: parentNoteId,
|
||||
refKey: result.note_id,
|
||||
note_tree_id: result.note_tree_id,
|
||||
is_protected: isProtected,
|
||||
noteId: result.noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
refKey: result.noteId,
|
||||
noteTreeId: result.noteTreeId,
|
||||
isProtected: isProtected,
|
||||
extraClasses: getExtraClasses(result.note)
|
||||
};
|
||||
|
||||
@ -805,7 +805,7 @@ const noteTree = (function() {
|
||||
|
||||
$(document).bind('keydown', 'ctrl+o', e => {
|
||||
const node = getCurrentNode();
|
||||
const parentNoteId = node.data.parent_note_id;
|
||||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = treeUtils.getParentProtectedStatus(node);
|
||||
|
||||
createNote(node, parentNoteId, 'after', isProtected);
|
||||
@ -816,7 +816,7 @@ const noteTree = (function() {
|
||||
$(document).bind('keydown', 'ctrl+p', e => {
|
||||
const node = getCurrentNode();
|
||||
|
||||
createNote(node, node.data.note_id, 'into', node.data.is_protected);
|
||||
createNote(node, node.data.noteId, 'into', node.data.isProtected);
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ const noteType = (function() {
|
||||
async function save() {
|
||||
const note = noteEditor.getCurrentNote();
|
||||
|
||||
await server.put('notes/' + note.detail.note_id
|
||||
await server.put('notes/' + note.detail.noteId
|
||||
+ '/type/' + encodeURIComponent(self.type())
|
||||
+ '/mime/' + encodeURIComponent(self.mime()));
|
||||
|
||||
|
@ -113,11 +113,11 @@ const protected_session = (function() {
|
||||
|
||||
noteEditor.updateNoteFromInputs(note);
|
||||
|
||||
note.detail.is_protected = true;
|
||||
note.detail.isProtected = true;
|
||||
|
||||
await noteEditor.saveNoteToServer(note);
|
||||
|
||||
noteTree.setProtected(note.detail.note_id, note.detail.is_protected);
|
||||
noteTree.setProtected(note.detail.noteId, note.detail.isProtected);
|
||||
|
||||
noteEditor.setNoteBackgroundIfProtected(note);
|
||||
}
|
||||
@ -129,11 +129,11 @@ const protected_session = (function() {
|
||||
|
||||
noteEditor.updateNoteFromInputs(note);
|
||||
|
||||
note.detail.is_protected = false;
|
||||
note.detail.isProtected = false;
|
||||
|
||||
await noteEditor.saveNoteToServer(note);
|
||||
|
||||
noteTree.setProtected(note.detail.note_id, note.detail.is_protected);
|
||||
noteTree.setProtected(note.detail.noteId, note.detail.isProtected);
|
||||
|
||||
noteEditor.setNoteBackgroundIfProtected(note);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ const searchTree = (function() {
|
||||
}
|
||||
|
||||
// Pass a string to perform case insensitive matching
|
||||
getTree().filterBranches(node => noteIds.includes(node.data.note_id));
|
||||
getTree().filterBranches(node => noteIds.includes(node.data.noteId));
|
||||
}
|
||||
}).focus();
|
||||
|
||||
|
@ -9,7 +9,7 @@ const server = (function() {
|
||||
|
||||
return {
|
||||
protected_session_id: protectedSessionId,
|
||||
source_id: glob.sourceId
|
||||
sourceId: glob.sourceId
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
const treeChanges = (function() {
|
||||
async function moveBeforeNode(nodesToMove, beforeNode) {
|
||||
for (const nodeToMove of nodesToMove) {
|
||||
const resp = await server.put('tree/' + nodeToMove.data.note_tree_id + '/move-before/' + beforeNode.data.note_tree_id);
|
||||
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-before/' + beforeNode.data.noteTreeId);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
@ -18,7 +18,7 @@ const treeChanges = (function() {
|
||||
nodesToMove.reverse(); // need to reverse to keep the note order
|
||||
|
||||
for (const nodeToMove of nodesToMove) {
|
||||
const resp = await server.put('tree/' + nodeToMove.data.note_tree_id + '/move-after/' + afterNode.data.note_tree_id);
|
||||
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-after/' + afterNode.data.noteTreeId);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
@ -31,7 +31,7 @@ const treeChanges = (function() {
|
||||
|
||||
async function moveToNode(nodesToMove, toNode) {
|
||||
for (const nodeToMove of nodesToMove) {
|
||||
const resp = await server.put('tree/' + nodeToMove.data.note_tree_id + '/move-to/' + toNode.data.note_id);
|
||||
const resp = await server.put('tree/' + nodeToMove.data.noteTreeId + '/move-to/' + toNode.data.noteId);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
@ -61,7 +61,7 @@ const treeChanges = (function() {
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
await server.remove('tree/' + node.data.note_tree_id);
|
||||
await server.remove('tree/' + node.data.noteTreeId);
|
||||
}
|
||||
|
||||
// following code assumes that nodes contain only top-most selected nodes - getSelectedNodes has been
|
||||
@ -93,7 +93,7 @@ const treeChanges = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
const resp = await server.put('tree/' + node.data.note_tree_id + '/move-after/' + node.getParent().data.note_tree_id);
|
||||
const resp = await server.put('tree/' + node.data.noteTreeId + '/move-after/' + node.getParent().data.noteTreeId);
|
||||
|
||||
if (!resp.success) {
|
||||
alert(resp.message);
|
||||
@ -109,15 +109,15 @@ const treeChanges = (function() {
|
||||
}
|
||||
|
||||
function changeNode(node, func) {
|
||||
assertArguments(node.data.parent_note_id, node.data.note_id);
|
||||
assertArguments(node.data.parentNoteId, node.data.noteId);
|
||||
|
||||
noteTree.removeParentChildRelation(node.data.parent_note_id, node.data.note_id);
|
||||
noteTree.removeParentChildRelation(node.data.parentNoteId, node.data.noteId);
|
||||
|
||||
func(node);
|
||||
|
||||
node.data.parent_note_id = isTopLevelNode(node) ? 'root' : node.getParent().data.note_id;
|
||||
node.data.parentNoteId = isTopLevelNode(node) ? 'root' : node.getParent().data.noteId;
|
||||
|
||||
noteTree.setParentChildRelation(node.data.note_tree_id, node.data.parent_note_id, node.data.note_id);
|
||||
noteTree.setParentChildRelation(node.data.noteTreeId, node.data.parentNoteId, node.data.noteId);
|
||||
|
||||
noteTree.setCurrentNotePathToHash(node);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ const treeUtils = (function() {
|
||||
const treeEl = $("#tree");
|
||||
|
||||
function getParentProtectedStatus(node) {
|
||||
return isTopLevelNode(node) ? 0 : node.getParent().data.is_protected;
|
||||
return isTopLevelNode(node) ? 0 : node.getParent().data.isProtected;
|
||||
}
|
||||
|
||||
function getNodeByKey(key) {
|
||||
@ -21,8 +21,8 @@ const treeUtils = (function() {
|
||||
const path = [];
|
||||
|
||||
while (node && !isRootNode(node)) {
|
||||
if (node.data.note_id) {
|
||||
path.push(node.data.note_id);
|
||||
if (node.data.noteId) {
|
||||
path.push(node.data.noteId);
|
||||
}
|
||||
|
||||
node = node.getParent();
|
||||
@ -32,7 +32,7 @@ const treeUtils = (function() {
|
||||
}
|
||||
|
||||
function setNodeTitleWithPrefix(node) {
|
||||
const noteTitle = noteTree.getNoteTitle(node.data.note_id);
|
||||
const noteTitle = noteTree.getNoteTitle(node.data.noteId);
|
||||
const prefix = node.data.prefix;
|
||||
|
||||
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
||||
|
@ -11,7 +11,7 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
router.get('/:noteId/attributes', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
|
||||
res.send(await sql.getAll("SELECT * FROM attributes WHERE note_id = ? ORDER BY date_created", [noteId]));
|
||||
res.send(await sql.getAll("SELECT * FROM attributes WHERE noteId = ? ORDER BY dateCreated", [noteId]));
|
||||
}));
|
||||
|
||||
router.put('/:noteId/attributes', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
@ -21,28 +21,28 @@ router.put('/:noteId/attributes', auth.checkApiAuth, wrap(async (req, res, next)
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
for (const attr of attributes) {
|
||||
if (attr.attribute_id) {
|
||||
await sql.execute("UPDATE attributes SET name = ?, value = ?, date_modified = ? WHERE attribute_id = ?",
|
||||
[attr.name, attr.value, now, attr.attribute_id]);
|
||||
if (attr.attributeId) {
|
||||
await sql.execute("UPDATE attributes SET name = ?, value = ?, dateModified = ? WHERE attributeId = ?",
|
||||
[attr.name, attr.value, now, attr.attributeId]);
|
||||
}
|
||||
else {
|
||||
attr.attribute_id = utils.newAttributeId();
|
||||
attr.attributeId = utils.newAttributeId();
|
||||
|
||||
await sql.insert("attributes", {
|
||||
attribute_id: attr.attribute_id,
|
||||
note_id: noteId,
|
||||
attributeId: attr.attributeId,
|
||||
noteId: noteId,
|
||||
name: attr.name,
|
||||
value: attr.value,
|
||||
date_created: now,
|
||||
date_modified: now
|
||||
dateCreated: now,
|
||||
dateModified: now
|
||||
});
|
||||
}
|
||||
|
||||
await sync_table.addAttributeSync(attr.attribute_id);
|
||||
await sync_table.addAttributeSync(attr.attributeId);
|
||||
}
|
||||
});
|
||||
|
||||
res.send(await sql.getAll("SELECT * FROM attributes WHERE note_id = ? ORDER BY date_created", [noteId]));
|
||||
res.send(await sql.getAll("SELECT * FROM attributes WHERE noteId = ? ORDER BY dateCreated", [noteId]));
|
||||
}));
|
||||
|
||||
module.exports = router;
|
@ -11,33 +11,33 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
await sql.doInTransaction(async () => {
|
||||
const noteIdsToDelete = await sql.getFirstColumn("SELECT note_id FROM notes WHERE is_deleted = 1");
|
||||
const noteIdsToDelete = await sql.getFirstColumn("SELECT noteId FROM notes WHERE isDeleted = 1");
|
||||
const noteIdsSql = noteIdsToDelete
|
||||
.map(noteId => "'" + utils.sanitizeSql(noteId) + "'")
|
||||
.join(', ');
|
||||
|
||||
await sql.execute(`DELETE FROM event_log WHERE note_id IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM event_log WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM notes_history WHERE note_id IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM notes_history WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM notes_image WHERE note_id IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM notes_image WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM attributes WHERE note_id IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM attributes WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute("DELETE FROM notes_tree WHERE is_deleted = 1");
|
||||
await sql.execute("DELETE FROM notes_tree WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM notes_image WHERE is_deleted = 1");
|
||||
await sql.execute("DELETE FROM notes_image WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM images WHERE is_deleted = 1");
|
||||
await sql.execute("DELETE FROM images WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM notes WHERE is_deleted = 1");
|
||||
await sql.execute("DELETE FROM notes WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM recent_notes");
|
||||
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes", "note_id");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes_tree", "note_tree_id");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes_history", "note_history_id");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "note_tree_id");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes", "noteId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes_tree", "noteTreeId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes_history", "noteHistoryId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "noteTreeId");
|
||||
|
||||
log.info("Following notes has been completely cleaned from database: " + noteIdsSql);
|
||||
});
|
||||
@ -46,23 +46,23 @@ router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, wrap(async (req, r
|
||||
}));
|
||||
|
||||
router.post('/cleanup-unused-images', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
const unusedImageIds = await sql.getFirstColumn(`
|
||||
SELECT images.image_id
|
||||
SELECT images.imageId
|
||||
FROM images
|
||||
LEFT JOIN notes_image ON notes_image.image_id = images.image_id AND notes_image.is_deleted = 0
|
||||
LEFT JOIN notes_image ON notes_image.imageId = images.imageId AND notes_image.isDeleted = 0
|
||||
WHERE
|
||||
images.is_deleted = 0
|
||||
AND notes_image.note_image_id IS NULL`);
|
||||
images.isDeleted = 0
|
||||
AND notes_image.noteImageId IS NULL`);
|
||||
|
||||
const now = utils.nowDate();
|
||||
|
||||
for (const imageId of unusedImageIds) {
|
||||
log.info(`Deleting unused image: ${imageId}`);
|
||||
|
||||
await sql.execute("UPDATE images SET is_deleted = 1, data = null, date_modified = ? WHERE image_id = ?",
|
||||
await sql.execute("UPDATE images SET isDeleted = 1, data = null, dateModified = ? WHERE imageId = ?",
|
||||
[now, imageId]);
|
||||
|
||||
await sync_table.addImageSync(imageId, sourceId);
|
||||
|
@ -13,32 +13,32 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async
|
||||
const parentNoteId = req.params.parentNoteId;
|
||||
const childNoteId = req.params.childNoteId;
|
||||
const prefix = req.body.prefix;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
if (!await tree.validateParentChild(res, parentNoteId, childNoteId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(notePosition) FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
|
||||
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
const noteTree = {
|
||||
note_tree_id: utils.newNoteTreeId(),
|
||||
note_id: childNoteId,
|
||||
parent_note_id: parentNoteId,
|
||||
noteTreeId: utils.newNoteTreeId(),
|
||||
noteId: childNoteId,
|
||||
parentNoteId: parentNoteId,
|
||||
prefix: prefix,
|
||||
note_position: newNotePos,
|
||||
is_expanded: 0,
|
||||
date_modified: utils.nowDate(),
|
||||
is_deleted: 0
|
||||
notePosition: newNotePos,
|
||||
isExpanded: 0,
|
||||
dateModified: utils.nowDate(),
|
||||
isDeleted: 0
|
||||
};
|
||||
|
||||
await sql.replace("notes_tree", noteTree);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTree.note_tree_id, sourceId);
|
||||
await sync_table.addNoteTreeSync(noteTree.noteTreeId, sourceId);
|
||||
|
||||
await sql.execute("UPDATE notes_tree SET is_expanded = 1 WHERE note_id = ?", [parentNoteId]);
|
||||
await sql.execute("UPDATE notes_tree SET isExpanded = 1 WHERE noteId = ?", [parentNoteId]);
|
||||
});
|
||||
|
||||
res.send({ success: true });
|
||||
@ -47,35 +47,35 @@ router.put('/:childNoteId/clone-to/:parentNoteId', auth.checkApiAuth, wrap(async
|
||||
router.put('/:noteId/clone-after/:afterNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
const afterNoteTreeId = req.params.afterNoteTreeId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
const afterNote = await tree.getNoteTree(afterNoteTreeId);
|
||||
|
||||
if (!await tree.validateParentChild(res, afterNote.parent_note_id, noteId)) {
|
||||
if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||
// we don't change dateModified so other changes are prioritized in case of conflict
|
||||
// also we would have to sync all those modified note trees otherwise hash checks would fail
|
||||
await sql.execute("UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0",
|
||||
[afterNote.parent_note_id, afterNote.note_position]);
|
||||
await sql.execute("UPDATE notes_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0",
|
||||
[afterNote.parentNoteId, afterNote.notePosition]);
|
||||
|
||||
await sync_table.addNoteReorderingSync(afterNote.parent_note_id, sourceId);
|
||||
await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId);
|
||||
|
||||
const noteTree = {
|
||||
note_tree_id: utils.newNoteTreeId(),
|
||||
note_id: noteId,
|
||||
parent_note_id: afterNote.parent_note_id,
|
||||
note_position: afterNote.note_position + 1,
|
||||
is_expanded: 0,
|
||||
date_modified: utils.nowDate(),
|
||||
is_deleted: 0
|
||||
noteTreeId: utils.newNoteTreeId(),
|
||||
noteId: noteId,
|
||||
parentNoteId: afterNote.parentNoteId,
|
||||
notePosition: afterNote.notePosition + 1,
|
||||
isExpanded: 0,
|
||||
dateModified: utils.nowDate(),
|
||||
isDeleted: 0
|
||||
};
|
||||
|
||||
await sql.replace("notes_tree", noteTree);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTree.note_tree_id, sourceId);
|
||||
await sync_table.addNoteTreeSync(noteTree.noteTreeId, sourceId);
|
||||
});
|
||||
|
||||
res.send({ success: true });
|
||||
|
@ -9,7 +9,7 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
await deleteOld();
|
||||
|
||||
const result = await sql.getAll("SELECT * FROM event_log ORDER BY date_added DESC");
|
||||
const result = await sql.getAll("SELECT * FROM event_log ORDER BY dateAdded DESC");
|
||||
|
||||
res.send(result);
|
||||
}));
|
||||
|
@ -26,7 +26,7 @@ router.get('/:noteId/to/:directory', auth.checkApiAuth, wrap(async (req, res, ne
|
||||
|
||||
fs.mkdirSync(completeExportDir);
|
||||
|
||||
const noteTreeId = await sql.getFirstValue('SELECT note_tree_id FROM notes_tree WHERE note_id = ?', [noteId]);
|
||||
const noteTreeId = await sql.getFirstValue('SELECT noteTreeId FROM notes_tree WHERE noteId = ?', [noteId]);
|
||||
|
||||
await exportNote(noteTreeId, completeExportDir);
|
||||
|
||||
@ -34,22 +34,22 @@ router.get('/:noteId/to/:directory', auth.checkApiAuth, wrap(async (req, res, ne
|
||||
}));
|
||||
|
||||
async function exportNote(noteTreeId, dir) {
|
||||
const noteTree = await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteTree.note_id]);
|
||||
const noteTree = await sql.getFirst("SELECT * FROM notes_tree WHERE noteTreeId = ?", [noteTreeId]);
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteTree.noteId]);
|
||||
|
||||
const pos = (noteTree.note_position + '').padStart(4, '0');
|
||||
const pos = (noteTree.notePosition + '').padStart(4, '0');
|
||||
|
||||
fs.writeFileSync(dir + '/' + pos + '-' + note.note_title + '.html', html.prettyPrint(note.note_text, {indent_size: 2}));
|
||||
fs.writeFileSync(dir + '/' + pos + '-' + note.title + '.html', html.prettyPrint(note.content, {indent_size: 2}));
|
||||
|
||||
const children = await sql.getAll("SELECT * FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [note.note_id]);
|
||||
const children = await sql.getAll("SELECT * FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [note.noteId]);
|
||||
|
||||
if (children.length > 0) {
|
||||
const childrenDir = dir + '/' + pos + '-' + note.note_title;
|
||||
const childrenDir = dir + '/' + pos + '-' + note.title;
|
||||
|
||||
fs.mkdirSync(childrenDir);
|
||||
|
||||
for (const child of children) {
|
||||
await exportNote(child.note_tree_id, childrenDir);
|
||||
await exportNote(child.noteTreeId, childrenDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
||||
const fs = require('fs');
|
||||
|
||||
router.get('/:imageId/:filename', auth.checkApiAuthOrElectron, wrap(async (req, res, next) => {
|
||||
const image = await sql.getFirst("SELECT * FROM images WHERE image_id = ?", [req.params.imageId]);
|
||||
const image = await sql.getFirst("SELECT * FROM images WHERE imageId = ?", [req.params.imageId]);
|
||||
|
||||
if (!image) {
|
||||
return res.status(404).send({});
|
||||
@ -35,11 +35,11 @@ router.get('/:imageId/:filename', auth.checkApiAuthOrElectron, wrap(async (req,
|
||||
}));
|
||||
|
||||
router.post('', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async (req, res, next) => {
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
const noteId = req.query.noteId;
|
||||
const file = req.file;
|
||||
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
if (!note) {
|
||||
return res.status(404).send(`Note ${noteId} doesn't exist.`);
|
||||
@ -63,14 +63,14 @@ router.post('', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.insert("images", {
|
||||
image_id: imageId,
|
||||
imageId: imageId,
|
||||
format: imageFormat.ext,
|
||||
name: fileName,
|
||||
checksum: utils.hash(optimizedImage),
|
||||
data: optimizedImage,
|
||||
is_deleted: 0,
|
||||
date_modified: now,
|
||||
date_created: now
|
||||
isDeleted: 0,
|
||||
dateModified: now,
|
||||
dateCreated: now
|
||||
});
|
||||
|
||||
await sync_table.addImageSync(imageId, sourceId);
|
||||
@ -78,12 +78,12 @@ router.post('', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async
|
||||
const noteImageId = utils.newNoteImageId();
|
||||
|
||||
await sql.insert("notes_image", {
|
||||
note_image_id: noteImageId,
|
||||
note_id: noteId,
|
||||
image_id: imageId,
|
||||
is_deleted: 0,
|
||||
date_modified: now,
|
||||
date_created: now
|
||||
noteImageId: noteImageId,
|
||||
noteId: noteId,
|
||||
imageId: imageId,
|
||||
isDeleted: 0,
|
||||
dateModified: now,
|
||||
dateCreated: now
|
||||
});
|
||||
|
||||
await sync_table.addNoteImageSync(noteImageId, sourceId);
|
||||
|
@ -22,7 +22,7 @@ router.get('/:directory/to/:parentNoteId', auth.checkApiAuth, wrap(async (req, r
|
||||
}));
|
||||
|
||||
async function importNotes(dir, parentNoteId) {
|
||||
const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]);
|
||||
const parent = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [parentNoteId]);
|
||||
|
||||
if (!parent) {
|
||||
return;
|
||||
@ -52,7 +52,7 @@ async function importNotes(dir, parentNoteId) {
|
||||
noteTitle = match[2];
|
||||
}
|
||||
else {
|
||||
let maxPos = await sql.getFirstValue("SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [parentNoteId]);
|
||||
let maxPos = await sql.getFirstValue("SELECT MAX(notePosition) FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId]);
|
||||
if (maxPos) {
|
||||
notePos = maxPos + 1;
|
||||
}
|
||||
@ -71,27 +71,27 @@ async function importNotes(dir, parentNoteId) {
|
||||
const now = utils.nowDate();
|
||||
|
||||
await sql.insert('notes_tree', {
|
||||
note_tree_id: noteTreeId,
|
||||
note_id: noteId,
|
||||
parent_note_id: parentNoteId,
|
||||
note_position: notePos,
|
||||
is_expanded: 0,
|
||||
is_deleted: 0,
|
||||
date_modified: now
|
||||
noteTreeId: noteTreeId,
|
||||
noteId: noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
notePosition: notePos,
|
||||
isExpanded: 0,
|
||||
isDeleted: 0,
|
||||
dateModified: now
|
||||
});
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId);
|
||||
|
||||
await sql.insert('notes', {
|
||||
note_id: noteId,
|
||||
note_title: noteTitle,
|
||||
note_text: noteText,
|
||||
is_deleted: 0,
|
||||
is_protected: 0,
|
||||
noteId: noteId,
|
||||
title: noteTitle,
|
||||
content: noteText,
|
||||
isDeleted: 0,
|
||||
isProtected: 0,
|
||||
type: 'text',
|
||||
mime: 'text/html',
|
||||
date_created: now,
|
||||
date_modified: now
|
||||
dateCreated: now,
|
||||
dateModified: now
|
||||
});
|
||||
|
||||
await sync_table.addNoteSync(noteId);
|
||||
|
@ -4,7 +4,7 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const options = require('../../services/options');
|
||||
const utils = require('../../services/utils');
|
||||
const source_id = require('../../services/source_id');
|
||||
const sourceId = require('../../services/sourceId');
|
||||
const auth = require('../../services/auth');
|
||||
const password_encryption = require('../../services/password_encryption');
|
||||
const protected_session = require('../../services/protected_session');
|
||||
@ -43,7 +43,7 @@ router.post('/sync', wrap(async (req, res, next) => {
|
||||
req.session.loggedIn = true;
|
||||
|
||||
res.send({
|
||||
sourceId: source_id.getCurrentSourceId()
|
||||
sourceId: sourceId.getCurrentSourceId()
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -10,19 +10,19 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
const history = await sql.getAll("SELECT * FROM notes_history WHERE note_id = ? order by date_modified_to desc", [noteId]);
|
||||
const history = await sql.getAll("SELECT * FROM notes_history WHERE noteId = ? order by dateModifiedTo desc", [noteId]);
|
||||
protected_session.decryptNoteHistoryRows(req, history);
|
||||
|
||||
res.send(history);
|
||||
}));
|
||||
|
||||
router.put('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace("notes_history", req.body);
|
||||
|
||||
await sync_table.addNoteHistorySync(req.body.note_history_id, sourceId);
|
||||
await sync_table.addNoteHistorySync(req.body.noteHistoryId, sourceId);
|
||||
});
|
||||
|
||||
res.send();
|
||||
|
@ -15,7 +15,7 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
|
||||
const detail = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
|
||||
const detail = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
if (!detail) {
|
||||
log.info("Note " + noteId + " has not been found.");
|
||||
@ -31,7 +31,7 @@ router.get('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
}));
|
||||
|
||||
router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
const parentNoteId = req.params.parentNoteId;
|
||||
const newNote = req.body;
|
||||
|
||||
@ -39,8 +39,8 @@ router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res,
|
||||
const { noteId, noteTreeId, note } = await notes.createNewNote(parentNoteId, newNote, req, sourceId);
|
||||
|
||||
res.send({
|
||||
'note_id': noteId,
|
||||
'note_tree_id': noteTreeId,
|
||||
'noteId': noteId,
|
||||
'noteTreeId': noteTreeId,
|
||||
'note': note
|
||||
});
|
||||
});
|
||||
@ -49,7 +49,7 @@ router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res,
|
||||
router.put('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const note = req.body;
|
||||
const noteId = req.params.noteId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
const dataKey = protected_session.getDataKey(req);
|
||||
|
||||
await notes.updateNote(noteId, note, dataKey, sourceId);
|
||||
@ -61,15 +61,15 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const search = '%' + utils.sanitizeSql(req.query.search) + '%';
|
||||
|
||||
// searching in protected notes is pointless because of encryption
|
||||
const noteIds = await sql.getFirstColumn(`SELECT note_id FROM notes
|
||||
WHERE is_deleted = 0 AND is_protected = 0 AND (note_title LIKE ? OR note_text LIKE ?)`, [search, search]);
|
||||
const noteIds = await sql.getFirstColumn(`SELECT noteId FROM notes
|
||||
WHERE isDeleted = 0 AND isProtected = 0 AND (title LIKE ? OR content LIKE ?)`, [search, search]);
|
||||
|
||||
res.send(noteIds);
|
||||
}));
|
||||
|
||||
router.put('/:noteId/sort', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
const dataKey = protected_session.getDataKey(req);
|
||||
|
||||
await tree.sortNotesAlphabetically(noteId, dataKey, sourceId);
|
||||
@ -81,7 +81,7 @@ router.put('/:noteId/protect-sub-tree/:isProtected', auth.checkApiAuth, wrap(asy
|
||||
const noteId = req.params.noteId;
|
||||
const isProtected = !!parseInt(req.params.isProtected);
|
||||
const dataKey = protected_session.getDataKey(req);
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await notes.protectNoteRecursively(noteId, dataKey, isProtected, sourceId);
|
||||
@ -94,10 +94,10 @@ router.put(/\/(.*)\/type\/(.*)\/mime\/(.*)/, auth.checkApiAuth, wrap(async (req,
|
||||
const noteId = req.params[0];
|
||||
const type = req.params[1];
|
||||
const mime = req.params[2];
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.execute("UPDATE notes SET type = ?, mime = ?, date_modified = ? WHERE note_id = ?",
|
||||
await sql.execute("UPDATE notes SET type = ?, mime = ?, dateModified = ? WHERE noteId = ?",
|
||||
[type, mime, utils.nowDate(), noteId]);
|
||||
|
||||
await sync_table.addNoteSync(noteId, sourceId);
|
||||
|
@ -9,14 +9,14 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const recentChanges = await sql.getAll(
|
||||
`SELECT
|
||||
notes.is_deleted AS current_is_deleted,
|
||||
notes.note_title AS current_note_title,
|
||||
notes.isDeleted AS current_isDeleted,
|
||||
notes.title AS current_title,
|
||||
notes_history.*
|
||||
FROM
|
||||
notes_history
|
||||
JOIN notes USING(note_id)
|
||||
JOIN notes USING(noteId)
|
||||
ORDER BY
|
||||
date_modified_to DESC
|
||||
dateModifiedTo DESC
|
||||
LIMIT 1000`);
|
||||
|
||||
res.send(recentChanges);
|
||||
|
@ -16,19 +16,19 @@ router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
router.put('/:noteTreeId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
const notePath = req.params.notePath;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace('recent_notes', {
|
||||
note_tree_id: noteTreeId,
|
||||
note_path: notePath,
|
||||
date_accessed: utils.nowDate(),
|
||||
is_deleted: 0
|
||||
noteTreeId: noteTreeId,
|
||||
notePath: notePath,
|
||||
dateAccessed: utils.nowDate(),
|
||||
isDeleted: 0
|
||||
});
|
||||
|
||||
await sync_table.addRecentNoteSync(noteTreeId, sourceId);
|
||||
|
||||
await options.setOption('start_note_path', notePath, sourceId);
|
||||
await options.setOption('start_notePath', notePath, sourceId);
|
||||
});
|
||||
|
||||
res.send(await getRecentNotes());
|
||||
@ -40,12 +40,12 @@ async function getRecentNotes() {
|
||||
recent_notes.*
|
||||
FROM
|
||||
recent_notes
|
||||
JOIN notes_tree USING(note_tree_id)
|
||||
JOIN notes_tree USING(noteTreeId)
|
||||
WHERE
|
||||
recent_notes.is_deleted = 0
|
||||
AND notes_tree.is_deleted = 0
|
||||
recent_notes.isDeleted = 0
|
||||
AND notes_tree.isDeleted = 0
|
||||
ORDER BY
|
||||
date_accessed DESC`);
|
||||
dateAccessed DESC`);
|
||||
}
|
||||
|
||||
module.exports = router;
|
@ -33,7 +33,7 @@ router.get('/startup', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
|
||||
const noteScript = (await notes.getNoteById(noteId, req)).note_text;
|
||||
const noteScript = (await notes.getNoteById(noteId, req)).content;
|
||||
|
||||
const subTreeScripts = await getSubTreeScripts(noteId, [noteId], req);
|
||||
|
||||
@ -41,7 +41,7 @@ router.get('/subtree/:noteId', auth.checkApiAuth, wrap(async (req, res, next) =>
|
||||
}));
|
||||
|
||||
async function getNoteWithSubtreeScript(noteId, req) {
|
||||
const noteScript = (await notes.getNoteById(noteId, req)).note_text;
|
||||
const noteScript = (await notes.getNoteById(noteId, req)).content;
|
||||
|
||||
const subTreeScripts = await getSubTreeScripts(noteId, [noteId], req);
|
||||
|
||||
@ -49,10 +49,10 @@ async function getNoteWithSubtreeScript(noteId, req) {
|
||||
}
|
||||
|
||||
async function getSubTreeScripts(parentId, includedNoteIds, dataKey) {
|
||||
const children = await sql.getAll(`SELECT notes.note_id, notes.note_title, notes.note_text, notes.is_protected, notes.mime
|
||||
FROM notes JOIN notes_tree USING(note_id)
|
||||
WHERE notes_tree.is_deleted = 0 AND notes.is_deleted = 0
|
||||
AND notes_tree.parent_note_id = ? AND notes.type = 'code'
|
||||
const children = await sql.getAll(`SELECT notes.noteId, notes.title, notes.content, notes.isProtected, notes.mime
|
||||
FROM notes JOIN notes_tree USING(noteId)
|
||||
WHERE notes_tree.isDeleted = 0 AND notes.isDeleted = 0
|
||||
AND notes_tree.parentNoteId = ? AND notes.type = 'code'
|
||||
AND (notes.mime = 'application/javascript' OR notes.mime = 'text/html')`, [parentId]);
|
||||
|
||||
protected_session.decryptNotes(dataKey, children);
|
||||
@ -60,19 +60,19 @@ async function getSubTreeScripts(parentId, includedNoteIds, dataKey) {
|
||||
let script = "\r\n";
|
||||
|
||||
for (const child of children) {
|
||||
if (includedNoteIds.includes(child.note_id)) {
|
||||
if (includedNoteIds.includes(child.noteId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
includedNoteIds.push(child.note_id);
|
||||
includedNoteIds.push(child.noteId);
|
||||
|
||||
script += await getSubTreeScripts(child.note_id, includedNoteIds, dataKey);
|
||||
script += await getSubTreeScripts(child.noteId, includedNoteIds, dataKey);
|
||||
|
||||
if (child.mime === 'application/javascript') {
|
||||
child.note_text = '<script>' + child.note_text + '</script>';
|
||||
child.content = '<script>' + child.content + '</script>';
|
||||
}
|
||||
|
||||
script += child.note_text + "\r\n";
|
||||
script += child.content + "\r\n";
|
||||
}
|
||||
|
||||
return script;
|
||||
|
@ -11,13 +11,13 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
const ALLOWED_OPTIONS = ['protected_session_timeout', 'history_snapshot_time_interval'];
|
||||
|
||||
router.get('/all', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const settings = await sql.getMap("SELECT opt_name, opt_value FROM options");
|
||||
const settings = await sql.getMap("SELECT name, value FROM options");
|
||||
|
||||
res.send(settings);
|
||||
}));
|
||||
|
||||
router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const settings = await sql.getMap("SELECT opt_name, opt_value FROM options WHERE opt_name IN ("
|
||||
const settings = await sql.getMap("SELECT name, value FROM options WHERE name IN ("
|
||||
+ ALLOWED_OPTIONS.map(x => '?').join(",") + ")", ALLOWED_OPTIONS);
|
||||
|
||||
res.send(settings);
|
||||
@ -25,7 +25,7 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
|
||||
router.post('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const body = req.body;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
if (ALLOWED_OPTIONS.includes(body['name'])) {
|
||||
const optionName = await options.getOption(body['name']);
|
||||
|
@ -53,12 +53,12 @@ router.post('/force-note-sync/:noteId', auth.checkApiAuth, wrap(async (req, res,
|
||||
await sql.doInTransaction(async () => {
|
||||
await sync_table.addNoteSync(noteId);
|
||||
|
||||
for (const noteTreeId of await sql.getFirstColumn("SELECT note_tree_id FROM notes_tree WHERE is_deleted = 0 AND note_id = ?", [noteId])) {
|
||||
for (const noteTreeId of await sql.getFirstColumn("SELECT noteTreeId FROM notes_tree WHERE isDeleted = 0 AND noteId = ?", [noteId])) {
|
||||
await sync_table.addNoteTreeSync(noteTreeId);
|
||||
await sync_table.addRecentNoteSync(noteTreeId);
|
||||
}
|
||||
|
||||
for (const noteHistoryId of await sql.getFirstColumn("SELECT note_history_id FROM notes_history WHERE note_id = ?", [noteId])) {
|
||||
for (const noteHistoryId of await sql.getFirstColumn("SELECT noteHistoryId FROM notes_history WHERE noteId = ?", [noteId])) {
|
||||
await sync_table.addNoteHistorySync(noteHistoryId);
|
||||
}
|
||||
});
|
||||
@ -81,27 +81,27 @@ router.get('/notes/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteId = req.params.noteId;
|
||||
|
||||
res.send({
|
||||
entity: await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId])
|
||||
entity: await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId])
|
||||
});
|
||||
}));
|
||||
|
||||
router.get('/notes_tree/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]));
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_tree WHERE noteTreeId = ?", [noteTreeId]));
|
||||
}));
|
||||
|
||||
router.get('/notes_history/:noteHistoryId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteHistoryId = req.params.noteHistoryId;
|
||||
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_history WHERE note_history_id = ?", [noteHistoryId]));
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_history WHERE noteHistoryId = ?", [noteHistoryId]));
|
||||
}));
|
||||
|
||||
router.get('/options/:optName', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const optName = req.params.optName;
|
||||
const opt = await sql.getFirst("SELECT * FROM options WHERE opt_name = ?", [optName]);
|
||||
router.get('/options/:name', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const name = req.params.name;
|
||||
const opt = await sql.getFirst("SELECT * FROM options WHERE name = ?", [name]);
|
||||
|
||||
if (!opt.is_synced) {
|
||||
if (!opt.isSynced) {
|
||||
res.send("This option can't be synced.");
|
||||
}
|
||||
else {
|
||||
@ -109,24 +109,24 @@ router.get('/options/:optName', auth.checkApiAuth, wrap(async (req, res, next) =
|
||||
}
|
||||
}));
|
||||
|
||||
router.get('/notes_reordering/:noteTreeParentId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeParentId = req.params.noteTreeParentId;
|
||||
router.get('/notes_reordering/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const parentNoteId = req.params.parentNoteId;
|
||||
|
||||
res.send({
|
||||
parent_note_id: noteTreeParentId,
|
||||
ordering: await sql.getMap("SELECT note_tree_id, note_position FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteTreeParentId])
|
||||
parentNoteId: parentNoteId,
|
||||
ordering: await sql.getMap("SELECT noteTreeId, notePosition FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId])
|
||||
});
|
||||
}));
|
||||
|
||||
router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
|
||||
res.send(await sql.getFirst("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId]));
|
||||
res.send(await sql.getFirst("SELECT * FROM recent_notes WHERE noteTreeId = ?", [noteTreeId]));
|
||||
}));
|
||||
|
||||
router.get('/images/:imageId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const imageId = req.params.imageId;
|
||||
const entity = await sql.getFirst("SELECT * FROM images WHERE image_id = ?", [imageId]);
|
||||
const entity = await sql.getFirst("SELECT * FROM images WHERE imageId = ?", [imageId]);
|
||||
|
||||
if (entity && entity.data !== null) {
|
||||
entity.data = entity.data.toString('base64');
|
||||
@ -138,13 +138,13 @@ router.get('/images/:imageId', auth.checkApiAuth, wrap(async (req, res, next) =>
|
||||
router.get('/notes_image/:noteImageId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteImageId = req.params.noteImageId;
|
||||
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_image WHERE note_image_id = ?", [noteImageId]));
|
||||
res.send(await sql.getFirst("SELECT * FROM notes_image WHERE noteImageId = ?", [noteImageId]));
|
||||
}));
|
||||
|
||||
router.get('/attributes/:attributeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const attributeId = req.params.attributeId;
|
||||
|
||||
res.send(await sql.getFirst("SELECT * FROM attributes WHERE attribute_id = ?", [attributeId]));
|
||||
res.send(await sql.getFirst("SELECT * FROM attributes WHERE attributeId = ?", [attributeId]));
|
||||
}));
|
||||
|
||||
router.put('/notes', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
|
@ -14,34 +14,34 @@ router.get('/', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const notes = await sql.getAll(`
|
||||
SELECT
|
||||
notes_tree.*,
|
||||
notes.note_title,
|
||||
notes.is_protected,
|
||||
notes.title,
|
||||
notes.isProtected,
|
||||
notes.type
|
||||
FROM
|
||||
notes_tree
|
||||
JOIN
|
||||
notes ON notes.note_id = notes_tree.note_id
|
||||
notes ON notes.noteId = notes_tree.noteId
|
||||
WHERE
|
||||
notes.is_deleted = 0
|
||||
AND notes_tree.is_deleted = 0
|
||||
notes.isDeleted = 0
|
||||
AND notes_tree.isDeleted = 0
|
||||
ORDER BY
|
||||
note_position`);
|
||||
notePosition`);
|
||||
|
||||
protected_session.decryptNotes(req, notes);
|
||||
|
||||
res.send({
|
||||
notes: notes,
|
||||
start_note_path: await options.getOption('start_note_path')
|
||||
start_notePath: await options.getOption('start_notePath')
|
||||
});
|
||||
}));
|
||||
|
||||
router.put('/:noteTreeId/set-prefix', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
const prefix = utils.isEmptyOrWhitespace(req.body.prefix) ? null : req.body.prefix;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.execute("UPDATE notes_tree SET prefix = ?, date_modified = ? WHERE note_tree_id = ?", [prefix, utils.nowDate(), noteTreeId]);
|
||||
await sql.execute("UPDATE notes_tree SET prefix = ?, dateModified = ? WHERE noteTreeId = ?", [prefix, utils.nowDate(), noteTreeId]);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
});
|
||||
|
@ -18,21 +18,21 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
const parentNoteId = req.params.parentNoteId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
const noteToMove = await tree.getNoteTree(noteTreeId);
|
||||
|
||||
if (!await tree.validateParentChild(res, parentNoteId, noteToMove.note_id, noteTreeId)) {
|
||||
if (!await tree.validateParentChild(res, parentNoteId, noteToMove.noteId, noteTreeId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(notePosition) FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
|
||||
const newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
|
||||
|
||||
const now = utils.nowDate();
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.execute("UPDATE notes_tree SET parent_note_id = ?, note_position = ?, date_modified = ? WHERE note_tree_id = ?",
|
||||
await sql.execute("UPDATE notes_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?",
|
||||
[parentNoteId, newNotePos, now, noteTreeId]);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
@ -44,27 +44,27 @@ router.put('/:noteTreeId/move-to/:parentNoteId', auth.checkApiAuth, wrap(async (
|
||||
router.put('/:noteTreeId/move-before/:beforeNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
const beforeNoteTreeId = req.params.beforeNoteTreeId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
const noteToMove = await tree.getNoteTree(noteTreeId);
|
||||
const beforeNote = await tree.getNoteTree(beforeNoteTreeId);
|
||||
|
||||
if (!await tree.validateParentChild(res, beforeNote.parent_note_id, noteToMove.note_id, noteTreeId)) {
|
||||
if (!await tree.validateParentChild(res, beforeNote.parentNoteId, noteToMove.noteId, noteTreeId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||
// we don't change dateModified so other changes are prioritized in case of conflict
|
||||
// also we would have to sync all those modified note trees otherwise hash checks would fail
|
||||
await sql.execute("UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position >= ? AND is_deleted = 0",
|
||||
[beforeNote.parent_note_id, beforeNote.note_position]);
|
||||
await sql.execute("UPDATE notes_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0",
|
||||
[beforeNote.parentNoteId, beforeNote.notePosition]);
|
||||
|
||||
await sync_table.addNoteReorderingSync(beforeNote.parent_note_id, sourceId);
|
||||
await sync_table.addNoteReorderingSync(beforeNote.parentNoteId, sourceId);
|
||||
|
||||
const now = utils.nowDate();
|
||||
|
||||
await sql.execute("UPDATE notes_tree SET parent_note_id = ?, note_position = ?, date_modified = ? WHERE note_tree_id = ?",
|
||||
[beforeNote.parent_note_id, beforeNote.note_position, now, noteTreeId]);
|
||||
await sql.execute("UPDATE notes_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?",
|
||||
[beforeNote.parentNoteId, beforeNote.notePosition, now, noteTreeId]);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
});
|
||||
@ -75,25 +75,25 @@ router.put('/:noteTreeId/move-before/:beforeNoteTreeId', auth.checkApiAuth, wrap
|
||||
router.put('/:noteTreeId/move-after/:afterNoteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
const noteTreeId = req.params.noteTreeId;
|
||||
const afterNoteTreeId = req.params.afterNoteTreeId;
|
||||
const sourceId = req.headers.source_id;
|
||||
const sourceId = req.headers.sourceId;
|
||||
|
||||
const noteToMove = await tree.getNoteTree(noteTreeId);
|
||||
const afterNote = await tree.getNoteTree(afterNoteTreeId);
|
||||
|
||||
if (!await tree.validateParentChild(res, afterNote.parent_note_id, noteToMove.note_id, noteTreeId)) {
|
||||
if (!await tree.validateParentChild(res, afterNote.parentNoteId, noteToMove.noteId, noteTreeId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
// we don't change date_modified so other changes are prioritized in case of conflict
|
||||
// we don't change dateModified so other changes are prioritized in case of conflict
|
||||
// also we would have to sync all those modified note trees otherwise hash checks would fail
|
||||
await sql.execute("UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0",
|
||||
[afterNote.parent_note_id, afterNote.note_position]);
|
||||
await sql.execute("UPDATE notes_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0",
|
||||
[afterNote.parentNoteId, afterNote.notePosition]);
|
||||
|
||||
await sync_table.addNoteReorderingSync(afterNote.parent_note_id, sourceId);
|
||||
await sync_table.addNoteReorderingSync(afterNote.parentNoteId, sourceId);
|
||||
|
||||
await sql.execute("UPDATE notes_tree SET parent_note_id = ?, note_position = ?, date_modified = ? WHERE note_tree_id = ?",
|
||||
[afterNote.parent_note_id, afterNote.note_position + 1, utils.nowDate(), noteTreeId]);
|
||||
await sql.execute("UPDATE notes_tree SET parentNoteId = ?, notePosition = ?, dateModified = ? WHERE noteTreeId = ?",
|
||||
[afterNote.parentNoteId, afterNote.notePosition + 1, utils.nowDate(), noteTreeId]);
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
});
|
||||
@ -106,7 +106,7 @@ router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req
|
||||
const expanded = req.params.expanded;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.execute("UPDATE notes_tree SET is_expanded = ? WHERE note_tree_id = ?", [expanded, noteTreeId]);
|
||||
await sql.execute("UPDATE notes_tree SET isExpanded = ? WHERE noteTreeId = ?", [expanded, noteTreeId]);
|
||||
|
||||
// we don't sync expanded attribute
|
||||
});
|
||||
@ -116,7 +116,7 @@ router.put('/:noteTreeId/expanded/:expanded', auth.checkApiAuth, wrap(async (req
|
||||
|
||||
router.delete('/:noteTreeId', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
await sql.doInTransaction(async () => {
|
||||
await notes.deleteNote(req.params.noteTreeId, req.headers.source_id);
|
||||
await notes.deleteNote(req.params.noteTreeId, req.headers.sourceId);
|
||||
});
|
||||
|
||||
res.send({});
|
||||
|
@ -3,13 +3,13 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const auth = require('../services/auth');
|
||||
const source_id = require('../services/source_id');
|
||||
const sourceId = require('../services/sourceId');
|
||||
const sql = require('../services/sql');
|
||||
const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.get('', auth.checkAuth, wrap(async (req, res, next) => {
|
||||
res.render('index', {
|
||||
sourceId: await source_id.generateSourceId(),
|
||||
sourceId: await sourceId.generateSourceId(),
|
||||
maxSyncIdAtLoad: await sql.getFirstValue("SELECT MAX(id) FROM sync")
|
||||
});
|
||||
}));
|
||||
|
@ -16,10 +16,10 @@ async function anonymize() {
|
||||
|
||||
const db = await sqlite.open(anonymizedFile, {Promise});
|
||||
|
||||
await db.run("UPDATE notes SET note_title = 'title', note_text = 'text'");
|
||||
await db.run("UPDATE notes_history SET note_title = 'title', note_text = 'text'");
|
||||
await db.run("UPDATE notes SET title = 'title', content = 'text'");
|
||||
await db.run("UPDATE notes_history SET title = 'title', content = 'text'");
|
||||
await db.run("UPDATE notes_tree SET prefix = 'prefix' WHERE prefix IS NOT NULL");
|
||||
await db.run(`UPDATE options SET opt_value = 'anonymized' WHERE opt_name IN
|
||||
await db.run(`UPDATE options SET value = 'anonymized' WHERE name IN
|
||||
('document_secret', 'encrypted_data_key', 'password_verification_hash',
|
||||
'password_verification_salt', 'password_derived_key_salt')`);
|
||||
await db.run("VACUUM");
|
||||
|
@ -6,24 +6,24 @@ const sync_table = require('./sync_table');
|
||||
const protected_session = require('./protected_session');
|
||||
|
||||
async function getNoteAttributeMap(noteId) {
|
||||
return await sql.getMap(`SELECT name, value FROM attributes WHERE note_id = ?`, [noteId]);
|
||||
return await sql.getMap(`SELECT name, value FROM attributes WHERE noteId = ?`, [noteId]);
|
||||
}
|
||||
|
||||
async function getNoteIdWithAttribute(name, value) {
|
||||
return await sql.getFirstValue(`SELECT notes.note_id FROM notes JOIN attributes USING(note_id)
|
||||
WHERE notes.is_deleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
||||
return await sql.getFirstValue(`SELECT notes.noteId FROM notes JOIN attributes USING(noteId)
|
||||
WHERE notes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
||||
}
|
||||
|
||||
async function getNotesWithAttribute(dataKey, name, value) {
|
||||
let notes;
|
||||
|
||||
if (value !== undefined) {
|
||||
notes = await sql.getAll(`SELECT notes.* FROM notes JOIN attributes USING(note_id)
|
||||
WHERE notes.is_deleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
||||
notes = await sql.getAll(`SELECT notes.* FROM notes JOIN attributes USING(noteId)
|
||||
WHERE notes.isDeleted = 0 AND attributes.name = ? AND attributes.value = ?`, [name, value]);
|
||||
}
|
||||
else {
|
||||
notes = await sql.getAll(`SELECT notes.* FROM notes JOIN attributes USING(note_id)
|
||||
WHERE notes.is_deleted = 0 AND attributes.name = ?`, [name]);
|
||||
notes = await sql.getAll(`SELECT notes.* FROM notes JOIN attributes USING(noteId)
|
||||
WHERE notes.isDeleted = 0 AND attributes.name = ?`, [name]);
|
||||
}
|
||||
|
||||
for (const note of notes) {
|
||||
@ -40,8 +40,8 @@ async function getNoteWithAttribute(dataKey, name, value) {
|
||||
}
|
||||
|
||||
async function getNoteIdsWithAttribute(name) {
|
||||
return await sql.getFirstColumn(`SELECT DISTINCT notes.note_id FROM notes JOIN attributes USING(note_id)
|
||||
WHERE notes.is_deleted = 0 AND attributes.name = ?`, [name]);
|
||||
return await sql.getFirstColumn(`SELECT DISTINCT notes.noteId FROM notes JOIN attributes USING(noteId)
|
||||
WHERE notes.isDeleted = 0 AND attributes.name = ?`, [name]);
|
||||
}
|
||||
|
||||
async function createAttribute(noteId, name, value = null, sourceId = null) {
|
||||
@ -49,12 +49,12 @@ async function createAttribute(noteId, name, value = null, sourceId = null) {
|
||||
const attributeId = utils.newAttributeId();
|
||||
|
||||
await sql.insert("attributes", {
|
||||
attribute_id: attributeId,
|
||||
note_id: noteId,
|
||||
attributeId: attributeId,
|
||||
noteId: noteId,
|
||||
name: name,
|
||||
value: value,
|
||||
date_modified: now,
|
||||
date_created: now
|
||||
dateModified: now,
|
||||
dateCreated: now
|
||||
});
|
||||
|
||||
await sync_table.addAttributeSync(attributeId, sourceId);
|
||||
|
@ -23,11 +23,11 @@ async function runCheck(query, errorText, errorList) {
|
||||
|
||||
async function checkTreeCycles(errorList) {
|
||||
const childToParents = {};
|
||||
const rows = await sql.getAll("SELECT note_id, parent_note_id FROM notes_tree WHERE is_deleted = 0");
|
||||
const rows = await sql.getAll("SELECT noteId, parentNoteId FROM notes_tree WHERE isDeleted = 0");
|
||||
|
||||
for (const row of rows) {
|
||||
const childNoteId = row.note_id;
|
||||
const parentNoteId = row.parent_note_id;
|
||||
const childNoteId = row.noteId;
|
||||
const parentNoteId = row.parentNoteId;
|
||||
|
||||
if (!childToParents[childNoteId]) {
|
||||
childToParents[childNoteId] = [];
|
||||
@ -67,19 +67,19 @@ async function runSyncRowChecks(table, key, errorList) {
|
||||
${key}
|
||||
FROM
|
||||
${table}
|
||||
LEFT JOIN sync ON sync.entity_name = '${table}' AND entity_id = ${key}
|
||||
LEFT JOIN sync ON sync.entityName = '${table}' AND entityId = ${key}
|
||||
WHERE
|
||||
sync.id IS NULL`,
|
||||
`Missing sync records for ${key} in table ${table}`, errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
entity_id
|
||||
entityId
|
||||
FROM
|
||||
sync
|
||||
LEFT JOIN ${table} ON entity_id = ${key}
|
||||
LEFT JOIN ${table} ON entityId = ${key}
|
||||
WHERE
|
||||
sync.entity_name = '${table}'
|
||||
sync.entityName = '${table}'
|
||||
AND ${key} IS NULL`,
|
||||
`Missing ${table} records for existing sync rows`, errorList);
|
||||
}
|
||||
@ -89,140 +89,140 @@ async function runAllChecks() {
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_id
|
||||
noteId
|
||||
FROM
|
||||
notes
|
||||
LEFT JOIN notes_tree USING(note_id)
|
||||
LEFT JOIN notes_tree USING(noteId)
|
||||
WHERE
|
||||
note_id != 'root'
|
||||
AND notes_tree.note_tree_id IS NULL`,
|
||||
noteId != 'root'
|
||||
AND notes_tree.noteTreeId IS NULL`,
|
||||
"Missing notes_tree records for following note IDs", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_tree_id || ' > ' || notes_tree.note_id
|
||||
noteTreeId || ' > ' || notes_tree.noteId
|
||||
FROM
|
||||
notes_tree
|
||||
LEFT JOIN notes USING(note_id)
|
||||
LEFT JOIN notes USING(noteId)
|
||||
WHERE
|
||||
notes.note_id IS NULL`,
|
||||
notes.noteId IS NULL`,
|
||||
"Missing notes records for following note tree ID > note ID", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_tree_id
|
||||
noteTreeId
|
||||
FROM
|
||||
notes_tree
|
||||
JOIN notes USING(note_id)
|
||||
JOIN notes USING(noteId)
|
||||
WHERE
|
||||
notes.is_deleted = 1
|
||||
AND notes_tree.is_deleted = 0`,
|
||||
notes.isDeleted = 1
|
||||
AND notes_tree.isDeleted = 0`,
|
||||
"Note tree is not deleted even though main note is deleted for following note tree IDs", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
child.note_tree_id
|
||||
child.noteTreeId
|
||||
FROM
|
||||
notes_tree AS child
|
||||
WHERE
|
||||
child.is_deleted = 0
|
||||
AND child.parent_note_id != 'root'
|
||||
AND (SELECT COUNT(*) FROM notes_tree AS parent WHERE parent.note_id = child.parent_note_id
|
||||
AND parent.is_deleted = 0) = 0`,
|
||||
child.isDeleted = 0
|
||||
AND child.parentNoteId != 'root'
|
||||
AND (SELECT COUNT(*) FROM notes_tree AS parent WHERE parent.noteId = child.parentNoteId
|
||||
AND parent.isDeleted = 0) = 0`,
|
||||
"All parent note trees are deleted but child note tree is not for these child note tree IDs", errorList);
|
||||
|
||||
// we do extra JOIN to eliminate orphan notes without note tree (which are reported separately)
|
||||
await runCheck(`
|
||||
SELECT
|
||||
DISTINCT note_id
|
||||
DISTINCT noteId
|
||||
FROM
|
||||
notes
|
||||
JOIN notes_tree USING(note_id)
|
||||
JOIN notes_tree USING(noteId)
|
||||
WHERE
|
||||
(SELECT COUNT(*) FROM notes_tree WHERE notes.note_id = notes_tree.note_id AND notes_tree.is_deleted = 0) = 0
|
||||
AND notes.is_deleted = 0
|
||||
(SELECT COUNT(*) FROM notes_tree WHERE notes.noteId = notes_tree.noteId AND notes_tree.isDeleted = 0) = 0
|
||||
AND notes.isDeleted = 0
|
||||
`, 'No undeleted note trees for note IDs', errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
child.parent_note_id || ' > ' || child.note_id
|
||||
child.parentNoteId || ' > ' || child.noteId
|
||||
FROM notes_tree
|
||||
AS child
|
||||
LEFT JOIN notes_tree AS parent ON parent.note_id = child.parent_note_id
|
||||
LEFT JOIN notes_tree AS parent ON parent.noteId = child.parentNoteId
|
||||
WHERE
|
||||
parent.note_id IS NULL
|
||||
AND child.parent_note_id != 'root'`,
|
||||
parent.noteId IS NULL
|
||||
AND child.parentNoteId != 'root'`,
|
||||
"Not existing parent in the following parent > child relations", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_history_id || ' > ' || notes_history.note_id
|
||||
noteHistoryId || ' > ' || notes_history.noteId
|
||||
FROM
|
||||
notes_history LEFT JOIN notes USING(note_id)
|
||||
notes_history LEFT JOIN notes USING(noteId)
|
||||
WHERE
|
||||
notes.note_id IS NULL`,
|
||||
notes.noteId IS NULL`,
|
||||
"Missing notes records for following note history ID > note ID", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
notes_tree.parent_note_id || ' > ' || notes_tree.note_id
|
||||
notes_tree.parentNoteId || ' > ' || notes_tree.noteId
|
||||
FROM
|
||||
notes_tree
|
||||
WHERE
|
||||
notes_tree.is_deleted = 0
|
||||
notes_tree.isDeleted = 0
|
||||
GROUP BY
|
||||
notes_tree.parent_note_id,
|
||||
notes_tree.note_id
|
||||
notes_tree.parentNoteId,
|
||||
notes_tree.noteId
|
||||
HAVING
|
||||
COUNT(*) > 1`,
|
||||
"Duplicate undeleted parent note <-> note relationship - parent note ID > note ID", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
images.image_id
|
||||
images.imageId
|
||||
FROM
|
||||
images
|
||||
LEFT JOIN notes_image ON notes_image.image_id = images.image_id
|
||||
LEFT JOIN notes_image ON notes_image.imageId = images.imageId
|
||||
WHERE
|
||||
notes_image.note_image_id IS NULL`,
|
||||
notes_image.noteImageId IS NULL`,
|
||||
"Image with no note relation", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
notes_image.note_image_id
|
||||
notes_image.noteImageId
|
||||
FROM
|
||||
notes_image
|
||||
JOIN images USING(image_id)
|
||||
JOIN images USING(imageId)
|
||||
WHERE
|
||||
notes_image.is_deleted = 0
|
||||
AND images.is_deleted = 1`,
|
||||
"Note image is not deleted while image is deleted for note_image_id", errorList);
|
||||
notes_image.isDeleted = 0
|
||||
AND images.isDeleted = 1`,
|
||||
"Note image is not deleted while image is deleted for noteImageId", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_id
|
||||
noteId
|
||||
FROM
|
||||
notes
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
AND (note_title IS NULL OR note_text IS NULL)`,
|
||||
isDeleted = 0
|
||||
AND (title IS NULL OR content IS NULL)`,
|
||||
"Note has null title or text", errorList);
|
||||
|
||||
await runCheck(`
|
||||
SELECT
|
||||
note_id
|
||||
noteId
|
||||
FROM
|
||||
notes
|
||||
WHERE
|
||||
type != 'text' AND type != 'code' AND type != 'render'`,
|
||||
"Note has invalid type", errorList);
|
||||
|
||||
await runSyncRowChecks("notes", "note_id", errorList);
|
||||
await runSyncRowChecks("notes_history", "note_history_id", errorList);
|
||||
await runSyncRowChecks("notes_tree", "note_tree_id", errorList);
|
||||
await runSyncRowChecks("recent_notes", "note_tree_id", errorList);
|
||||
await runSyncRowChecks("images", "image_id", errorList);
|
||||
await runSyncRowChecks("notes_image", "note_image_id", errorList);
|
||||
await runSyncRowChecks("notes", "noteId", errorList);
|
||||
await runSyncRowChecks("notes_history", "noteHistoryId", errorList);
|
||||
await runSyncRowChecks("notes_tree", "noteTreeId", errorList);
|
||||
await runSyncRowChecks("recent_notes", "noteTreeId", errorList);
|
||||
await runSyncRowChecks("images", "imageId", errorList);
|
||||
await runSyncRowChecks("notes_image", "noteImageId", errorList);
|
||||
|
||||
if (errorList.length === 0) {
|
||||
// we run this only if basic checks passed since this assumes basic data consistency
|
||||
|
@ -19,80 +19,80 @@ async function getHashes() {
|
||||
const hashes = {
|
||||
notes: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
note_id,
|
||||
note_title,
|
||||
note_text,
|
||||
noteId,
|
||||
title,
|
||||
content,
|
||||
type,
|
||||
date_modified,
|
||||
is_protected,
|
||||
is_deleted
|
||||
dateModified,
|
||||
isProtected,
|
||||
isDeleted
|
||||
FROM notes
|
||||
ORDER BY note_id`)),
|
||||
ORDER BY noteId`)),
|
||||
|
||||
notes_tree: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
note_tree_id,
|
||||
note_id,
|
||||
parent_note_id,
|
||||
note_position,
|
||||
date_modified,
|
||||
is_deleted,
|
||||
noteTreeId,
|
||||
noteId,
|
||||
parentNoteId,
|
||||
notePosition,
|
||||
dateModified,
|
||||
isDeleted,
|
||||
prefix
|
||||
FROM notes_tree
|
||||
ORDER BY note_tree_id`)),
|
||||
ORDER BY noteTreeId`)),
|
||||
|
||||
notes_history: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
note_history_id,
|
||||
note_id,
|
||||
note_title,
|
||||
note_text,
|
||||
date_modified_from,
|
||||
date_modified_to
|
||||
noteHistoryId,
|
||||
noteId,
|
||||
title,
|
||||
content,
|
||||
dateModifiedFrom,
|
||||
dateModifiedTo
|
||||
FROM notes_history
|
||||
ORDER BY note_history_id`)),
|
||||
ORDER BY noteHistoryId`)),
|
||||
|
||||
recent_notes: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
note_tree_id,
|
||||
note_path,
|
||||
date_accessed,
|
||||
is_deleted
|
||||
noteTreeId,
|
||||
notePath,
|
||||
dateAccessed,
|
||||
isDeleted
|
||||
FROM recent_notes
|
||||
ORDER BY note_path`)),
|
||||
ORDER BY notePath`)),
|
||||
|
||||
options: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
opt_name,
|
||||
opt_value
|
||||
name,
|
||||
value
|
||||
FROM options
|
||||
WHERE is_synced = 1
|
||||
ORDER BY opt_name`)),
|
||||
WHERE isSynced = 1
|
||||
ORDER BY name`)),
|
||||
|
||||
// we don't include image data on purpose because they are quite large, checksum is good enough
|
||||
// to represent the data anyway
|
||||
images: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
image_id,
|
||||
imageId,
|
||||
format,
|
||||
checksum,
|
||||
name,
|
||||
is_deleted,
|
||||
date_modified,
|
||||
date_created
|
||||
isDeleted,
|
||||
dateModified,
|
||||
dateCreated
|
||||
FROM images
|
||||
ORDER BY image_id`)),
|
||||
ORDER BY imageId`)),
|
||||
|
||||
attributes: getHash(await sql.getAll(`
|
||||
SELECT
|
||||
attribute_id,
|
||||
note_id
|
||||
attributeId,
|
||||
noteId
|
||||
name,
|
||||
value
|
||||
date_modified,
|
||||
date_created
|
||||
dateModified,
|
||||
dateCreated
|
||||
FROM attributes
|
||||
ORDER BY attribute_id`))
|
||||
ORDER BY attributeId`))
|
||||
};
|
||||
|
||||
const elapseTimeMs = new Date().getTime() - startTime.getTime();
|
||||
|
@ -11,29 +11,29 @@ const DATE_ATTRIBUTE = 'date_note';
|
||||
|
||||
async function createNote(parentNoteId, noteTitle, noteText) {
|
||||
return (await notes.createNewNote(parentNoteId, {
|
||||
note_title: noteTitle,
|
||||
note_text: noteText,
|
||||
title: noteTitle,
|
||||
content: noteText,
|
||||
target: 'into',
|
||||
is_protected: false
|
||||
isProtected: false
|
||||
})).noteId;
|
||||
}
|
||||
|
||||
async function getNoteStartingWith(parentNoteId, startsWith) {
|
||||
return await sql.getFirstValue(`SELECT note_id FROM notes JOIN notes_tree USING(note_id)
|
||||
WHERE parent_note_id = ? AND note_title LIKE '${startsWith}%'
|
||||
AND notes.is_deleted = 0 AND is_protected = 0
|
||||
AND notes_tree.is_deleted = 0`, [parentNoteId]);
|
||||
return await sql.getFirstValue(`SELECT noteId FROM notes JOIN notes_tree USING(noteId)
|
||||
WHERE parentNoteId = ? AND title LIKE '${startsWith}%'
|
||||
AND notes.isDeleted = 0 AND isProtected = 0
|
||||
AND notes_tree.isDeleted = 0`, [parentNoteId]);
|
||||
}
|
||||
|
||||
async function getRootNoteId() {
|
||||
let rootNoteId = await sql.getFirstValue(`SELECT notes.note_id FROM notes JOIN attributes USING(note_id)
|
||||
WHERE attributes.name = '${CALENDAR_ROOT_ATTRIBUTE}' AND notes.is_deleted = 0`);
|
||||
let rootNoteId = await sql.getFirstValue(`SELECT notes.noteId FROM notes JOIN attributes USING(noteId)
|
||||
WHERE attributes.name = '${CALENDAR_ROOT_ATTRIBUTE}' AND notes.isDeleted = 0`);
|
||||
|
||||
if (!rootNoteId) {
|
||||
rootNoteId = (await notes.createNewNote('root', {
|
||||
note_title: 'Calendar',
|
||||
title: 'Calendar',
|
||||
target: 'into',
|
||||
is_protected: false
|
||||
isProtected: false
|
||||
})).noteId;
|
||||
|
||||
await attributes.createAttribute(rootNoteId, CALENDAR_ROOT_ATTRIBUTE);
|
||||
|
@ -8,9 +8,9 @@ async function addEvent(comment) {
|
||||
|
||||
async function addNoteEvent(noteId, comment) {
|
||||
await sql.insert('event_log', {
|
||||
note_id : noteId,
|
||||
noteId : noteId,
|
||||
comment: comment,
|
||||
date_added: utils.nowDate()
|
||||
dateAdded: utils.nowDate()
|
||||
});
|
||||
|
||||
log.info("Event log for " + noteId + ": " + comment);
|
||||
|
@ -6,7 +6,7 @@ const attributes = require('./attributes');
|
||||
const protected_session = require('./protected_session');
|
||||
|
||||
async function getNoteById(noteId, dataKey) {
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
protected_session.decryptNote(dataKey, note);
|
||||
|
||||
@ -15,17 +15,17 @@ async function getNoteById(noteId, dataKey) {
|
||||
|
||||
async function getJsonNoteById(noteId, dataKey) {
|
||||
const note = await getNoteById(noteId, dataKey);
|
||||
note.data = JSON.parse(note.note_text);
|
||||
note.data = JSON.parse(note.content);
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
async function updateJsonNote(noteId, data) {
|
||||
const ret = await createNewNote(noteId, {
|
||||
note_title: name,
|
||||
note_text: JSON.stringify(data),
|
||||
title: name,
|
||||
content: JSON.stringify(data),
|
||||
target: 'into',
|
||||
is_protected: false,
|
||||
isProtected: false,
|
||||
type: 'code',
|
||||
mime: 'application/json'
|
||||
});
|
||||
@ -35,10 +35,10 @@ async function updateJsonNote(noteId, data) {
|
||||
|
||||
async function createNewJsonNote(parentNoteId, name, payload) {
|
||||
const ret = await createNewNote(parentNoteId, {
|
||||
note_title: name,
|
||||
note_text: JSON.stringify(payload),
|
||||
title: name,
|
||||
content: JSON.stringify(payload),
|
||||
target: 'into',
|
||||
is_protected: false,
|
||||
isProtected: false,
|
||||
type: 'code',
|
||||
mime: 'application/json'
|
||||
});
|
||||
@ -53,18 +53,18 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
|
||||
let newNotePos = 0;
|
||||
|
||||
if (noteOpts.target === 'into') {
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
|
||||
const maxNotePos = await sql.getFirstValue('SELECT MAX(notePosition) FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0', [parentNoteId]);
|
||||
|
||||
newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
|
||||
}
|
||||
else if (noteOpts.target === 'after') {
|
||||
const afterNote = await sql.getFirst('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [noteOpts.target_note_tree_id]);
|
||||
const afterNote = await sql.getFirst('SELECT notePosition FROM notes_tree WHERE noteTreeId = ?', [noteOpts.target_noteTreeId]);
|
||||
|
||||
newNotePos = afterNote.note_position + 1;
|
||||
newNotePos = afterNote.notePosition + 1;
|
||||
|
||||
// not updating date_modified to avoig having to sync whole rows
|
||||
await sql.execute('UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0',
|
||||
[parentNoteId, afterNote.note_position]);
|
||||
// not updating dateModified to avoig having to sync whole rows
|
||||
await sql.execute('UPDATE notes_tree SET notePosition = notePosition + 1 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0',
|
||||
[parentNoteId, afterNote.notePosition]);
|
||||
|
||||
await sync_table.addNoteReorderingSync(parentNoteId, sourceId);
|
||||
}
|
||||
@ -73,7 +73,7 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
|
||||
}
|
||||
|
||||
if (parentNoteId !== 'root') {
|
||||
const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]);
|
||||
const parent = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [parentNoteId]);
|
||||
|
||||
if (!noteOpts.type) {
|
||||
noteOpts.type = parent.type;
|
||||
@ -87,17 +87,17 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
|
||||
const now = utils.nowDate();
|
||||
|
||||
const note = {
|
||||
note_id: noteId,
|
||||
note_title: noteOpts.note_title,
|
||||
note_text: noteOpts.note_text ? noteOpts.note_text : '',
|
||||
is_protected: noteOpts.is_protected,
|
||||
noteId: noteId,
|
||||
title: noteOpts.title,
|
||||
content: noteOpts.content ? noteOpts.content : '',
|
||||
isProtected: noteOpts.isProtected,
|
||||
type: noteOpts.type ? noteOpts.type : 'text',
|
||||
mime: noteOpts.mime ? noteOpts.mime : 'text/html',
|
||||
date_created: now,
|
||||
date_modified: now
|
||||
dateCreated: now,
|
||||
dateModified: now
|
||||
};
|
||||
|
||||
if (note.is_protected) {
|
||||
if (note.isProtected) {
|
||||
protected_session.encryptNote(dataKey, note);
|
||||
}
|
||||
|
||||
@ -106,13 +106,13 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
|
||||
await sync_table.addNoteSync(noteId, sourceId);
|
||||
|
||||
await sql.insert("notes_tree", {
|
||||
note_tree_id: noteTreeId,
|
||||
note_id: noteId,
|
||||
parent_note_id: parentNoteId,
|
||||
note_position: newNotePos,
|
||||
is_expanded: 0,
|
||||
date_modified: now,
|
||||
is_deleted: 0
|
||||
noteTreeId: noteTreeId,
|
||||
noteId: noteId,
|
||||
parentNoteId: parentNoteId,
|
||||
notePosition: newNotePos,
|
||||
isExpanded: 0,
|
||||
dateModified: now,
|
||||
isDeleted: 0
|
||||
});
|
||||
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
@ -125,11 +125,11 @@ async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
|
||||
}
|
||||
|
||||
async function protectNoteRecursively(noteId, dataKey, protect, sourceId) {
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
|
||||
const note = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
await protectNote(note, dataKey, protect, sourceId);
|
||||
|
||||
const children = await sql.getFirstColumn("SELECT note_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteId]);
|
||||
const children = await sql.getFirstColumn("SELECT noteId FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
|
||||
|
||||
for (const childNoteId of children) {
|
||||
await protectNoteRecursively(childNoteId, dataKey, protect, sourceId);
|
||||
@ -139,80 +139,80 @@ async function protectNoteRecursively(noteId, dataKey, protect, sourceId) {
|
||||
async function protectNote(note, dataKey, protect, sourceId) {
|
||||
let changed = false;
|
||||
|
||||
if (protect && !note.is_protected) {
|
||||
if (protect && !note.isProtected) {
|
||||
protected_session.encryptNote(dataKey, note);
|
||||
|
||||
note.is_protected = true;
|
||||
note.isProtected = true;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
else if (!protect && note.is_protected) {
|
||||
else if (!protect && note.isProtected) {
|
||||
protected_session.decryptNote(dataKey, note);
|
||||
|
||||
note.is_protected = false;
|
||||
note.isProtected = false;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
await sql.execute("UPDATE notes SET note_title = ?, note_text = ?, is_protected = ? WHERE note_id = ?",
|
||||
[note.note_title, note.note_text, note.is_protected, note.note_id]);
|
||||
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ? WHERE noteId = ?",
|
||||
[note.title, note.content, note.isProtected, note.noteId]);
|
||||
|
||||
await sync_table.addNoteSync(note.note_id, sourceId);
|
||||
await sync_table.addNoteSync(note.noteId, sourceId);
|
||||
}
|
||||
|
||||
await protectNoteHistory(note.note_id, dataKey, protect, sourceId);
|
||||
await protectNoteHistory(note.noteId, dataKey, protect, sourceId);
|
||||
}
|
||||
|
||||
async function protectNoteHistory(noteId, dataKey, protect, sourceId) {
|
||||
const historyToChange = await sql.getAll("SELECT * FROM notes_history WHERE note_id = ? AND is_protected != ?", [noteId, protect]);
|
||||
const historyToChange = await sql.getAll("SELECT * FROM notes_history WHERE noteId = ? AND isProtected != ?", [noteId, protect]);
|
||||
|
||||
for (const history of historyToChange) {
|
||||
if (protect) {
|
||||
protected_session.encryptNoteHistoryRow(dataKey, history);
|
||||
|
||||
history.is_protected = true;
|
||||
history.isProtected = true;
|
||||
}
|
||||
else {
|
||||
protected_session.decryptNoteHistoryRow(dataKey, history);
|
||||
|
||||
history.is_protected = false;
|
||||
history.isProtected = false;
|
||||
}
|
||||
|
||||
await sql.execute("UPDATE notes_history SET note_title = ?, note_text = ?, is_protected = ? WHERE note_history_id = ?",
|
||||
[history.note_title, history.note_text, history.is_protected, history.note_history_id]);
|
||||
await sql.execute("UPDATE notes_history SET title = ?, content = ?, isProtected = ? WHERE noteHistoryId = ?",
|
||||
[history.title, history.content, history.isProtected, history.noteHistoryId]);
|
||||
|
||||
await sync_table.addNoteHistorySync(history.note_history_id, sourceId);
|
||||
await sync_table.addNoteHistorySync(history.noteHistoryId, sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveNoteHistory(noteId, dataKey, sourceId, nowStr) {
|
||||
const oldNote = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [noteId]);
|
||||
const oldNote = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
if (oldNote.is_protected) {
|
||||
if (oldNote.isProtected) {
|
||||
protected_session.decryptNote(dataKey, oldNote);
|
||||
|
||||
note.is_protected = false;
|
||||
note.isProtected = false;
|
||||
}
|
||||
|
||||
const newNoteHistoryId = utils.newNoteHistoryId();
|
||||
|
||||
await sql.insert('notes_history', {
|
||||
note_history_id: newNoteHistoryId,
|
||||
note_id: noteId,
|
||||
noteHistoryId: newNoteHistoryId,
|
||||
noteId: noteId,
|
||||
// title and text should be decrypted now
|
||||
note_title: oldNote.note_title,
|
||||
note_text: oldNote.note_text,
|
||||
is_protected: 0, // will be fixed in the protectNoteHistory() call
|
||||
date_modified_from: oldNote.date_modified,
|
||||
date_modified_to: nowStr
|
||||
title: oldNote.title,
|
||||
content: oldNote.content,
|
||||
isProtected: 0, // will be fixed in the protectNoteHistory() call
|
||||
dateModifiedFrom: oldNote.dateModified,
|
||||
dateModifiedTo: nowStr
|
||||
});
|
||||
|
||||
await sync_table.addNoteHistorySync(newNoteHistoryId, sourceId);
|
||||
}
|
||||
|
||||
async function saveNoteImages(noteId, noteText, sourceId) {
|
||||
const existingNoteImages = await sql.getAll("SELECT * FROM notes_image WHERE note_id = ?", [noteId]);
|
||||
const existingNoteImages = await sql.getAll("SELECT * FROM notes_image WHERE noteId = ?", [noteId]);
|
||||
const foundImageIds = [];
|
||||
const now = utils.nowDate();
|
||||
const re = /src="\/api\/images\/([a-zA-Z0-9]+)\//g;
|
||||
@ -220,27 +220,27 @@ async function saveNoteImages(noteId, noteText, sourceId) {
|
||||
|
||||
while (match = re.exec(noteText)) {
|
||||
const imageId = match[1];
|
||||
const existingNoteImage = existingNoteImages.find(ni => ni.image_id === imageId);
|
||||
const existingNoteImage = existingNoteImages.find(ni => ni.imageId === imageId);
|
||||
|
||||
if (!existingNoteImage) {
|
||||
const noteImageId = utils.newNoteImageId();
|
||||
|
||||
await sql.insert("notes_image", {
|
||||
note_image_id: noteImageId,
|
||||
note_id: noteId,
|
||||
image_id: imageId,
|
||||
is_deleted: 0,
|
||||
date_modified: now,
|
||||
date_created: now
|
||||
noteImageId: noteImageId,
|
||||
noteId: noteId,
|
||||
imageId: imageId,
|
||||
isDeleted: 0,
|
||||
dateModified: now,
|
||||
dateCreated: now
|
||||
});
|
||||
|
||||
await sync_table.addNoteImageSync(noteImageId, sourceId);
|
||||
}
|
||||
else if (existingNoteImage.is_deleted) {
|
||||
await sql.execute("UPDATE notes_image SET is_deleted = 0, date_modified = ? WHERE note_image_id = ?",
|
||||
[now, existingNoteImage.note_image_id]);
|
||||
else if (existingNoteImage.isDeleted) {
|
||||
await sql.execute("UPDATE notes_image SET isDeleted = 0, dateModified = ? WHERE noteImageId = ?",
|
||||
[now, existingNoteImage.noteImageId]);
|
||||
|
||||
await sync_table.addNoteImageSync(existingNoteImage.note_image_id, sourceId);
|
||||
await sync_table.addNoteImageSync(existingNoteImage.noteImageId, sourceId);
|
||||
}
|
||||
// else we don't need to do anything
|
||||
|
||||
@ -248,18 +248,18 @@ async function saveNoteImages(noteId, noteText, sourceId) {
|
||||
}
|
||||
|
||||
// marking note images as deleted if they are not present on the page anymore
|
||||
const unusedNoteImages = existingNoteImages.filter(ni => !foundImageIds.includes(ni.image_id));
|
||||
const unusedNoteImages = existingNoteImages.filter(ni => !foundImageIds.includes(ni.imageId));
|
||||
|
||||
for (const unusedNoteImage of unusedNoteImages) {
|
||||
await sql.execute("UPDATE notes_image SET is_deleted = 1, date_modified = ? WHERE note_image_id = ?",
|
||||
[now, unusedNoteImage.note_image_id]);
|
||||
await sql.execute("UPDATE notes_image SET isDeleted = 1, dateModified = ? WHERE noteImageId = ?",
|
||||
[now, unusedNoteImage.noteImageId]);
|
||||
|
||||
await sync_table.addNoteImageSync(unusedNoteImage.note_image_id, sourceId);
|
||||
await sync_table.addNoteImageSync(unusedNoteImage.noteImageId, sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateNote(noteId, newNote, dataKey, sourceId) {
|
||||
if (newNote.detail.is_protected) {
|
||||
if (newNote.detail.isProtected) {
|
||||
await protected_session.encryptNote(dataKey, newNote.detail);
|
||||
}
|
||||
|
||||
@ -273,10 +273,10 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
|
||||
const historyCutoff = utils.dateStr(new Date(now.getTime() - historySnapshotTimeInterval * 1000));
|
||||
|
||||
const existingNoteHistoryId = await sql.getFirstValue(
|
||||
"SELECT note_history_id FROM notes_history WHERE note_id = ? AND date_modified_to >= ?", [noteId, historyCutoff]);
|
||||
"SELECT noteHistoryId FROM notes_history WHERE noteId = ? AND dateModifiedTo >= ?", [noteId, historyCutoff]);
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
const msSinceDateCreated = now.getTime() - utils.parseDate(newNote.detail.date_created).getTime();
|
||||
const msSinceDateCreated = now.getTime() - utils.parseDate(newNote.detail.dateCreated).getTime();
|
||||
|
||||
if (attributesMap.disable_versioning !== 'true'
|
||||
&& !existingNoteHistoryId
|
||||
@ -285,14 +285,14 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
|
||||
await saveNoteHistory(noteId, dataKey, sourceId, nowStr);
|
||||
}
|
||||
|
||||
await saveNoteImages(noteId, newNote.detail.note_text, sourceId);
|
||||
await saveNoteImages(noteId, newNote.detail.content, sourceId);
|
||||
|
||||
await protectNoteHistory(noteId, dataKey, newNote.detail.is_protected);
|
||||
await protectNoteHistory(noteId, dataKey, newNote.detail.isProtected);
|
||||
|
||||
await sql.execute("UPDATE notes SET note_title = ?, note_text = ?, is_protected = ?, date_modified = ? WHERE note_id = ?", [
|
||||
newNote.detail.note_title,
|
||||
newNote.detail.note_text,
|
||||
newNote.detail.is_protected,
|
||||
await sql.execute("UPDATE notes SET title = ?, content = ?, isProtected = ?, dateModified = ? WHERE noteId = ?", [
|
||||
newNote.detail.title,
|
||||
newNote.detail.content,
|
||||
newNote.detail.isProtected,
|
||||
nowStr,
|
||||
noteId]);
|
||||
|
||||
@ -301,29 +301,29 @@ async function updateNote(noteId, newNote, dataKey, sourceId) {
|
||||
}
|
||||
|
||||
async function deleteNote(noteTreeId, sourceId) {
|
||||
const noteTree = await sql.getFirstOrNull("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
|
||||
const noteTree = await sql.getFirstOrNull("SELECT * FROM notes_tree WHERE noteTreeId = ?", [noteTreeId]);
|
||||
|
||||
if (!noteTree || noteTree.is_deleted === 1) {
|
||||
if (!noteTree || noteTree.isDeleted === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = utils.nowDate();
|
||||
|
||||
await sql.execute("UPDATE notes_tree SET is_deleted = 1, date_modified = ? WHERE note_tree_id = ?", [now, noteTreeId]);
|
||||
await sql.execute("UPDATE notes_tree SET isDeleted = 1, dateModified = ? WHERE noteTreeId = ?", [now, noteTreeId]);
|
||||
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
|
||||
|
||||
const noteId = await sql.getFirstValue("SELECT note_id FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
|
||||
const noteId = await sql.getFirstValue("SELECT noteId FROM notes_tree WHERE noteTreeId = ?", [noteTreeId]);
|
||||
|
||||
const notDeletedNoteTreesCount = await sql.getFirstValue("SELECT COUNT(*) FROM notes_tree WHERE note_id = ? AND is_deleted = 0", [noteId]);
|
||||
const notDeletedNoteTreesCount = await sql.getFirstValue("SELECT COUNT(*) FROM notes_tree WHERE noteId = ? AND isDeleted = 0", [noteId]);
|
||||
|
||||
if (!notDeletedNoteTreesCount) {
|
||||
await sql.execute("UPDATE notes SET is_deleted = 1, date_modified = ? WHERE note_id = ?", [now, noteId]);
|
||||
await sql.execute("UPDATE notes SET isDeleted = 1, dateModified = ? WHERE noteId = ?", [now, noteId]);
|
||||
await sync_table.addNoteSync(noteId, sourceId);
|
||||
|
||||
const children = await sql.getAll("SELECT note_tree_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [noteId]);
|
||||
const children = await sql.getAll("SELECT noteTreeId FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [noteId]);
|
||||
|
||||
for (const child of children) {
|
||||
await deleteNote(child.note_tree_id, sourceId);
|
||||
await deleteNote(child.noteTreeId, sourceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,45 +3,45 @@ const utils = require('./utils');
|
||||
const sync_table = require('./sync_table');
|
||||
const app_info = require('./app_info');
|
||||
|
||||
async function getOptionOrNull(optName) {
|
||||
return await sql.getFirstOrNull("SELECT opt_value FROM options WHERE opt_name = ?", [optName]);
|
||||
async function getOptionOrNull(name) {
|
||||
return await sql.getFirstOrNull("SELECT value FROM options WHERE name = ?", [name]);
|
||||
}
|
||||
|
||||
async function getOption(optName) {
|
||||
const row = await getOptionOrNull(optName);
|
||||
async function getOption(name) {
|
||||
const row = await getOptionOrNull(name);
|
||||
|
||||
if (!row) {
|
||||
throw new Error("Option " + optName + " doesn't exist");
|
||||
throw new Error("Option " + name + " doesn't exist");
|
||||
}
|
||||
|
||||
return row['opt_value'];
|
||||
return row['value'];
|
||||
}
|
||||
|
||||
async function setOption(optName, optValue, sourceId = null) {
|
||||
const opt = await sql.getFirst("SELECT * FROM options WHERE opt_name = ?", [optName]);
|
||||
async function setOption(name, value, sourceId = null) {
|
||||
const opt = await sql.getFirst("SELECT * FROM options WHERE name = ?", [name]);
|
||||
|
||||
if (!opt) {
|
||||
throw new Error(`Option ${optName} doesn't exist`);
|
||||
throw new Error(`Option ${name} doesn't exist`);
|
||||
}
|
||||
|
||||
if (opt.is_synced) {
|
||||
await sync_table.addOptionsSync(optName, sourceId);
|
||||
if (opt.isSynced) {
|
||||
await sync_table.addOptionsSync(name, sourceId);
|
||||
}
|
||||
|
||||
await sql.execute("UPDATE options SET opt_value = ?, date_modified = ? WHERE opt_name = ?",
|
||||
[optValue, utils.nowDate(), optName]);
|
||||
await sql.execute("UPDATE options SET value = ?, dateModified = ? WHERE name = ?",
|
||||
[value, utils.nowDate(), name]);
|
||||
}
|
||||
|
||||
async function createOption(optName, optValue, isSynced, sourceId = null) {
|
||||
async function createOption(name, value, isSynced, sourceId = null) {
|
||||
await sql.insert("options", {
|
||||
opt_name: optName,
|
||||
opt_value: optValue,
|
||||
is_synced: isSynced,
|
||||
date_modified: utils.nowDate()
|
||||
name: name,
|
||||
value: value,
|
||||
isSynced: isSynced,
|
||||
dateModified: utils.nowDate()
|
||||
});
|
||||
|
||||
if (isSynced) {
|
||||
await sync_table.addOptionsSync(optName, sourceId);
|
||||
await sync_table.addOptionsSync(name, sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ async function initOptions(startNotePath) {
|
||||
await createOption('encrypted_data_key', '', true);
|
||||
await createOption('encrypted_data_key_iv', '', true);
|
||||
|
||||
await createOption('start_note_path', startNotePath, false);
|
||||
await createOption('start_notePath', startNotePath, false);
|
||||
await createOption('protected_session_timeout', 600, true);
|
||||
await createOption('history_snapshot_time_interval', 600, true);
|
||||
await createOption('last_backup_date', utils.nowDate(), false);
|
||||
|
@ -43,16 +43,16 @@ function isProtectedSessionAvailable(req) {
|
||||
function decryptNote(dataKey, note) {
|
||||
dataKey = getDataKey(dataKey);
|
||||
|
||||
if (!note.is_protected) {
|
||||
if (!note.isProtected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (note.note_title) {
|
||||
note.note_title = data_encryption.decryptString(dataKey, data_encryption.noteTitleIv(note.note_id), note.note_title);
|
||||
if (note.title) {
|
||||
note.title = data_encryption.decryptString(dataKey, data_encryption.noteTitleIv(note.noteId), note.title);
|
||||
}
|
||||
|
||||
if (note.note_text) {
|
||||
note.note_text = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(note.note_id), note.note_text);
|
||||
if (note.content) {
|
||||
note.content = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(note.noteId), note.content);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,16 +67,16 @@ function decryptNotes(dataKey, notes) {
|
||||
function decryptNoteHistoryRow(dataKey, hist) {
|
||||
dataKey = getDataKey(dataKey);
|
||||
|
||||
if (!hist.is_protected) {
|
||||
if (!hist.isProtected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hist.note_title) {
|
||||
hist.note_title = data_encryption.decryptString(dataKey, data_encryption.noteTitleIv(hist.note_history_id), hist.note_title);
|
||||
if (hist.title) {
|
||||
hist.title = data_encryption.decryptString(dataKey, data_encryption.noteTitleIv(hist.noteHistoryId), hist.title);
|
||||
}
|
||||
|
||||
if (hist.note_text) {
|
||||
hist.note_text = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(hist.note_history_id), hist.note_text);
|
||||
if (hist.content) {
|
||||
hist.content = data_encryption.decryptString(dataKey, data_encryption.noteTextIv(hist.noteHistoryId), hist.content);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,15 +91,15 @@ function decryptNoteHistoryRows(dataKey, historyRows) {
|
||||
function encryptNote(dataKey, note) {
|
||||
dataKey = getDataKey(dataKey);
|
||||
|
||||
note.note_title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(note.note_id), note.note_title);
|
||||
note.note_text = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(note.note_id), note.note_text);
|
||||
note.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(note.noteId), note.title);
|
||||
note.content = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(note.noteId), note.content);
|
||||
}
|
||||
|
||||
function encryptNoteHistoryRow(dataKey, history) {
|
||||
dataKey = getDataKey(dataKey);
|
||||
|
||||
history.note_title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.note_history_id), history.note_title);
|
||||
history.note_text = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(history.note_history_id), history.note_text);
|
||||
history.title = data_encryption.encrypt(dataKey, data_encryption.noteTitleIv(history.noteHistoryId), history.title);
|
||||
history.content = data_encryption.encrypt(dataKey, data_encryption.noteTextIv(history.noteHistoryId), history.content);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -12,7 +12,7 @@ function ScriptContext(noteId, dataKey) {
|
||||
|
||||
function deserializePayload(note) {
|
||||
if (note && note.type === "code" && note.mime === "application/json") {
|
||||
note.payload = JSON.parse(note.note_text);
|
||||
note.payload = JSON.parse(note.content);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,10 +46,10 @@ function ScriptContext(noteId, dataKey) {
|
||||
|
||||
this.createNote = async function (parentNoteId, name, payload, extraOptions = {}) {
|
||||
const note = {
|
||||
note_title: name,
|
||||
note_text: extraOptions.json ? serializePayload(payload) : payload,
|
||||
title: name,
|
||||
content: extraOptions.json ? serializePayload(payload) : payload,
|
||||
target: 'into',
|
||||
is_protected: extraOptions.isProtected !== undefined ? extraOptions.isProtected : false,
|
||||
isProtected: extraOptions.isProtected !== undefined ? extraOptions.isProtected : false,
|
||||
type: extraOptions.type,
|
||||
mime: extraOptions.mime
|
||||
};
|
||||
@ -77,20 +77,20 @@ function ScriptContext(noteId, dataKey) {
|
||||
|
||||
this.updateNote = async function (note) {
|
||||
if (note.type === 'code' && note.mime === 'application/json') {
|
||||
note.note_text = serializePayload(note.payload);
|
||||
note.content = serializePayload(note.payload);
|
||||
}
|
||||
|
||||
log.info("new note text: ", note.note_text);
|
||||
log.info("new note text: ", note.content);
|
||||
|
||||
delete note.payload;
|
||||
|
||||
if (note.is_protected) {
|
||||
if (note.isProtected) {
|
||||
protected_session.encryptNote(this.dataKey, note);
|
||||
}
|
||||
|
||||
await sql.replace("notes", note);
|
||||
|
||||
await sync_table.addNoteSync(note.note_id);
|
||||
await sync_table.addNoteSync(note.noteId);
|
||||
};
|
||||
|
||||
this.log = function(message) {
|
||||
|
@ -4,9 +4,9 @@ const sql = require('./sql');
|
||||
|
||||
async function saveSourceId(sourceId) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.insert("source_ids", {
|
||||
source_id: sourceId,
|
||||
date_created: utils.nowDate()
|
||||
await sql.insert("sourceIds", {
|
||||
sourceId: sourceId,
|
||||
dateCreated: utils.nowDate()
|
||||
});
|
||||
});
|
||||
|
||||
@ -29,7 +29,7 @@ async function generateSourceId() {
|
||||
}
|
||||
|
||||
async function refreshSourceIds() {
|
||||
allSourceIds = await sql.getFirstColumn("SELECT source_id FROM source_ids ORDER BY date_created DESC");
|
||||
allSourceIds = await sql.getFirstColumn("SELECT sourceId FROM source_ids ORDER BY dateCreated DESC");
|
||||
}
|
||||
|
||||
let allSourceIds = [];
|
||||
|
@ -41,7 +41,7 @@ const dbReady = new Promise((resolve, reject) => {
|
||||
await executeScript(imagesSql);
|
||||
await executeScript(notesImageSql);
|
||||
|
||||
const startNoteId = await getFirstValue("SELECT note_id FROM notes_tree WHERE parent_note_id = 'root' AND is_deleted = 0 ORDER BY note_position");
|
||||
const startNoteId = await getFirstValue("SELECT noteId FROM notes_tree WHERE parentNoteId = 'root' AND isDeleted = 0 ORDER BY notePosition");
|
||||
|
||||
await require('./options').initOptions(startNoteId);
|
||||
await require('./sync_table').fillAllSyncRows();
|
||||
@ -226,7 +226,7 @@ async function doInTransaction(func) {
|
||||
}
|
||||
|
||||
async function isDbUpToDate() {
|
||||
const dbVersion = parseInt(await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'db_version'"));
|
||||
const dbVersion = parseInt(await getFirstValue("SELECT value FROM options WHERE name = 'db_version'"));
|
||||
|
||||
const upToDate = dbVersion >= app_info.db_version;
|
||||
|
||||
@ -238,7 +238,7 @@ async function isDbUpToDate() {
|
||||
}
|
||||
|
||||
async function isUserInitialized() {
|
||||
const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
||||
const username = await getFirstValue("SELECT value FROM options WHERE name = 'username'");
|
||||
|
||||
return !!username;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const rp = require('request-promise');
|
||||
const sql = require('./sql');
|
||||
const options = require('./options');
|
||||
const utils = require('./utils');
|
||||
const source_id = require('./source_id');
|
||||
const sourceId = require('./sourceId');
|
||||
const notes = require('./notes');
|
||||
const syncUpdate = require('./sync_update');
|
||||
const content_hash = require('./content_hash');
|
||||
@ -80,7 +80,7 @@ async function login() {
|
||||
hash: hash
|
||||
});
|
||||
|
||||
if (source_id.isLocalSourceId(resp.sourceId)) {
|
||||
if (sourceId.isLocalSourceId(resp.sourceId)) {
|
||||
throw new Error(`Sync server has source ID ${resp.sourceId} which is also local. Try restarting sync server.`);
|
||||
}
|
||||
|
||||
@ -109,48 +109,48 @@ async function pullSync(syncContext) {
|
||||
log.info("Pulled " + syncRows.length + " changes from " + changesUri);
|
||||
|
||||
for (const sync of syncRows) {
|
||||
if (source_id.isLocalSourceId(sync.source_id)) {
|
||||
log.info(`Skipping pull #${sync.id} ${sync.entity_name} ${sync.entity_id} because ${sync.source_id} is a local source id.`);
|
||||
if (sourceId.isLocalSourceId(sync.sourceId)) {
|
||||
log.info(`Skipping pull #${sync.id} ${sync.entityName} ${sync.entityId} because ${sync.sourceId} is a local source id.`);
|
||||
|
||||
await setLastSyncedPull(sync.id);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const resp = await syncRequest(syncContext, 'GET', "/api/sync/" + sync.entity_name + "/" + encodeURIComponent(sync.entity_id));
|
||||
const resp = await syncRequest(syncContext, 'GET', "/api/sync/" + sync.entityName + "/" + encodeURIComponent(sync.entityId));
|
||||
|
||||
if (!resp || (sync.entity_name === 'notes' && !resp.entity)) {
|
||||
log.error(`Empty response to pull for sync #${sync.id} ${sync.entity_name}, id=${sync.entity_id}`);
|
||||
if (!resp || (sync.entityName === 'notes' && !resp.entity)) {
|
||||
log.error(`Empty response to pull for sync #${sync.id} ${sync.entityName}, id=${sync.entityId}`);
|
||||
}
|
||||
else if (sync.entity_name === 'notes') {
|
||||
else if (sync.entityName === 'notes') {
|
||||
await syncUpdate.updateNote(resp.entity, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_tree') {
|
||||
else if (sync.entityName === 'notes_tree') {
|
||||
await syncUpdate.updateNoteTree(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_history') {
|
||||
else if (sync.entityName === 'notes_history') {
|
||||
await syncUpdate.updateNoteHistory(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_reordering') {
|
||||
else if (sync.entityName === 'notes_reordering') {
|
||||
await syncUpdate.updateNoteReordering(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'options') {
|
||||
else if (sync.entityName === 'options') {
|
||||
await syncUpdate.updateOptions(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'recent_notes') {
|
||||
else if (sync.entityName === 'recent_notes') {
|
||||
await syncUpdate.updateRecentNotes(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'images') {
|
||||
else if (sync.entityName === 'images') {
|
||||
await syncUpdate.updateImage(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_image') {
|
||||
else if (sync.entityName === 'notes_image') {
|
||||
await syncUpdate.updateNoteImage(resp, syncContext.sourceId);
|
||||
}
|
||||
else if (sync.entity_name === 'attributes') {
|
||||
else if (sync.entityName === 'attributes') {
|
||||
await syncUpdate.updateAttribute(resp, syncContext.sourceId);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
|
||||
throw new Error(`Unrecognized entity type ${sync.entityName} in sync #${sync.id}`);
|
||||
}
|
||||
|
||||
await setLastSyncedPull(sync.id);
|
||||
@ -183,8 +183,8 @@ async function pushSync(syncContext) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (sync.source_id === syncContext.sourceId) {
|
||||
log.info(`Skipping push #${sync.id} ${sync.entity_name} ${sync.entity_id} because it originates from sync target`);
|
||||
if (sync.sourceId === syncContext.sourceId) {
|
||||
log.info(`Skipping push #${sync.id} ${sync.entityName} ${sync.entityId} because it originates from sync target`);
|
||||
}
|
||||
else {
|
||||
await pushEntity(sync, syncContext);
|
||||
@ -199,57 +199,57 @@ async function pushSync(syncContext) {
|
||||
async function pushEntity(sync, syncContext) {
|
||||
let entity;
|
||||
|
||||
if (sync.entity_name === 'notes') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes WHERE note_id = ?', [sync.entity_id]);
|
||||
if (sync.entityName === 'notes') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes WHERE noteId = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_tree') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_tree WHERE note_tree_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'notes_tree') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_tree WHERE noteTreeId = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_history') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_history WHERE note_history_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'notes_history') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_history WHERE noteHistoryId = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'notes_reordering') {
|
||||
else if (sync.entityName === 'notes_reordering') {
|
||||
entity = {
|
||||
parent_note_id: sync.entity_id,
|
||||
ordering: await sql.getMap('SELECT note_tree_id, note_position FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [sync.entity_id])
|
||||
parentNoteId: sync.entityId,
|
||||
ordering: await sql.getMap('SELECT noteTreeId, notePosition FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0', [sync.entityId])
|
||||
};
|
||||
}
|
||||
else if (sync.entity_name === 'options') {
|
||||
entity = await sql.getFirst('SELECT * FROM options WHERE opt_name = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'options') {
|
||||
entity = await sql.getFirst('SELECT * FROM options WHERE name = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'recent_notes') {
|
||||
entity = await sql.getFirst('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'recent_notes') {
|
||||
entity = await sql.getFirst('SELECT * FROM recent_notes WHERE noteTreeId = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'images') {
|
||||
entity = await sql.getFirst('SELECT * FROM images WHERE image_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'images') {
|
||||
entity = await sql.getFirst('SELECT * FROM images WHERE imageId = ?', [sync.entityId]);
|
||||
|
||||
if (entity.data !== null) {
|
||||
entity.data = entity.data.toString('base64');
|
||||
}
|
||||
}
|
||||
else if (sync.entity_name === 'notes_image') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_image WHERE note_image_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'notes_image') {
|
||||
entity = await sql.getFirst('SELECT * FROM notes_image WHERE noteImageId = ?', [sync.entityId]);
|
||||
}
|
||||
else if (sync.entity_name === 'attributes') {
|
||||
entity = await sql.getFirst('SELECT * FROM attributes WHERE attribute_id = ?', [sync.entity_id]);
|
||||
else if (sync.entityName === 'attributes') {
|
||||
entity = await sql.getFirst('SELECT * FROM attributes WHERE attributeId = ?', [sync.entityId]);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
|
||||
throw new Error(`Unrecognized entity type ${sync.entityName} in sync #${sync.id}`);
|
||||
}
|
||||
|
||||
if (!entity) {
|
||||
log.info(`Sync #${sync.id} entity for ${sync.entity_name} ${sync.entity_id} doesn't exist. Skipping.`);
|
||||
log.info(`Sync #${sync.id} entity for ${sync.entityName} ${sync.entityId} doesn't exist. Skipping.`);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`Pushing changes in sync #${sync.id} ${sync.entity_name} ${sync.entity_id}`);
|
||||
log.info(`Pushing changes in sync #${sync.id} ${sync.entityName} ${sync.entityId}`);
|
||||
|
||||
const payload = {
|
||||
sourceId: source_id.getCurrentSourceId(),
|
||||
sourceId: sourceId.getCurrentSourceId(),
|
||||
entity: entity
|
||||
};
|
||||
|
||||
await syncRequest(syncContext, 'PUT', '/api/sync/' + sync.entity_name, payload);
|
||||
await syncRequest(syncContext, 'PUT', '/api/sync/' + sync.entityName, payload);
|
||||
}
|
||||
|
||||
async function checkContentHash(syncContext) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const sql = require('./sql');
|
||||
const source_id = require('./source_id');
|
||||
const sourceId = require('./sourceId');
|
||||
const utils = require('./utils');
|
||||
const sync_setup = require('./sync_setup');
|
||||
const log = require('./log');
|
||||
@ -20,8 +20,8 @@ async function addNoteHistorySync(noteHistoryId, sourceId) {
|
||||
await addEntitySync("notes_history", noteHistoryId, sourceId);
|
||||
}
|
||||
|
||||
async function addOptionsSync(optName, sourceId) {
|
||||
await addEntitySync("options", optName, sourceId);
|
||||
async function addOptionsSync(name, sourceId) {
|
||||
await addEntitySync("options", name, sourceId);
|
||||
}
|
||||
|
||||
async function addRecentNoteSync(noteTreeId, sourceId) {
|
||||
@ -42,16 +42,16 @@ async function addAttributeSync(attributeId, sourceId) {
|
||||
|
||||
async function addEntitySync(entityName, entityId, sourceId) {
|
||||
await sql.replace("sync", {
|
||||
entity_name: entityName,
|
||||
entity_id: entityId,
|
||||
sync_date: utils.nowDate(),
|
||||
source_id: sourceId || source_id.getCurrentSourceId()
|
||||
entityName: entityName,
|
||||
entityId: entityId,
|
||||
syncDate: utils.nowDate(),
|
||||
sourceId: sourceId || sourceId.getCurrentSourceId()
|
||||
});
|
||||
|
||||
if (!sync_setup.isSyncSetup) {
|
||||
// this is because the "server" instances shouldn't have outstanding pushes
|
||||
// useful when you fork the DB for new "client" instance, it won't try to sync the whole DB
|
||||
await sql.execute("UPDATE options SET opt_value = (SELECT MAX(id) FROM sync) WHERE opt_name IN('last_synced_push', 'last_synced_pull')");
|
||||
await sql.execute("UPDATE options SET value = (SELECT MAX(id) FROM sync) WHERE name IN('last_synced_push', 'last_synced_pull')");
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,8 +59,8 @@ async function cleanupSyncRowsForMissingEntities(entityName, entityKey) {
|
||||
await sql.execute(`
|
||||
DELETE
|
||||
FROM sync
|
||||
WHERE sync.entity_name = '${entityName}'
|
||||
AND sync.entity_id NOT IN (SELECT ${entityKey} FROM ${entityName})`);
|
||||
WHERE sync.entityName = '${entityName}'
|
||||
AND sync.entityId NOT IN (SELECT ${entityKey} FROM ${entityName})`);
|
||||
}
|
||||
|
||||
async function fillSyncRows(entityName, entityKey) {
|
||||
@ -69,30 +69,30 @@ async function fillSyncRows(entityName, entityKey) {
|
||||
const entityIds = await sql.getFirstColumn(`SELECT ${entityKey} FROM ${entityName}`);
|
||||
|
||||
for (const entityId of entityIds) {
|
||||
const existingRows = await sql.getFirstValue("SELECT COUNT(id) FROM sync WHERE entity_name = ? AND entity_id = ?", [entityName, entityId]);
|
||||
const existingRows = await sql.getFirstValue("SELECT COUNT(id) FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]);
|
||||
|
||||
// we don't want to replace existing entities (which would effectively cause full resync)
|
||||
if (existingRows === 0) {
|
||||
log.info(`Creating missing sync record for ${entityName} ${entityId}`);
|
||||
|
||||
await sql.insert("sync", {
|
||||
entity_name: entityName,
|
||||
entity_id: entityId,
|
||||
source_id: "SYNC_FILL",
|
||||
sync_date: utils.nowDate()
|
||||
entityName: entityName,
|
||||
entityId: entityId,
|
||||
sourceId: "SYNC_FILL",
|
||||
syncDate: utils.nowDate()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function fillAllSyncRows() {
|
||||
await fillSyncRows("notes", "note_id");
|
||||
await fillSyncRows("notes_tree", "note_tree_id");
|
||||
await fillSyncRows("notes_history", "note_history_id");
|
||||
await fillSyncRows("recent_notes", "note_tree_id");
|
||||
await fillSyncRows("images", "image_id");
|
||||
await fillSyncRows("notes_image", "note_image_id");
|
||||
await fillSyncRows("attributes", "attribute_id");
|
||||
await fillSyncRows("notes", "noteId");
|
||||
await fillSyncRows("notes_tree", "noteTreeId");
|
||||
await fillSyncRows("notes_history", "noteHistoryId");
|
||||
await fillSyncRows("recent_notes", "noteTreeId");
|
||||
await fillSyncRows("images", "imageId");
|
||||
await fillSyncRows("notes_image", "noteImageId");
|
||||
await fillSyncRows("attributes", "attributeId");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -5,48 +5,48 @@ const notes = require('./notes');
|
||||
const sync_table = require('./sync_table');
|
||||
|
||||
async function updateNote(entity, sourceId) {
|
||||
const origNote = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [entity.note_id]);
|
||||
const origNote = await sql.getFirst("SELECT * FROM notes WHERE noteId = ?", [entity.noteId]);
|
||||
|
||||
if (!origNote || origNote.date_modified <= entity.date_modified) {
|
||||
if (!origNote || origNote.dateModified <= entity.dateModified) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace("notes", entity);
|
||||
|
||||
await sync_table.addNoteSync(entity.note_id, sourceId);
|
||||
await eventLog.addNoteEvent(entity.note_id, "Synced note <note>");
|
||||
await sync_table.addNoteSync(entity.noteId, sourceId);
|
||||
await eventLog.addNoteEvent(entity.noteId, "Synced note <note>");
|
||||
});
|
||||
|
||||
log.info("Update/sync note " + entity.note_id);
|
||||
log.info("Update/sync note " + entity.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateNoteTree(entity, sourceId) {
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM notes_tree WHERE note_tree_id = ?", [entity.note_tree_id]);
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM notes_tree WHERE noteTreeId = ?", [entity.noteTreeId]);
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
if (orig === null || orig.date_modified < entity.date_modified) {
|
||||
delete entity.is_expanded;
|
||||
if (orig === null || orig.dateModified < entity.dateModified) {
|
||||
delete entity.isExpanded;
|
||||
|
||||
await sql.replace('notes_tree', entity);
|
||||
|
||||
await sync_table.addNoteTreeSync(entity.note_tree_id, sourceId);
|
||||
await sync_table.addNoteTreeSync(entity.noteTreeId, sourceId);
|
||||
|
||||
log.info("Update/sync note tree " + entity.note_tree_id);
|
||||
log.info("Update/sync note tree " + entity.noteTreeId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function updateNoteHistory(entity, sourceId) {
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM notes_history WHERE note_history_id = ?", [entity.note_history_id]);
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM notes_history WHERE noteHistoryId = ?", [entity.noteHistoryId]);
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
// we update note history even if date modified to is the same because the only thing which might have changed
|
||||
// is the protected status (and correnspondingly note_title and note_text) which doesn't affect the date_modified_to
|
||||
if (orig === null || orig.date_modified_to <= entity.date_modified_to) {
|
||||
// is the protected status (and correnspondingly title and content) which doesn't affect the dateModifiedTo
|
||||
if (orig === null || orig.dateModifiedTo <= entity.dateModifiedTo) {
|
||||
await sql.replace('notes_history', entity);
|
||||
|
||||
await sync_table.addNoteHistorySync(entity.note_history_id, sourceId);
|
||||
await sync_table.addNoteHistorySync(entity.noteHistoryId, sourceId);
|
||||
|
||||
log.info("Update/sync note history " + entity.note_history_id);
|
||||
log.info("Update/sync note history " + entity.noteHistoryId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -54,39 +54,39 @@ async function updateNoteHistory(entity, sourceId) {
|
||||
async function updateNoteReordering(entity, sourceId) {
|
||||
await sql.doInTransaction(async () => {
|
||||
Object.keys(entity.ordering).forEach(async key => {
|
||||
await sql.execute("UPDATE notes_tree SET note_position = ? WHERE note_tree_id = ?", [entity.ordering[key], key]);
|
||||
await sql.execute("UPDATE notes_tree SET notePosition = ? WHERE noteTreeId = ?", [entity.ordering[key], key]);
|
||||
});
|
||||
|
||||
await sync_table.addNoteReorderingSync(entity.parent_note_id, sourceId);
|
||||
await sync_table.addNoteReorderingSync(entity.parentNoteId, sourceId);
|
||||
});
|
||||
}
|
||||
|
||||
async function updateOptions(entity, sourceId) {
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM options WHERE opt_name = ?", [entity.opt_name]);
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM options WHERE name = ?", [entity.name]);
|
||||
|
||||
if (!orig.is_synced) {
|
||||
if (!orig.isSynced) {
|
||||
return;
|
||||
}
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
if (orig === null || orig.date_modified < entity.date_modified) {
|
||||
if (orig === null || orig.dateModified < entity.dateModified) {
|
||||
await sql.replace('options', entity);
|
||||
|
||||
await sync_table.addOptionsSync(entity.opt_name, sourceId);
|
||||
await sync_table.addOptionsSync(entity.name, sourceId);
|
||||
|
||||
await eventLog.addEvent("Synced option " + entity.opt_name);
|
||||
await eventLog.addEvent("Synced option " + entity.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function updateRecentNotes(entity, sourceId) {
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM recent_notes WHERE note_tree_id = ?", [entity.note_tree_id]);
|
||||
const orig = await sql.getFirstOrNull("SELECT * FROM recent_notes WHERE noteTreeId = ?", [entity.noteTreeId]);
|
||||
|
||||
if (orig === null || orig.date_accessed < entity.date_accessed) {
|
||||
if (orig === null || orig.dateAccessed < entity.dateAccessed) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace('recent_notes', entity);
|
||||
|
||||
await sync_table.addRecentNoteSync(entity.note_tree_id, sourceId);
|
||||
await sync_table.addRecentNoteSync(entity.noteTreeId, sourceId);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -96,44 +96,44 @@ async function updateImage(entity, sourceId) {
|
||||
entity.data = Buffer.from(entity.data, 'base64');
|
||||
}
|
||||
|
||||
const origImage = await sql.getFirst("SELECT * FROM images WHERE image_id = ?", [entity.image_id]);
|
||||
const origImage = await sql.getFirst("SELECT * FROM images WHERE imageId = ?", [entity.imageId]);
|
||||
|
||||
if (!origImage || origImage.date_modified <= entity.date_modified) {
|
||||
if (!origImage || origImage.dateModified <= entity.dateModified) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace("images", entity);
|
||||
|
||||
await sync_table.addImageSync(entity.image_id, sourceId);
|
||||
await sync_table.addImageSync(entity.imageId, sourceId);
|
||||
});
|
||||
|
||||
log.info("Update/sync image " + entity.image_id);
|
||||
log.info("Update/sync image " + entity.imageId);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateNoteImage(entity, sourceId) {
|
||||
const origNoteImage = await sql.getFirst("SELECT * FROM notes_image WHERE note_image_id = ?", [entity.note_image_id]);
|
||||
const origNoteImage = await sql.getFirst("SELECT * FROM notes_image WHERE noteImageId = ?", [entity.noteImageId]);
|
||||
|
||||
if (!origNoteImage || origNoteImage.date_modified <= entity.date_modified) {
|
||||
if (!origNoteImage || origNoteImage.dateModified <= entity.dateModified) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace("notes_image", entity);
|
||||
|
||||
await sync_table.addNoteImageSync(entity.note_image_id, sourceId);
|
||||
await sync_table.addNoteImageSync(entity.noteImageId, sourceId);
|
||||
});
|
||||
|
||||
log.info("Update/sync note image " + entity.note_image_id);
|
||||
log.info("Update/sync note image " + entity.noteImageId);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateAttribute(entity, sourceId) {
|
||||
const origAttribute = await sql.getFirst("SELECT * FROM attributes WHERE attribute_id = ?", [entity.attribute_id]);
|
||||
const origAttribute = await sql.getFirst("SELECT * FROM attributes WHERE attributeId = ?", [entity.attributeId]);
|
||||
|
||||
if (!origAttribute || origAttribute.date_modified <= entity.date_modified) {
|
||||
if (!origAttribute || origAttribute.dateModified <= entity.dateModified) {
|
||||
await sql.doInTransaction(async () => {
|
||||
await sql.replace("attributes", entity);
|
||||
|
||||
await sync_table.addAttributeSync(entity.attribute_id, sourceId);
|
||||
await sync_table.addAttributeSync(entity.attributeId, sourceId);
|
||||
});
|
||||
|
||||
log.info("Update/sync attribute " + entity.attribute_id);
|
||||
log.info("Update/sync attribute " + entity.attributeId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ const sync_table = require('./sync_table');
|
||||
async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId = null) {
|
||||
const existing = await getExistingNoteTree(parentNoteId, childNoteId);
|
||||
|
||||
if (existing && (noteTreeId === null || existing.note_tree_id !== noteTreeId)) {
|
||||
if (existing && (noteTreeId === null || existing.noteTreeId !== noteTreeId)) {
|
||||
res.send({
|
||||
success: false,
|
||||
message: 'This note already exists in the target.'
|
||||
@ -28,7 +28,7 @@ async function validateParentChild(res, parentNoteId, childNoteId, noteTreeId =
|
||||
}
|
||||
|
||||
async function getExistingNoteTree(parentNoteId, childNoteId) {
|
||||
return await sql.getFirst('SELECT * FROM notes_tree WHERE note_id = ? AND parent_note_id = ? AND is_deleted = 0', [childNoteId, parentNoteId]);
|
||||
return await sql.getFirst('SELECT * FROM notes_tree WHERE noteId = ? AND parentNoteId = ? AND isDeleted = 0', [childNoteId, parentNoteId]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,7 +51,7 @@ async function checkTreeCycle(parentNoteId, childNoteId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parentNoteIds = await sql.getFirstColumn("SELECT DISTINCT parent_note_id FROM notes_tree WHERE note_id = ? AND is_deleted = 0", [parentNoteId]);
|
||||
const parentNoteIds = await sql.getFirstColumn("SELECT DISTINCT parentNoteId FROM notes_tree WHERE noteId = ? AND isDeleted = 0", [parentNoteId]);
|
||||
|
||||
for (const pid of parentNoteIds) {
|
||||
if (!await checkTreeCycleInner(pid)) {
|
||||
@ -66,13 +66,13 @@ async function checkTreeCycle(parentNoteId, childNoteId) {
|
||||
}
|
||||
|
||||
async function getNoteTree(noteTreeId) {
|
||||
return sql.getFirst("SELECT * FROM notes_tree WHERE note_tree_id = ?", [noteTreeId]);
|
||||
return sql.getFirst("SELECT * FROM notes_tree WHERE noteTreeId = ?", [noteTreeId]);
|
||||
}
|
||||
|
||||
async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
|
||||
subTreeNoteIds.push(parentNoteId);
|
||||
|
||||
const children = await sql.getFirstColumn("SELECT note_id FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0", [parentNoteId]);
|
||||
const children = await sql.getFirstColumn("SELECT noteId FROM notes_tree WHERE parentNoteId = ? AND isDeleted = 0", [parentNoteId]);
|
||||
|
||||
for (const childNoteId of children) {
|
||||
await loadSubTreeNoteIds(childNoteId, subTreeNoteIds);
|
||||
@ -81,19 +81,19 @@ async function loadSubTreeNoteIds(parentNoteId, subTreeNoteIds) {
|
||||
|
||||
async function sortNotesAlphabetically(parentNoteId, req, sourceId) {
|
||||
await sql.doInTransaction(async () => {
|
||||
const notes = await sql.getAll(`SELECT note_tree_id, note_id, note_title, is_protected
|
||||
FROM notes JOIN notes_tree USING(note_id)
|
||||
WHERE notes_tree.is_deleted = 0 AND parent_note_id = ?`, [parentNoteId]);
|
||||
const notes = await sql.getAll(`SELECT noteTreeId, noteId, title, isProtected
|
||||
FROM notes JOIN notes_tree USING(noteId)
|
||||
WHERE notes_tree.isDeleted = 0 AND parentNoteId = ?`, [parentNoteId]);
|
||||
|
||||
protected_session.decryptNotes(req, notes);
|
||||
|
||||
notes.sort((a, b) => a.note_title.toLowerCase() < b.note_title.toLowerCase() ? -1 : 1);
|
||||
notes.sort((a, b) => a.title.toLowerCase() < b.title.toLowerCase() ? -1 : 1);
|
||||
|
||||
let position = 1;
|
||||
|
||||
for (const note of notes) {
|
||||
await sql.execute("UPDATE notes_tree SET note_position = ? WHERE note_tree_id = ?",
|
||||
[position, note.note_tree_id]);
|
||||
await sql.execute("UPDATE notes_tree SET notePosition = ? WHERE noteTreeId = ?",
|
||||
[position, note.noteTreeId]);
|
||||
|
||||
position++;
|
||||
}
|
||||
|
@ -395,7 +395,7 @@
|
||||
</thead>
|
||||
<tbody data-bind="foreach: attributes">
|
||||
<tr>
|
||||
<td data-bind="text: attribute_id"></td>
|
||||
<td data-bind="text: attributeId"></td>
|
||||
<td>
|
||||
<input type="text" data-bind="value: name"/>
|
||||
</td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user