Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7dd3558a7 | |||
| eac5ec6e26 | |||
| f273b4334e | |||
| 15eaf67189 | |||
| 983d9c4319 | |||
| a88a00b60e | |||
| a44f43b133 | |||
| 69677b15fe | |||
| 2573c3b8a6 | |||
| 0b0e9f2953 | |||
| 1990c9399e | |||
| 151641b659 | |||
| 36c6376220 | |||
| f0e22b70f6 | |||
| 225e893461 | |||
| 064a11d872 | |||
| 3760835608 | |||
| e7ac2ec4ed | |||
| 8da8dfc543 | |||
| 6b3c8b4bac | |||
| 25fe78012f | |||
| 147d79c65c | |||
| 6fddd2bd62 | |||
| 77c9b64dc7 | |||
| 47cb7c7f5e | |||
| 1bd769827d | |||
| 288ec88c2f | |||
| 71916b5e28 | |||
| b2d4330692 | |||
| 253a6ef081 | |||
| e1e020c1a4 | |||
| 2b4413a1bd | |||
| dae674a7cd | |||
| 751bf94758 | |||
| 4b934a4a81 | |||
| 7e374e795b | |||
| be378f71b0 | |||
| 27f74489fd | |||
| ae8f4ffbbe | |||
| 896776516b | |||
| a27525af9e | |||
| 83b4382787 | |||
| ef1b32d586 | |||
| fe3a0bc756 | |||
| 2259e1d44d | |||
| 9ca4a016eb |
+135
-241
@@ -17,763 +17,657 @@
|
||||
<table id="9" parent="2" name="event_log"/>
|
||||
<table id="10" parent="2" name="links"/>
|
||||
<table id="11" parent="2" name="note_contents"/>
|
||||
<table id="12" parent="2" name="note_fulltext_config">
|
||||
<WithoutRowId>1</WithoutRowId>
|
||||
</table>
|
||||
<table id="13" parent="2" name="note_fulltext_content"/>
|
||||
<table id="14" parent="2" name="note_fulltext_data"/>
|
||||
<table id="15" parent="2" name="note_fulltext_docsize"/>
|
||||
<table id="16" parent="2" name="note_fulltext_idx">
|
||||
<WithoutRowId>1</WithoutRowId>
|
||||
</table>
|
||||
<table id="17" parent="2" name="note_revisions"/>
|
||||
<table id="18" parent="2" name="notes"/>
|
||||
<table id="19" parent="2" name="options"/>
|
||||
<table id="20" parent="2" name="recent_notes"/>
|
||||
<table id="21" parent="2" name="source_ids"/>
|
||||
<table id="22" parent="2" name="sqlite_master">
|
||||
<table id="12" parent="2" name="note_revisions"/>
|
||||
<table id="13" parent="2" name="notes"/>
|
||||
<table id="14" parent="2" name="options"/>
|
||||
<table id="15" parent="2" name="recent_notes"/>
|
||||
<table id="16" parent="2" name="source_ids"/>
|
||||
<table id="17" parent="2" name="sqlite_master">
|
||||
<System>1</System>
|
||||
</table>
|
||||
<table id="23" parent="2" name="sqlite_sequence">
|
||||
<table id="18" parent="2" name="sqlite_sequence">
|
||||
<System>1</System>
|
||||
</table>
|
||||
<table id="24" parent="2" name="sync"/>
|
||||
<virtual-table id="25" parent="2" name="note_fulltext">
|
||||
<Module>fts5</Module>
|
||||
<Arguments>noteId UNINDEXED
|
||||
title
|
||||
titleHash UNINDEXED
|
||||
content
|
||||
contentHash UNINDEXED</Arguments>
|
||||
</virtual-table>
|
||||
<column id="26" parent="6" name="apiTokenId">
|
||||
<table id="19" parent="2" name="sync"/>
|
||||
<column id="20" parent="6" name="apiTokenId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="27" parent="6" name="token">
|
||||
<column id="21" parent="6" name="token">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="28" parent="6" name="utcDateCreated">
|
||||
<column id="22" parent="6" name="utcDateCreated">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="29" parent="6" name="isDeleted">
|
||||
<column id="23" parent="6" name="isDeleted">
|
||||
<Position>4</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="30" parent="6" name="hash">
|
||||
<column id="24" parent="6" name="hash">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<index id="31" parent="6" name="sqlite_autoindex_api_tokens_1">
|
||||
<index id="25" parent="6" name="sqlite_autoindex_api_tokens_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>apiTokenId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="32" parent="6">
|
||||
<key id="26" parent="6">
|
||||
<ColNames>apiTokenId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_api_tokens_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="33" parent="7" name="attributeId">
|
||||
<column id="27" parent="7" name="attributeId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="34" parent="7" name="noteId">
|
||||
<column id="28" parent="7" name="noteId">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="35" parent="7" name="type">
|
||||
<column id="29" parent="7" name="type">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="36" parent="7" name="name">
|
||||
<column id="30" parent="7" name="name">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="37" parent="7" name="value">
|
||||
<column id="31" parent="7" name="value">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>''</DefaultExpression>
|
||||
</column>
|
||||
<column id="38" parent="7" name="position">
|
||||
<column id="32" parent="7" name="position">
|
||||
<Position>6</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="39" parent="7" name="utcDateCreated">
|
||||
<column id="33" parent="7" name="utcDateCreated">
|
||||
<Position>7</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="40" parent="7" name="utcDateModified">
|
||||
<column id="34" parent="7" name="utcDateModified">
|
||||
<Position>8</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="41" parent="7" name="isDeleted">
|
||||
<column id="35" parent="7" name="isDeleted">
|
||||
<Position>9</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="42" parent="7" name="hash">
|
||||
<column id="36" parent="7" name="hash">
|
||||
<Position>10</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="43" parent="7" name="isInheritable">
|
||||
<column id="37" parent="7" name="isInheritable">
|
||||
<Position>11</Position>
|
||||
<DataType>int|0s</DataType>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<index id="44" parent="7" name="sqlite_autoindex_attributes_1">
|
||||
<index id="38" parent="7" name="sqlite_autoindex_attributes_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>attributeId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<index id="45" parent="7" name="IDX_attributes_noteId_index">
|
||||
<index id="39" parent="7" name="IDX_attributes_noteId_index">
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="46" parent="7" name="IDX_attributes_name_value">
|
||||
<index id="40" parent="7" name="IDX_attributes_name_value">
|
||||
<ColNames>name
|
||||
value</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="47" parent="7" name="IDX_attributes_name_index">
|
||||
<index id="41" parent="7" name="IDX_attributes_name_index">
|
||||
<ColNames>name</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="48" parent="7" name="IDX_attributes_value_index">
|
||||
<index id="42" parent="7" name="IDX_attributes_value_index">
|
||||
<ColNames>value</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<key id="49" parent="7">
|
||||
<key id="43" parent="7">
|
||||
<ColNames>attributeId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_attributes_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="50" parent="8" name="branchId">
|
||||
<column id="44" parent="8" name="branchId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="51" parent="8" name="noteId">
|
||||
<column id="45" parent="8" name="noteId">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="52" parent="8" name="parentNoteId">
|
||||
<column id="46" parent="8" name="parentNoteId">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="53" parent="8" name="notePosition">
|
||||
<column id="47" parent="8" name="notePosition">
|
||||
<Position>4</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="54" parent="8" name="prefix">
|
||||
<column id="48" parent="8" name="prefix">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="55" parent="8" name="isExpanded">
|
||||
<column id="49" parent="8" name="isExpanded">
|
||||
<Position>6</Position>
|
||||
<DataType>BOOLEAN|0s</DataType>
|
||||
</column>
|
||||
<column id="56" parent="8" name="isDeleted">
|
||||
<column id="50" parent="8" name="isDeleted">
|
||||
<Position>7</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="57" parent="8" name="utcDateModified">
|
||||
<column id="51" parent="8" name="utcDateModified">
|
||||
<Position>8</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="58" parent="8" name="utcDateCreated">
|
||||
<column id="52" parent="8" name="utcDateCreated">
|
||||
<Position>9</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="59" parent="8" name="hash">
|
||||
<column id="53" parent="8" name="hash">
|
||||
<Position>10</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<index id="60" parent="8" name="sqlite_autoindex_branches_1">
|
||||
<index id="54" parent="8" name="sqlite_autoindex_branches_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>branchId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<index id="61" parent="8" name="IDX_branches_noteId_parentNoteId">
|
||||
<index id="55" parent="8" name="IDX_branches_noteId_parentNoteId">
|
||||
<ColNames>noteId
|
||||
parentNoteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="62" parent="8" name="IDX_branches_noteId">
|
||||
<index id="56" parent="8" name="IDX_branches_noteId">
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="63" parent="8" name="IDX_branches_parentNoteId">
|
||||
<index id="57" parent="8" name="IDX_branches_parentNoteId">
|
||||
<ColNames>parentNoteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<key id="64" parent="8">
|
||||
<key id="58" parent="8">
|
||||
<ColNames>branchId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_branches_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="65" parent="9" name="eventId">
|
||||
<column id="59" parent="9" name="eventId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="66" parent="9" name="noteId">
|
||||
<column id="60" parent="9" name="noteId">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="67" parent="9" name="comment">
|
||||
<column id="61" parent="9" name="comment">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="68" parent="9" name="utcDateCreated">
|
||||
<column id="62" parent="9" name="utcDateCreated">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="69" parent="9" name="sqlite_autoindex_event_log_1">
|
||||
<index id="63" parent="9" name="sqlite_autoindex_event_log_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>eventId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="70" parent="9">
|
||||
<key id="64" parent="9">
|
||||
<ColNames>eventId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_event_log_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="71" parent="10" name="linkId">
|
||||
<column id="65" parent="10" name="linkId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="72" parent="10" name="noteId">
|
||||
<column id="66" parent="10" name="noteId">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="73" parent="10" name="targetNoteId">
|
||||
<column id="67" parent="10" name="targetNoteId">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="74" parent="10" name="type">
|
||||
<column id="68" parent="10" name="type">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="75" parent="10" name="hash">
|
||||
<column id="69" parent="10" name="hash">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="76" parent="10" name="isDeleted">
|
||||
<column id="70" parent="10" name="isDeleted">
|
||||
<Position>6</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="77" parent="10" name="utcDateCreated">
|
||||
<column id="71" parent="10" name="utcDateCreated">
|
||||
<Position>7</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="78" parent="10" name="utcDateModified">
|
||||
<column id="72" parent="10" name="utcDateModified">
|
||||
<Position>8</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="79" parent="10" name="sqlite_autoindex_links_1">
|
||||
<index id="73" parent="10" name="sqlite_autoindex_links_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>linkId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<index id="80" parent="10" name="IDX_links_noteId_index">
|
||||
<index id="74" parent="10" name="IDX_links_noteId_index">
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="81" parent="10" name="IDX_links_targetNoteId_index">
|
||||
<index id="75" parent="10" name="IDX_links_targetNoteId_index">
|
||||
<ColNames>targetNoteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<key id="82" parent="10">
|
||||
<key id="76" parent="10">
|
||||
<ColNames>linkId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_links_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="83" parent="11" name="noteId">
|
||||
<column id="77" parent="11" name="noteId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="84" parent="11" name="content">
|
||||
<column id="78" parent="11" name="content">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<DefaultExpression>NULL</DefaultExpression>
|
||||
</column>
|
||||
<column id="85" parent="11" name="hash">
|
||||
<column id="79" parent="11" name="hash">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="86" parent="11" name="utcDateModified">
|
||||
<column id="80" parent="11" name="utcDateModified">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="87" parent="11" name="sqlite_autoindex_note_contents_1">
|
||||
<index id="81" parent="11" name="sqlite_autoindex_note_contents_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="88" parent="11">
|
||||
<key id="82" parent="11">
|
||||
<ColNames>noteId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_note_contents_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="89" parent="12" name="k">
|
||||
<Position>1</Position>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="90" parent="12" name="v">
|
||||
<Position>2</Position>
|
||||
</column>
|
||||
<index id="91" parent="12" name="sqlite_autoindex_note_fulltext_config_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>k</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="92" parent="12">
|
||||
<ColNames>k</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_note_fulltext_config_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="93" parent="13" name="id">
|
||||
<Position>1</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
</column>
|
||||
<column id="94" parent="13" name="c0">
|
||||
<Position>2</Position>
|
||||
</column>
|
||||
<column id="95" parent="13" name="c1">
|
||||
<Position>3</Position>
|
||||
</column>
|
||||
<column id="96" parent="13" name="c2">
|
||||
<Position>4</Position>
|
||||
</column>
|
||||
<column id="97" parent="13" name="c3">
|
||||
<Position>5</Position>
|
||||
</column>
|
||||
<column id="98" parent="13" name="c4">
|
||||
<Position>6</Position>
|
||||
</column>
|
||||
<key id="99" parent="13">
|
||||
<ColNames>id</ColNames>
|
||||
<Primary>1</Primary>
|
||||
</key>
|
||||
<column id="100" parent="14" name="id">
|
||||
<Position>1</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
</column>
|
||||
<column id="101" parent="14" name="block">
|
||||
<Position>2</Position>
|
||||
<DataType>BLOB|0s</DataType>
|
||||
</column>
|
||||
<key id="102" parent="14">
|
||||
<ColNames>id</ColNames>
|
||||
<Primary>1</Primary>
|
||||
</key>
|
||||
<column id="103" parent="15" name="id">
|
||||
<Position>1</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
</column>
|
||||
<column id="104" parent="15" name="sz">
|
||||
<Position>2</Position>
|
||||
<DataType>BLOB|0s</DataType>
|
||||
</column>
|
||||
<key id="105" parent="15">
|
||||
<ColNames>id</ColNames>
|
||||
<Primary>1</Primary>
|
||||
</key>
|
||||
<column id="106" parent="16" name="segid">
|
||||
<Position>1</Position>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="107" parent="16" name="term">
|
||||
<Position>2</Position>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="108" parent="16" name="pgno">
|
||||
<Position>3</Position>
|
||||
</column>
|
||||
<index id="109" parent="16" name="sqlite_autoindex_note_fulltext_idx_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>segid
|
||||
term</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="110" parent="16">
|
||||
<ColNames>segid
|
||||
term</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_note_fulltext_idx_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="111" parent="17" name="noteRevisionId">
|
||||
<column id="83" parent="12" name="noteRevisionId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="112" parent="17" name="noteId">
|
||||
<column id="84" parent="12" name="noteId">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="113" parent="17" name="title">
|
||||
<column id="85" parent="12" name="title">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="114" parent="17" name="content">
|
||||
<column id="86" parent="12" name="content">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="115" parent="17" name="isProtected">
|
||||
<column id="87" parent="12" name="isProtected">
|
||||
<Position>5</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="116" parent="17" name="utcDateModifiedFrom">
|
||||
<column id="88" parent="12" name="utcDateModifiedFrom">
|
||||
<Position>6</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="117" parent="17" name="utcDateModifiedTo">
|
||||
<column id="89" parent="12" name="utcDateModifiedTo">
|
||||
<Position>7</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="118" parent="17" name="dateModifiedFrom">
|
||||
<column id="90" parent="12" name="dateModifiedFrom">
|
||||
<Position>8</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="119" parent="17" name="dateModifiedTo">
|
||||
<column id="91" parent="12" name="dateModifiedTo">
|
||||
<Position>9</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="120" parent="17" name="type">
|
||||
<column id="92" parent="12" name="type">
|
||||
<Position>10</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>''</DefaultExpression>
|
||||
</column>
|
||||
<column id="121" parent="17" name="mime">
|
||||
<column id="93" parent="12" name="mime">
|
||||
<Position>11</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>''</DefaultExpression>
|
||||
</column>
|
||||
<column id="122" parent="17" name="hash">
|
||||
<column id="94" parent="12" name="hash">
|
||||
<Position>12</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<index id="123" parent="17" name="sqlite_autoindex_note_revisions_1">
|
||||
<index id="95" parent="12" name="sqlite_autoindex_note_revisions_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>noteRevisionId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<index id="124" parent="17" name="IDX_note_revisions_noteId">
|
||||
<index id="96" parent="12" name="IDX_note_revisions_noteId">
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="125" parent="17" name="IDX_note_revisions_dateModifiedFrom">
|
||||
<index id="97" parent="12" name="IDX_note_revisions_dateModifiedFrom">
|
||||
<ColNames>utcDateModifiedFrom</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<index id="126" parent="17" name="IDX_note_revisions_dateModifiedTo">
|
||||
<index id="98" parent="12" name="IDX_note_revisions_dateModifiedTo">
|
||||
<ColNames>utcDateModifiedTo</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<key id="127" parent="17">
|
||||
<key id="99" parent="12">
|
||||
<ColNames>noteRevisionId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_note_revisions_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="128" parent="18" name="noteId">
|
||||
<column id="100" parent="13" name="noteId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="129" parent="18" name="title">
|
||||
<column id="101" parent="13" name="title">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>"note"</DefaultExpression>
|
||||
</column>
|
||||
<column id="130" parent="18" name="isProtected">
|
||||
<column id="102" parent="13" name="isProtected">
|
||||
<Position>3</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="131" parent="18" name="type">
|
||||
<column id="103" parent="13" name="type">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>'text'</DefaultExpression>
|
||||
</column>
|
||||
<column id="132" parent="18" name="mime">
|
||||
<column id="104" parent="13" name="mime">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>'text/html'</DefaultExpression>
|
||||
</column>
|
||||
<column id="133" parent="18" name="hash">
|
||||
<column id="105" parent="13" name="hash">
|
||||
<Position>6</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="134" parent="18" name="isDeleted">
|
||||
<column id="106" parent="13" name="isDeleted">
|
||||
<Position>7</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="135" parent="18" name="dateCreated">
|
||||
<column id="107" parent="13" name="dateCreated">
|
||||
<Position>8</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="136" parent="18" name="dateModified">
|
||||
<column id="108" parent="13" name="dateModified">
|
||||
<Position>9</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="137" parent="18" name="utcDateCreated">
|
||||
<column id="109" parent="13" name="utcDateCreated">
|
||||
<Position>10</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="138" parent="18" name="utcDateModified">
|
||||
<column id="110" parent="13" name="utcDateModified">
|
||||
<Position>11</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="139" parent="18" name="sqlite_autoindex_notes_1">
|
||||
<index id="111" parent="13" name="sqlite_autoindex_notes_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>noteId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="140" parent="18">
|
||||
<key id="112" parent="13">
|
||||
<ColNames>noteId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_notes_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="141" parent="19" name="name">
|
||||
<column id="113" parent="14" name="name">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="142" parent="19" name="value">
|
||||
<column id="114" parent="14" name="value">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
</column>
|
||||
<column id="143" parent="19" name="isSynced">
|
||||
<column id="115" parent="14" name="isSynced">
|
||||
<Position>3</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>0</DefaultExpression>
|
||||
</column>
|
||||
<column id="144" parent="19" name="hash">
|
||||
<column id="116" parent="14" name="hash">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="145" parent="19" name="utcDateCreated">
|
||||
<column id="117" parent="14" name="utcDateCreated">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="146" parent="19" name="utcDateModified">
|
||||
<column id="118" parent="14" name="utcDateModified">
|
||||
<Position>6</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="147" parent="19" name="sqlite_autoindex_options_1">
|
||||
<index id="119" parent="14" name="sqlite_autoindex_options_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>name</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="148" parent="19">
|
||||
<key id="120" parent="14">
|
||||
<ColNames>name</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_options_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="149" parent="20" name="branchId">
|
||||
<column id="121" parent="15" name="branchId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="150" parent="20" name="notePath">
|
||||
<column id="122" parent="15" name="notePath">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="151" parent="20" name="hash">
|
||||
<column id="123" parent="15" name="hash">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<DefaultExpression>""</DefaultExpression>
|
||||
</column>
|
||||
<column id="152" parent="20" name="utcDateCreated">
|
||||
<column id="124" parent="15" name="utcDateCreated">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="153" parent="20" name="isDeleted">
|
||||
<column id="125" parent="15" name="isDeleted">
|
||||
<Position>5</Position>
|
||||
<DataType>INT|0s</DataType>
|
||||
</column>
|
||||
<index id="154" parent="20" name="sqlite_autoindex_recent_notes_1">
|
||||
<index id="126" parent="15" name="sqlite_autoindex_recent_notes_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>branchId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="155" parent="20">
|
||||
<key id="127" parent="15">
|
||||
<ColNames>branchId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_recent_notes_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="156" parent="21" name="sourceId">
|
||||
<column id="128" parent="16" name="sourceId">
|
||||
<Position>1</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="157" parent="21" name="utcDateCreated">
|
||||
<column id="129" parent="16" name="utcDateCreated">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="158" parent="21" name="sqlite_autoindex_source_ids_1">
|
||||
<index id="130" parent="16" name="sqlite_autoindex_source_ids_1">
|
||||
<NameSurrogate>1</NameSurrogate>
|
||||
<ColNames>sourceId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<key id="159" parent="21">
|
||||
<key id="131" parent="16">
|
||||
<ColNames>sourceId</ColNames>
|
||||
<Primary>1</Primary>
|
||||
<UnderlyingIndexName>sqlite_autoindex_source_ids_1</UnderlyingIndexName>
|
||||
</key>
|
||||
<column id="160" parent="22" name="type">
|
||||
<column id="132" parent="17" name="type">
|
||||
<Position>1</Position>
|
||||
<DataType>text|0s</DataType>
|
||||
</column>
|
||||
<column id="161" parent="22" name="name">
|
||||
<column id="133" parent="17" name="name">
|
||||
<Position>2</Position>
|
||||
<DataType>text|0s</DataType>
|
||||
</column>
|
||||
<column id="162" parent="22" name="tbl_name">
|
||||
<column id="134" parent="17" name="tbl_name">
|
||||
<Position>3</Position>
|
||||
<DataType>text|0s</DataType>
|
||||
</column>
|
||||
<column id="163" parent="22" name="rootpage">
|
||||
<column id="135" parent="17" name="rootpage">
|
||||
<Position>4</Position>
|
||||
<DataType>int|0s</DataType>
|
||||
</column>
|
||||
<column id="164" parent="22" name="sql">
|
||||
<column id="136" parent="17" name="sql">
|
||||
<Position>5</Position>
|
||||
<DataType>text|0s</DataType>
|
||||
</column>
|
||||
<column id="165" parent="23" name="name">
|
||||
<column id="137" parent="18" name="name">
|
||||
<Position>1</Position>
|
||||
</column>
|
||||
<column id="166" parent="23" name="seq">
|
||||
<column id="138" parent="18" name="seq">
|
||||
<Position>2</Position>
|
||||
</column>
|
||||
<column id="167" parent="24" name="id">
|
||||
<column id="139" parent="19" name="id">
|
||||
<Position>1</Position>
|
||||
<DataType>INTEGER|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
<SequenceIdentity>1</SequenceIdentity>
|
||||
</column>
|
||||
<column id="168" parent="24" name="entityName">
|
||||
<column id="140" parent="19" name="entityName">
|
||||
<Position>2</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="169" parent="24" name="entityId">
|
||||
<column id="141" parent="19" name="entityId">
|
||||
<Position>3</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="170" parent="24" name="sourceId">
|
||||
<column id="142" parent="19" name="sourceId">
|
||||
<Position>4</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<column id="171" parent="24" name="utcSyncDate">
|
||||
<column id="143" parent="19" name="utcSyncDate">
|
||||
<Position>5</Position>
|
||||
<DataType>TEXT|0s</DataType>
|
||||
<NotNull>1</NotNull>
|
||||
</column>
|
||||
<index id="172" parent="24" name="IDX_sync_entityName_entityId">
|
||||
<index id="144" parent="19" name="IDX_sync_entityName_entityId">
|
||||
<ColNames>entityName
|
||||
entityId</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
<Unique>1</Unique>
|
||||
</index>
|
||||
<index id="173" parent="24" name="IDX_sync_utcSyncDate">
|
||||
<index id="145" parent="19" name="IDX_sync_utcSyncDate">
|
||||
<ColNames>utcSyncDate</ColNames>
|
||||
<ColumnCollations></ColumnCollations>
|
||||
</index>
|
||||
<key id="174" parent="24">
|
||||
<key id="146" parent="19">
|
||||
<ColNames>id</ColNames>
|
||||
<Primary>1</Primary>
|
||||
</key>
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
|
||||
VERSION=`jq -r ".version" package.json`
|
||||
|
||||
sudo docker build -t zadam/trilium:latest -t zadam/trilium:$VERSION .
|
||||
sudo docker build -t zadam/trilium:$VERSION .
|
||||
@@ -14,6 +14,8 @@ rm node-v${NODE_VERSION}-linux-x64.tar.xz
|
||||
mv node-v${NODE_VERSION}-linux-x64 node
|
||||
|
||||
cp -r ../../node_modules/ ./
|
||||
cp -r ../../images/ ./
|
||||
cp -r ../../libraries/ ./
|
||||
cp -r ../../src/ ./
|
||||
cp -r ../../db/ ./
|
||||
cp -r ../../package.json ./
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
SCHEMA_FILE_PATH=db/schema.sql
|
||||
|
||||
sqlite3 ~/trilium-data/document.db .schema | grep -v "sqlite_sequence" | grep -v "note_fulltext_" > "$SCHEMA_FILE_PATH"
|
||||
sqlite3 ~/trilium-data/document.db .schema | grep -v "sqlite_sequence" > "$SCHEMA_FILE_PATH"
|
||||
|
||||
echo "DB schema exported to $SCHEMA_FILE_PATH"
|
||||
@@ -5,5 +5,8 @@ if [[ $# -eq 0 ]] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo docker push zadam/trilium:latest
|
||||
sudo docker push zadam/trilium:$1
|
||||
sudo docker push zadam/trilium:$1
|
||||
|
||||
if [[ $1 != *"beta"* ]]; then
|
||||
sudo docker push zadam/trilium:latest
|
||||
fi
|
||||
|
||||
BIN
Binary file not shown.
@@ -1 +0,0 @@
|
||||
CREATE VIRTUAL TABLE note_fulltext USING fts5(noteId UNINDEXED, title, titleHash UNINDEXED, content, contentHash UNINDEXED);
|
||||
|
||||
@@ -1,10 +1 @@
|
||||
const repository = require('../../src/services/repository');
|
||||
const noteFulltextService = require('../../src/services/note_fulltext');
|
||||
|
||||
module.exports = async () => {
|
||||
const notes = await repository.getEntities('SELECT * FROM notes WHERE isDeleted = 0 AND isProtected = 0');
|
||||
|
||||
for (const note of notes) {
|
||||
await noteFulltextService.updateNoteFulltext(note);
|
||||
}
|
||||
};
|
||||
module.exports = async () => {};
|
||||
@@ -0,0 +1,5 @@
|
||||
const syncTableService = require('../../src/services/sync_table');
|
||||
|
||||
module.exports = async () => {
|
||||
await syncTableService.fillAllSyncRows();
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS note_fulltext;
|
||||
@@ -1,5 +1,3 @@
|
||||
CREATE VIRTUAL TABLE note_fulltext USING fts5(noteId UNINDEXED, title, titleHash UNINDEXED, content, contentHash UNINDEXED)
|
||||
/* note_fulltext(noteId,title,titleHash,content,contentHash) */;
|
||||
CREATE TABLE IF NOT EXISTS "sync" (
|
||||
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
`entityName` TEXT NOT NULL,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
version: '2.1'
|
||||
services:
|
||||
trilium:
|
||||
build:
|
||||
context: .
|
||||
image: zadam/trilium
|
||||
restart: always
|
||||
environment:
|
||||
- TRILIUM_DATA_DIR=/data
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- trilium:/data
|
||||
|
||||
volumes:
|
||||
trilium:
|
||||
|
||||
@@ -394,7 +394,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line296">line 296</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line310">line 310</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -758,7 +758,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line184">line 184</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line198">line 198</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1044,7 +1044,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line197">line 197</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line211">line 211</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1224,7 +1224,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line145">line 145</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line159">line 159</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1423,7 +1423,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line135">line 135</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line149">line 149</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1523,7 +1523,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line301">line 301</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line315">line 315</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1981,7 +1981,7 @@ the backend.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line225">line 225</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line239">line 239</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2739,7 +2739,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line244">line 244</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line258">line 258</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3084,7 +3084,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line114">line 114</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line128">line 128</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3280,7 +3280,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line124">line 124</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line138">line 138</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3384,7 +3384,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line216">line 216</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line230">line 230</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3560,7 +3560,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line235">line 235</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line249">line 249</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3713,7 +3713,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line253">line 253</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line267">line 267</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3861,7 +3861,7 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line208">line 208</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line222">line 222</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3891,6 +3891,160 @@ if some action needs to happen on only one specific instance.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="searchForNote"><span class="type-signature"></span>searchForNote<span class="signature">(searchString)</span><span class="type-signature"> → {Promise.<(<a href="Note.html">Note</a>|null)>}</span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">
|
||||
This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
"@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>searchString</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">string</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last"></td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line114">line 114</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Returns:</h5>
|
||||
|
||||
|
||||
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
Type
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<span class="param-type">Promise.<(<a href="Note.html">Note</a>|null)></span>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4023,10 +4177,6 @@ if some action needs to happen on only one specific instance.
|
||||
<h5>Returns:</h5>
|
||||
|
||||
|
||||
<div class="param-desc">
|
||||
$
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<dl>
|
||||
@@ -4231,7 +4381,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line273">line 273</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line287">line 287</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4362,7 +4512,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line260">line 260</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line274">line 274</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4576,7 +4726,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line157">line 157</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line171">line 171</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4733,7 +4883,7 @@ transactional by default.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line286">line 286</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line300">line 300</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
+52
-52
@@ -396,7 +396,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line36">line 36</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line35">line 35</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line326">line 326</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line345">line 345</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -746,7 +746,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line195">line 195</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line214">line 214</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line337">line 337</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line356">line 356</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1026,7 +1026,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line624">line 624</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line643">line 643</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1126,7 +1126,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line652">line 652</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line671">line 671</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1230,7 +1230,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line638">line 638</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line657">line 657</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1334,7 +1334,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line66">line 66</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line74">line 74</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1434,7 +1434,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line513">line 513</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line532">line 532</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1665,7 +1665,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line536">line 536</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line555">line 555</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -1861,7 +1861,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line574">line 574</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line593">line 593</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2057,7 +2057,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line583">line 583</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line602">line 602</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2157,7 +2157,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line90">line 90</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line109">line 109</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2306,7 +2306,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line424">line 424</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line443">line 443</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2471,7 +2471,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line220">line 220</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line239">line 239</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2636,7 +2636,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line212">line 212</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line231">line 231</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2789,7 +2789,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line436">line 436</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line455">line 455</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -2897,7 +2897,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line599">line 599</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line618">line 618</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3001,7 +3001,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line617">line 617</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line636">line 636</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3101,7 +3101,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line180">line 180</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line199">line 199</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3205,7 +3205,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line664">line 664</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line683">line 683</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3358,7 +3358,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line430">line 430</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line449">line 449</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3523,7 +3523,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line236">line 236</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line255">line 255</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3688,7 +3688,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line228">line 228</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line247">line 247</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3841,7 +3841,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line448">line 448</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line467">line 467</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -3997,7 +3997,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line442">line 442</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line461">line 461</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4105,7 +4105,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line590">line 590</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line609">line 609</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4205,7 +4205,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line161">line 161</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line180">line 180</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4313,7 +4313,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line608">line 608</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line627">line 627</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4413,7 +4413,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line187">line 187</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line206">line 206</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4589,7 +4589,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line317">line 317</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line336">line 336</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4693,7 +4693,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line631">line 631</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line650">line 650</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4846,7 +4846,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line412">line 412</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line431">line 431</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -4999,7 +4999,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line418">line 418</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line437">line 437</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5108,7 +5108,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line244">line 244</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line263">line 263</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5190,7 +5190,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line149">line 149</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line168">line 168</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5294,7 +5294,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line141">line 141</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line160">line 160</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5398,7 +5398,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line136">line 136</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line155">line 155</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5502,7 +5502,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line131">line 131</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line150">line 150</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5606,7 +5606,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line154">line 154</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line173">line 173</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5710,7 +5710,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line249">line 249</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line268">line 268</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -5937,7 +5937,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line395">line 395</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line414">line 414</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6133,7 +6133,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line499">line 499</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line518">line 518</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6329,7 +6329,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line508">line 508</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line527">line 527</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6556,7 +6556,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line369">line 369</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line388">line 388</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6656,7 +6656,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line97">line 97</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line116">line 116</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6756,7 +6756,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line126">line 126</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line145">line 145</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -6952,7 +6952,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line481">line 481</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line500">line 500</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7148,7 +7148,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line490">line 490</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line509">line 509</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7406,7 +7406,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line352">line 352</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line371">line 371</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7633,7 +7633,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line462">line 462</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line481">line 481</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -7860,7 +7860,7 @@ Cache is note instance scoped.
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line472">line 472</a>
|
||||
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line491">line 491</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ const repository = require('../services/repository');
|
||||
const sql = require('../services/sql');
|
||||
const utils = require('../services/utils');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
const noteFulltextService = require('../services/note_fulltext');
|
||||
const syncTableService = require('../services/sync_table');
|
||||
|
||||
const LABEL = 'label';
|
||||
@@ -90,10 +89,30 @@ class Note extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note content has quite special handling - it's not a separate entity, but a lazily loaded
|
||||
* part of Note entity with it's own sync. Reasons behind this hybrid design has been:
|
||||
*
|
||||
* - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search
|
||||
* - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and sync rows)
|
||||
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
|
||||
*/
|
||||
|
||||
/** @returns {Promise<*>} */
|
||||
async getContent() {
|
||||
async getContent(silentNotFoundError = false) {
|
||||
if (this.content === undefined) {
|
||||
this.content = await sql.getValue(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
|
||||
const res = await sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]);
|
||||
|
||||
if (!res) {
|
||||
if (silentNotFoundError) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
throw new Error("Cannot find note content for noteId=" + this.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
this.content = res.content;
|
||||
|
||||
if (this.isProtected) {
|
||||
if (this.isContentAvailable) {
|
||||
@@ -123,6 +142,10 @@ class Note extends Entity {
|
||||
|
||||
/** @returns {Promise} */
|
||||
async setContent(content) {
|
||||
// force updating note itself so that dateChanged is represented correctly even for the content
|
||||
this.forcedChange = true;
|
||||
await this.save();
|
||||
|
||||
this.content = content;
|
||||
|
||||
const pojo = {
|
||||
@@ -144,10 +167,6 @@ class Note extends Entity {
|
||||
await sql.upsert("note_contents", "noteId", pojo);
|
||||
|
||||
await syncTableService.addNoteContentSync(this.noteId);
|
||||
|
||||
this.forcedChange = true;
|
||||
|
||||
await this.save();
|
||||
}
|
||||
|
||||
/** @returns {Promise} */
|
||||
@@ -736,10 +755,7 @@ class Note extends Entity {
|
||||
delete pojo.isContentAvailable;
|
||||
delete pojo.__attributeCache;
|
||||
delete pojo.content;
|
||||
}
|
||||
|
||||
async afterSaving() {
|
||||
noteFulltextService.triggerNoteFulltextUpdate(this.noteId);
|
||||
delete pojo.contentHash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line159">line 159</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line173">line 173</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line166">line 166</a>
|
||||
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line180">line 180</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -127,10 +127,24 @@ function BackendScriptApi(currentNote, apiParams) {
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns ${Promise<Note[]>}
|
||||
* @returns {Promise<Note[]>}
|
||||
*/
|
||||
this.searchForNotes = searchService.searchForNotes;
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<Note|null>}
|
||||
*/
|
||||
this.searchForNote = async searchString => {
|
||||
const notes = await searchService.searchForNotes(searchString);
|
||||
|
||||
return notes.length > 0 ? notes[0] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves notes with given label name & value
|
||||
*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -199,7 +199,7 @@
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="utcDateCreated"><span class="type-signature"></span>utcDateCreated<span class="type-signature"></span></h4>
|
||||
<h4 class="name" id="dateCreated"><span class="type-signature"></span>dateCreated<span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="utcDateModified"><span class="type-signature"></span>utcDateModified<span class="type-signature"></span></h4>
|
||||
<h4 class="name" id="dateModified"><span class="type-signature"></span>dateModified<span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
@@ -314,6 +314,122 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="utcDateCreated"><span class="type-signature"></span>utcDateCreated<span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note_full.js.html">entities/note_full.js</a>, <a href="entities_note_full.js.html#line20">line 20</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="name" id="utcDateModified"><span class="type-signature"></span>utcDateModified<span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="entities_note_full.js.html">entities/note_full.js</a>, <a href="entities_note_full.js.html#line23">line 23</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,12 @@ class NoteFull extends NoteShort {
|
||||
/** @param {string} */
|
||||
this.content = row.content;
|
||||
|
||||
/** @param {string} */
|
||||
this.dateCreated = row.dateCreated;
|
||||
|
||||
/** @param {string} */
|
||||
this.dateModified = row.dateModified;
|
||||
|
||||
/** @param {string} */
|
||||
this.utcDateCreated = row.utcDateCreated;
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line49">line 49</a>
|
||||
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line53">line 53</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import noteDetailService from './note_detail.js';
|
||||
import noteTypeService from './note_type.js';
|
||||
import noteTooltipService from './note_tooltip.js';
|
||||
import protectedSessionService from'./protected_session.js';
|
||||
import dateNotesService from'./date_notes.js';
|
||||
|
||||
/**
|
||||
* This is the main frontend API interface for scripts. It's published in the local "api" object.
|
||||
@@ -53,6 +54,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
/** @property {object|null} entity whose event triggered this execution */
|
||||
this.originEntity = originEntity;
|
||||
|
||||
// to keep consistency with backend API
|
||||
this.dayjs = dayjs;
|
||||
|
||||
/**
|
||||
* Activates note in the tree and in the note detail.
|
||||
*
|
||||
@@ -159,6 +163,46 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<NoteShort[]>}
|
||||
*/
|
||||
this.searchForNotes = async searchString => {
|
||||
const noteIds = await this.runOnServer(async searchString => {
|
||||
const notes = await api.searchForNotes(searchString);
|
||||
|
||||
return notes.map(note => note.noteId);
|
||||
}, [searchString]);
|
||||
|
||||
return await treeCache.getNotes(noteIds);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<NoteShort|null>}
|
||||
*/
|
||||
this.searchForNote = async searchString => {
|
||||
const notes = await this.searchForNotes(searchString);
|
||||
|
||||
return notes.length > 0 ? notes[0] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns note by given noteId. If note is missing from cache, it's loaded.
|
||||
**
|
||||
* @param {string} noteId
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getNote = async noteId => await treeCache.getNote(noteId);
|
||||
|
||||
/**
|
||||
* Returns list of notes. If note is missing from cache, it's loaded.
|
||||
*
|
||||
@@ -171,6 +215,18 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
*/
|
||||
this.getNotes = async (noteIds, silentNotFoundError = false) => await treeCache.getNotes(noteIds, silentNotFoundError);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadChildren = async noteId => await treeCache.reloadChildren(noteId);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadParents = async noteId => await treeCache.reloadParents(noteId);
|
||||
|
||||
/**
|
||||
* Instance name identifies particular Trilium instance. It can be useful for scripts
|
||||
* if some action needs to happen on only one specific instance.
|
||||
@@ -238,6 +294,12 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
*/
|
||||
this.getActiveNote = noteDetailService.getActiveNote;
|
||||
|
||||
/**
|
||||
* @method
|
||||
* @returns {Promise<string>} returns note path of active note
|
||||
*/
|
||||
this.getActiveNotePath = treeService.getActiveNotePath;
|
||||
|
||||
/**
|
||||
* This method checks whether user navigated away from the note from which the scripts has been started.
|
||||
* This is necessary because script execution is async and by the time it is finished, the user might have
|
||||
@@ -285,6 +347,41 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
* @method
|
||||
*/
|
||||
this.protectActiveNote = protectedSessionService.protectNoteAndSendToServer;
|
||||
|
||||
/**
|
||||
* Returns date-note for today. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getTodayNote = dateNotesService.getTodayNote;
|
||||
|
||||
/**
|
||||
* Returns date-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} date - e.g. "2019-04-29"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getDateNote = dateNotesService.getDateNote;
|
||||
|
||||
/**
|
||||
* Returns month-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} month - e.g. "2019-04"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getMonthNote = dateNotesService.getMonthNote;
|
||||
|
||||
/**
|
||||
* Returns year-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} year - e.g. "2019"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getYearNote = dateNotesService.getYearNote;
|
||||
}
|
||||
|
||||
export default FrontendScriptApi;</code></pre>
|
||||
|
||||
+3
-6
@@ -30,6 +30,8 @@ function onClosed() {
|
||||
}
|
||||
|
||||
async function createMainWindow() {
|
||||
await sqlInit.dbConnection;
|
||||
|
||||
// if schema doesn't exist -> setup process
|
||||
// if schema exists, then we need to wait until the migration process is finished
|
||||
if (await sqlInit.schemaExists()) {
|
||||
@@ -95,15 +97,10 @@ app.on('ready', async () => {
|
||||
mainWindow = await createMainWindow();
|
||||
|
||||
const result = globalShortcut.register('CommandOrControl+Alt+P', cls.wrap(async () => {
|
||||
const dateNoteService = require('./src/services/date_notes');
|
||||
const dateUtils = require('./src/services/date_utils');
|
||||
|
||||
const parentNote = await dateNoteService.getDateNote(dateUtils.localNowDate());
|
||||
|
||||
// window may be hidden / not in focus
|
||||
mainWindow.focus();
|
||||
|
||||
mainWindow.webContents.send('create-day-sub-note', parentNote.noteId);
|
||||
mainWindow.webContents.send('create-day-sub-note');
|
||||
}));
|
||||
|
||||
if (!result) {
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Generated
+9
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "trilium",
|
||||
"version": "0.30.7",
|
||||
"version": "0.31.1-beta",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -2164,9 +2164,9 @@
|
||||
"integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI="
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.8.11",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.11.tgz",
|
||||
"integrity": "sha512-eBvWmKn52ax/TBYg7f+tzzqARPl0D0/NUmf5QrZ0Pp+/vFoTP3Q7y4t6p438+5NPN+t8y8Sps3Ed34OV8sNFBQ=="
|
||||
"version": "1.8.12",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.12.tgz",
|
||||
"integrity": "sha512-7keChCzzjU68sYJpk7kEI1Q9qbJyscyiW0STwEhqDFt+2js9pA/BSzmYE4PRxcMMoUMxNeY0TEMZHqV/JBR4OA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
@@ -3222,6 +3222,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"electron-find": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/electron-find/-/electron-find-1.0.5.tgz",
|
||||
"integrity": "sha512-LmFp6wolElQwlnjFR4jo7cARUZq+siR0sCS5Qp5Jywz2puM5OJzjRRyUEHCMi9Pm7xLupVYjwNVF1JojVQ0QPA=="
|
||||
},
|
||||
"electron-in-page-search": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-in-page-search/-/electron-in-page-search-1.3.2.tgz",
|
||||
|
||||
+3
-2
@@ -2,7 +2,7 @@
|
||||
"name": "trilium",
|
||||
"productName": "Trilium Notes",
|
||||
"description": "Trilium Notes",
|
||||
"version": "0.31.0-beta",
|
||||
"version": "0.31.2-beta",
|
||||
"license": "AGPL-3.0-only",
|
||||
"main": "electron.js",
|
||||
"bin": {
|
||||
@@ -28,11 +28,12 @@
|
||||
"commonmark": "0.28.1",
|
||||
"cookie-parser": "1.4.4",
|
||||
"csurf": "1.9.0",
|
||||
"dayjs": "1.8.11",
|
||||
"dayjs": "1.8.12",
|
||||
"debug": "4.1.1",
|
||||
"ejs": "2.6.1",
|
||||
"electron-debug": "2.1.0",
|
||||
"electron-dl": "1.13.0",
|
||||
"electron-find": "1.0.5",
|
||||
"electron-in-page-search": "1.3.2",
|
||||
"electron-window-state": "5.0.3",
|
||||
"express": "4.16.4",
|
||||
|
||||
+14
-11
@@ -7,7 +7,6 @@ const repository = require('../services/repository');
|
||||
const sql = require('../services/sql');
|
||||
const utils = require('../services/utils');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
const noteFulltextService = require('../services/note_fulltext');
|
||||
const syncTableService = require('../services/sync_table');
|
||||
|
||||
const LABEL = 'label';
|
||||
@@ -72,12 +71,20 @@ class Note extends Entity {
|
||||
*/
|
||||
|
||||
/** @returns {Promise<*>} */
|
||||
async getContent() {
|
||||
async getContent(silentNotFoundError = false) {
|
||||
if (this.content === undefined) {
|
||||
const res = await sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]);
|
||||
|
||||
if (!res) {
|
||||
if (silentNotFoundError) {
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
throw new Error("Cannot find note content for noteId=" + this.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
this.content = res.content;
|
||||
this.contentHash = res.contentHash; // used only for note_fulltext consistency check
|
||||
|
||||
if (this.isProtected) {
|
||||
if (this.isContentAvailable) {
|
||||
@@ -107,6 +114,10 @@ class Note extends Entity {
|
||||
|
||||
/** @returns {Promise} */
|
||||
async setContent(content) {
|
||||
// force updating note itself so that dateChanged is represented correctly even for the content
|
||||
this.forcedChange = true;
|
||||
await this.save();
|
||||
|
||||
this.content = content;
|
||||
|
||||
const pojo = {
|
||||
@@ -128,10 +139,6 @@ class Note extends Entity {
|
||||
await sql.upsert("note_contents", "noteId", pojo);
|
||||
|
||||
await syncTableService.addNoteContentSync(this.noteId);
|
||||
|
||||
this.forcedChange = true;
|
||||
|
||||
await this.save();
|
||||
}
|
||||
|
||||
/** @returns {Promise} */
|
||||
@@ -722,10 +729,6 @@ class Note extends Entity {
|
||||
delete pojo.content;
|
||||
delete pojo.contentHash;
|
||||
}
|
||||
|
||||
async afterSaving() {
|
||||
noteFulltextService.triggerNoteFulltextUpdate(this.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Note;
|
||||
@@ -39,6 +39,7 @@ import linkService from './services/link.js';
|
||||
import noteAutocompleteService from './services/note_autocomplete.js';
|
||||
import macInit from './services/mac_init.js';
|
||||
import cssLoader from './services/css_loader.js';
|
||||
import dateNoteService from './services/date_notes.js';
|
||||
|
||||
// required for CKEditor image upload plugin
|
||||
window.glob.getActiveNode = treeService.getActiveNode;
|
||||
@@ -114,20 +115,14 @@ $("body").on("click", "a.external", function () {
|
||||
});
|
||||
|
||||
if (utils.isElectron()) {
|
||||
require('electron').ipcRenderer.on('create-day-sub-note', async function(event, parentNoteId) {
|
||||
await treeService.activateNote(parentNoteId);
|
||||
require('electron').ipcRenderer.on('create-day-sub-note', async function(event) {
|
||||
const todayNote = await dateNoteService.getTodayNote();
|
||||
const node = await treeService.expandToNote(todayNote.noteId);
|
||||
|
||||
setTimeout(async () => {
|
||||
const parentNode = treeService.getActiveNode();
|
||||
|
||||
const {note} = await treeService.createNote(parentNode, parentNode.data.noteId, 'into', {
|
||||
type: "text",
|
||||
isProtected: parentNode.data.isProtected
|
||||
});
|
||||
|
||||
await treeService.activateNote(note.noteId);
|
||||
|
||||
}, 500);
|
||||
await treeService.createNote(node, todayNote.noteId, 'into', {
|
||||
type: "text",
|
||||
isProtected: node.data.isProtected
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ $("#note-menu-button").click(async e => {
|
||||
enabled: isNotRoot && parentNote.type !== 'search' }
|
||||
];
|
||||
|
||||
contextMenuWidget.initContextMenu(e, items, (event, cmd) => {
|
||||
contextMenuWidget.initContextMenu(e, items, async (event, cmd) => {
|
||||
if (cmd === "insertNoteAfter") {
|
||||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = treeUtils.getParentProtectedStatus(node);
|
||||
const isProtected = await treeUtils.getParentProtectedStatus(node);
|
||||
|
||||
treeService.createNote(node, parentNoteId, 'after', { isProtected: isProtected });
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ import utils from './utils.js';
|
||||
import server from './server.js';
|
||||
import infoService from "./info.js";
|
||||
import treeCache from "./tree_cache.js";
|
||||
import treeBuilder from "./tree_builder.js";
|
||||
import hoistedNoteService from "./hoisted_note.js";
|
||||
|
||||
async function moveBeforeNode(nodesToMove, beforeNode) {
|
||||
nodesToMove = filterRootNote(nodesToMove);
|
||||
nodesToMove = await filterRootNote(nodesToMove);
|
||||
|
||||
if (beforeNode.data.noteId === 'root') {
|
||||
alert('Cannot move notes before root note.');
|
||||
@@ -30,9 +30,9 @@ async function moveBeforeNode(nodesToMove, beforeNode) {
|
||||
}
|
||||
|
||||
async function moveAfterNode(nodesToMove, afterNode) {
|
||||
nodesToMove = filterRootNote(nodesToMove);
|
||||
nodesToMove = await filterRootNote(nodesToMove);
|
||||
|
||||
if (afterNode.data.noteId === 'root') {
|
||||
if (afterNode.data.noteId === 'root' || afterNode.data.noteId === await hoistedNoteService.getHoistedNoteId()) {
|
||||
alert('Cannot move notes after root note.');
|
||||
return;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ async function moveAfterNode(nodesToMove, afterNode) {
|
||||
}
|
||||
|
||||
async function moveToNode(nodesToMove, toNode) {
|
||||
nodesToMove = filterRootNote(nodesToMove);
|
||||
nodesToMove = await filterRootNote(nodesToMove);
|
||||
|
||||
for (const nodeToMove of nodesToMove) {
|
||||
const resp = await server.put('branches/' + nodeToMove.data.branchId + '/move-to/' + toNode.data.noteId);
|
||||
@@ -77,13 +77,8 @@ async function moveToNode(nodesToMove, toNode) {
|
||||
}
|
||||
}
|
||||
|
||||
function filterRootNote(nodes) {
|
||||
// some operations are not possible on root notes
|
||||
return nodes.filter(node => node.data.noteId !== 'root');
|
||||
}
|
||||
|
||||
async function deleteNodes(nodes) {
|
||||
nodes = filterRootNote(nodes);
|
||||
nodes = await filterRootNote(nodes);
|
||||
|
||||
if (nodes.length === 0 || !confirm('Are you sure you want to delete select note(s) and all the sub-notes?')) {
|
||||
return;
|
||||
@@ -93,8 +88,6 @@ async function deleteNodes(nodes) {
|
||||
await server.remove('branches/' + node.data.branchId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// following code assumes that nodes contain only top-most selected nodes - getSelectedNodes has been
|
||||
// called with stopOnParent=true
|
||||
let next = nodes[nodes.length - 1].getNextSibling();
|
||||
@@ -103,7 +96,7 @@ async function deleteNodes(nodes) {
|
||||
next = nodes[0].getPrevSibling();
|
||||
}
|
||||
|
||||
if (!next && !utils.isTopLevelNode(nodes[0])) {
|
||||
if (!next && !hoistedNoteService.isTopLevelNode(nodes[0])) {
|
||||
next = nodes[0].getParent();
|
||||
}
|
||||
|
||||
@@ -130,7 +123,7 @@ async function deleteNodes(nodes) {
|
||||
}
|
||||
|
||||
async function moveNodeUpInHierarchy(node) {
|
||||
if (utils.isRootNode(node) || utils.isTopLevelNode(node)) {
|
||||
if (await hoistedNoteService.isRootNode(node) || await hoistedNoteService.isTopLevelNode(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,7 +134,7 @@ async function moveNodeUpInHierarchy(node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!utils.isTopLevelNode(node) && node.getParent().getChildren().length <= 1) {
|
||||
if (!hoistedNoteService.isTopLevelNode(node) && node.getParent().getChildren().length <= 1) {
|
||||
node.getParent().folder = false;
|
||||
node.getParent().renderTitle();
|
||||
}
|
||||
@@ -203,6 +196,14 @@ async function changeNode(func, node, beforeNoteId = null, afterNoteId = null) {
|
||||
}
|
||||
}
|
||||
|
||||
async function filterRootNote(nodes) {
|
||||
const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
|
||||
|
||||
return nodes.filter(node =>
|
||||
node.data.noteId !== 'root'
|
||||
&& node.data.noteId !== hoistedNoteId);
|
||||
}
|
||||
|
||||
export default {
|
||||
moveBeforeNode,
|
||||
moveAfterNode,
|
||||
|
||||
@@ -42,7 +42,7 @@ function initContextMenu(event, contextMenuItems, selectContextMenuItem) {
|
||||
});
|
||||
|
||||
if (item.enabled !== undefined && !item.enabled) {
|
||||
$link.addClass("disabled");
|
||||
$item.addClass("disabled");
|
||||
}
|
||||
|
||||
if (item.items) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import treeCache from "./tree_cache.js";
|
||||
import server from "./server.js";
|
||||
|
||||
/** @return {NoteShort} */
|
||||
async function getTodayNote() {
|
||||
return await getDateNote(dayjs().format("YYYY-MM-DD"));
|
||||
}
|
||||
|
||||
/** @return {NoteShort} */
|
||||
async function getDateNote(date) {
|
||||
const note = await server.get('date-notes/date/' + date);
|
||||
|
||||
await treeCache.reloadParents(note.noteId);
|
||||
|
||||
return await treeCache.getNote(note.noteId);
|
||||
}
|
||||
|
||||
/** @return {NoteShort} */
|
||||
async function getMonthNote(month) {
|
||||
const note = await server.get('date-notes/month/' + month);
|
||||
|
||||
await treeCache.reloadParents(note.noteId);
|
||||
|
||||
return await treeCache.getNote(note.noteId);
|
||||
}
|
||||
|
||||
/** @return {NoteShort} */
|
||||
async function getYearNote(year) {
|
||||
const note = await server.get('date-notes/year/' + year);
|
||||
|
||||
await treeCache.reloadParents(note.noteId);
|
||||
|
||||
return await treeCache.getNote(note.noteId);
|
||||
}
|
||||
|
||||
export default {
|
||||
getTodayNote,
|
||||
getDateNote,
|
||||
getMonthNote,
|
||||
getYearNote
|
||||
}
|
||||
@@ -103,6 +103,7 @@ function registerEntrypoints() {
|
||||
|
||||
utils.bindShortcut('f5', utils.reloadApp);
|
||||
|
||||
$("#reload-frontend-button").click(utils.reloadApp);
|
||||
utils.bindShortcut('ctrl+r', utils.reloadApp);
|
||||
|
||||
$("#open-dev-tools-button").toggle(utils.isElectron());
|
||||
@@ -118,27 +119,33 @@ function registerEntrypoints() {
|
||||
$("#open-dev-tools-button").click(openDevTools);
|
||||
}
|
||||
|
||||
function openInPageSearch() {
|
||||
if (utils.isElectron()) {
|
||||
const $searchWindowWebview = $(".electron-in-page-search-window");
|
||||
$searchWindowWebview.show();
|
||||
let findInPage;
|
||||
|
||||
const searchInPage = require('electron-in-page-search').default;
|
||||
const {remote} = require('electron');
|
||||
if (utils.isElectron()) {
|
||||
const { remote } = require('electron');
|
||||
const { FindInPage } = require('electron-find');
|
||||
|
||||
const inPageSearch = searchInPage(remote.getCurrentWebContents(), {
|
||||
searchWindowWebview: $searchWindowWebview[0],
|
||||
//openDevToolsOfSearchWindow: true,
|
||||
customCssPath: '/libraries/electron-in-page-search/default-style.css'
|
||||
});
|
||||
|
||||
inPageSearch.openSearchWindow();
|
||||
|
||||
return false;
|
||||
}
|
||||
findInPage = new FindInPage(remote.getCurrentWebContents(), {
|
||||
offsetTop: 10,
|
||||
offsetRight: 10,
|
||||
boxBgColor: 'var(--main-background-color)',
|
||||
boxShadowColor: '#000',
|
||||
inputColor: 'var(--input-text-color)',
|
||||
inputBgColor: 'var(--input-background-color)',
|
||||
inputFocusColor: '#555',
|
||||
textColor: 'var(--main-text-color)',
|
||||
textHoverBgColor: '#555',
|
||||
caseSelectedColor: 'var(--main-border-color)'
|
||||
});
|
||||
}
|
||||
|
||||
utils.bindShortcut('ctrl+f', openInPageSearch);
|
||||
if (utils.isElectron()) {
|
||||
utils.bindShortcut('ctrl+f', () => {
|
||||
findInPage.openFindWindow();
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME: do we really need these at this point?
|
||||
utils.bindShortcut("ctrl+shift+up", () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import noteDetailService from './note_detail.js';
|
||||
import noteTypeService from './note_type.js';
|
||||
import noteTooltipService from './note_tooltip.js';
|
||||
import protectedSessionService from'./protected_session.js';
|
||||
import dateNotesService from'./date_notes.js';
|
||||
|
||||
/**
|
||||
* This is the main frontend API interface for scripts. It's published in the local "api" object.
|
||||
@@ -25,6 +26,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
/** @property {object|null} entity whose event triggered this execution */
|
||||
this.originEntity = originEntity;
|
||||
|
||||
// to keep consistency with backend API
|
||||
this.dayjs = dayjs;
|
||||
|
||||
/**
|
||||
* Activates note in the tree and in the note detail.
|
||||
*
|
||||
@@ -131,6 +135,46 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<NoteShort[]>}
|
||||
*/
|
||||
this.searchForNotes = async searchString => {
|
||||
const noteIds = await this.runOnServer(async searchString => {
|
||||
const notes = await api.searchForNotes(searchString);
|
||||
|
||||
return notes.map(note => note.noteId);
|
||||
}, [searchString]);
|
||||
|
||||
return await treeCache.getNotes(noteIds);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<NoteShort|null>}
|
||||
*/
|
||||
this.searchForNote = async searchString => {
|
||||
const notes = await this.searchForNotes(searchString);
|
||||
|
||||
return notes.length > 0 ? notes[0] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns note by given noteId. If note is missing from cache, it's loaded.
|
||||
**
|
||||
* @param {string} noteId
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getNote = async noteId => await treeCache.getNote(noteId);
|
||||
|
||||
/**
|
||||
* Returns list of notes. If note is missing from cache, it's loaded.
|
||||
*
|
||||
@@ -143,6 +187,18 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
*/
|
||||
this.getNotes = async (noteIds, silentNotFoundError = false) => await treeCache.getNotes(noteIds, silentNotFoundError);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadChildren = async noteId => await treeCache.reloadChildren(noteId);
|
||||
|
||||
/**
|
||||
* @param {string} noteId
|
||||
* @method
|
||||
*/
|
||||
this.reloadParents = async noteId => await treeCache.reloadParents(noteId);
|
||||
|
||||
/**
|
||||
* Instance name identifies particular Trilium instance. It can be useful for scripts
|
||||
* if some action needs to happen on only one specific instance.
|
||||
@@ -210,6 +266,12 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
*/
|
||||
this.getActiveNote = noteDetailService.getActiveNote;
|
||||
|
||||
/**
|
||||
* @method
|
||||
* @returns {Promise<string>} returns note path of active note
|
||||
*/
|
||||
this.getActiveNotePath = treeService.getActiveNotePath;
|
||||
|
||||
/**
|
||||
* This method checks whether user navigated away from the note from which the scripts has been started.
|
||||
* This is necessary because script execution is async and by the time it is finished, the user might have
|
||||
@@ -257,6 +319,41 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null) {
|
||||
* @method
|
||||
*/
|
||||
this.protectActiveNote = protectedSessionService.protectNoteAndSendToServer;
|
||||
|
||||
/**
|
||||
* Returns date-note for today. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getTodayNote = dateNotesService.getTodayNote;
|
||||
|
||||
/**
|
||||
* Returns date-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} date - e.g. "2019-04-29"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getDateNote = dateNotesService.getDateNote;
|
||||
|
||||
/**
|
||||
* Returns month-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} month - e.g. "2019-04"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getMonthNote = dateNotesService.getMonthNote;
|
||||
|
||||
/**
|
||||
* Returns year-note. If it doesn't exist, it is automatically created.
|
||||
*
|
||||
* @method
|
||||
* @param {string} year - e.g. "2019"
|
||||
* @return {Promise<NoteShort>}
|
||||
*/
|
||||
this.getYearNote = dateNotesService.getYearNote;
|
||||
}
|
||||
|
||||
export default FrontendScriptApi;
|
||||
@@ -26,8 +26,20 @@ async function unhoist() {
|
||||
await setHoistedNoteId('root');
|
||||
}
|
||||
|
||||
async function isTopLevelNode(node) {
|
||||
return await isRootNode(node.getParent());
|
||||
}
|
||||
|
||||
async function isRootNode(node) {
|
||||
// even though check for 'root' should not be necessary, we keep it just in case
|
||||
return node.data.noteId === "root"
|
||||
|| node.data.noteId === await getHoistedNoteId();
|
||||
}
|
||||
|
||||
export default {
|
||||
getHoistedNoteId,
|
||||
setHoistedNoteId,
|
||||
unhoist
|
||||
unhoist,
|
||||
isTopLevelNode,
|
||||
isRootNode
|
||||
}
|
||||
@@ -270,7 +270,7 @@ async function showChildrenOverview() {
|
||||
|
||||
$childrenOverview.empty();
|
||||
|
||||
const notePath = treeService.getActiveNotePath();
|
||||
const notePath = await treeService.getActiveNotePath();
|
||||
|
||||
for (const childBranch of await note.getChildBranches()) {
|
||||
const link = $('<a>', {
|
||||
|
||||
@@ -34,6 +34,9 @@ async function show() {
|
||||
else {
|
||||
$previewRow.hide();
|
||||
}
|
||||
|
||||
// open doesn't work for protected notes since it works through browser which isn't in protected session
|
||||
$openButton.toggle(!activeNote.isProtected);
|
||||
}
|
||||
|
||||
$downloadButton.click(() => utils.download(getFileUrl()));
|
||||
@@ -51,7 +54,7 @@ $openButton.click(() => {
|
||||
|
||||
function getFileUrl() {
|
||||
// electron needs absolute URL so we extract current host, port, protocol
|
||||
return utils.getHost() + "/api/notes/" + noteDetailService.getActiveNoteId();
|
||||
return utils.getHost() + "/api/notes/" + noteDetailService.getActiveNoteId() + "/download";
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@@ -7,8 +7,8 @@ function setupGlobalTooltip() {
|
||||
$(document).on("mouseenter", "a", mouseEnterHandler);
|
||||
$(document).on("mouseleave", "a", mouseLeaveHandler);
|
||||
|
||||
// close any tooltip after click, this fixes the problem that sometimes tooltips remained on the screen
|
||||
//$(document).on("click", () => $('.tooltip').remove());
|
||||
// close any note tooltip after click, this fixes the problem that sometimes tooltips remained on the screen
|
||||
$(document).on("click", () => $('.note-tooltip').remove());
|
||||
}
|
||||
|
||||
function setupElementTooltip($el) {
|
||||
@@ -58,7 +58,8 @@ async function mouseEnterHandler() {
|
||||
trigger: 'manual',
|
||||
boundary: 'window',
|
||||
title: html,
|
||||
html: true
|
||||
html: true,
|
||||
template: '<div class="tooltip note-tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>'
|
||||
});
|
||||
|
||||
$(this).tooltip('show');
|
||||
|
||||
@@ -80,12 +80,17 @@ async function doSearch(searchText) {
|
||||
return;
|
||||
}
|
||||
|
||||
const results = await server.get('search/' + encodeURIComponent(searchText));
|
||||
const response = await server.get('search/' + encodeURIComponent(searchText));
|
||||
|
||||
if (!response.success) {
|
||||
infoService.showError("Search failed.", 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
$searchResultsInner.empty();
|
||||
$searchResults.show();
|
||||
|
||||
for (const result of results) {
|
||||
for (const result of response.results) {
|
||||
const link = $('<a>', {
|
||||
href: 'javascript:',
|
||||
text: result.title
|
||||
|
||||
@@ -39,10 +39,8 @@ function getActiveNode() {
|
||||
return $tree.fancytree("getActiveNode");
|
||||
}
|
||||
|
||||
function getActiveNotePath() {
|
||||
const node = getActiveNode();
|
||||
|
||||
return treeUtils.getNotePath(node);
|
||||
async function getActiveNotePath() {
|
||||
return getHashValueFromAddress();
|
||||
}
|
||||
|
||||
async function getNodesByBranchId(branchId) {
|
||||
@@ -110,18 +108,13 @@ async function expandToNote(notePath, expandOpts) {
|
||||
let node = getNode(childNoteId, parentNoteId);
|
||||
|
||||
if (!node && parentNoteId) {
|
||||
const parents = getNodesByNoteId(parentNoteId);
|
||||
|
||||
for (const parent of parents) {
|
||||
// force load parents. This is useful when fancytree doesn't contain recently created notes yet.
|
||||
await parent.load(true);
|
||||
}
|
||||
await reloadNote(parentNoteId);
|
||||
|
||||
node = getNode(childNoteId, parentNoteId);
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
console.error(`Can't find node for noteId=${childNoteId} with parentNoteId=${parentNoteId}`);
|
||||
console.error(`Can't find node for noteId=${childNoteId} with parentNoteId=${parentNoteId} and hoistedNoteId=${hoistedNoteId}`);
|
||||
}
|
||||
|
||||
if (childNoteId === noteId) {
|
||||
@@ -330,16 +323,16 @@ async function setExpandedToServer(branchId, isExpanded) {
|
||||
function addRecentNote(branchId, notePath) {
|
||||
setTimeout(async () => {
|
||||
// we include the note into recent list only if the user stayed on the note at least 5 seconds
|
||||
if (notePath && notePath === getActiveNotePath()) {
|
||||
if (notePath && notePath === await getActiveNotePath()) {
|
||||
await server.post('recent-notes', { branchId, notePath });
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
function setCurrentNotePathToHash(node) {
|
||||
async function setCurrentNotePathToHash(node) {
|
||||
utils.assertArguments(node);
|
||||
|
||||
const activeNotePath = treeUtils.getNotePath(node);
|
||||
const activeNotePath = await treeUtils.getNotePath(node);
|
||||
const currentBranchId = node.data.branchId;
|
||||
|
||||
document.location.hash = activeNotePath;
|
||||
@@ -371,20 +364,26 @@ async function treeInitialized() {
|
||||
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(startNotePath);
|
||||
|
||||
if (!await treeCache.getNote(noteId)) {
|
||||
if (!await treeCache.noteExists(noteId)) {
|
||||
// note doesn't exist so don't try to activate it
|
||||
startNotePath = null;
|
||||
}
|
||||
|
||||
if (startNotePath) {
|
||||
const node = await activateNote(startNotePath);
|
||||
// this is weird but it looks like even though init event has been called, but we the tree still
|
||||
// can't find nodes for given path which causes double loading of data. Little timeout fixes this.
|
||||
setTimeout(async () => {
|
||||
const node = await activateNote(startNotePath);
|
||||
|
||||
// looks like this this doesn't work when triggered immediatelly after activating node
|
||||
// so waiting a second helps
|
||||
setTimeout(() => node.makeVisible({scrollIntoView: true}), 1000);
|
||||
// looks like this this doesn't work when triggered immediatelly after activating node
|
||||
// so waiting a second helps
|
||||
setTimeout(() => node.makeVisible({scrollIntoView: true}), 1000);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
let ignoreNextActivationNoteId = null;
|
||||
|
||||
function initFancyTree(tree) {
|
||||
utils.assertArguments(tree);
|
||||
|
||||
@@ -413,14 +412,25 @@ function initFancyTree(tree) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
activate: (event, data) => {
|
||||
beforeActivate: (event, data) => {
|
||||
// this is for the case when tree reload has been called and we don't want to
|
||||
if (ignoreNextActivationNoteId && getActiveNode() !== null) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
activate: async (event, data) => {
|
||||
const node = data.node;
|
||||
const noteId = node.data.noteId;
|
||||
|
||||
if (ignoreNextActivationNoteId === noteId) {
|
||||
ignoreNextActivationNoteId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// click event won't propagate so let's close context menu manually
|
||||
contextMenuWidget.hideContextMenu();
|
||||
|
||||
setCurrentNotePathToHash(node);
|
||||
await setCurrentNotePathToHash(node);
|
||||
|
||||
noteDetailService.switchToNote(noteId);
|
||||
|
||||
@@ -490,7 +500,11 @@ function getTree() {
|
||||
async function reload() {
|
||||
const notes = await loadTree();
|
||||
|
||||
// this will also reload the note content
|
||||
// make sure the reload won't trigger reactivation. This is important especially in cases where we wait for the reload
|
||||
// to finish to then activate some other note. But since the activate() event is called asynchronously, it may be called
|
||||
// (or finished calling) after we switched to a different note.
|
||||
ignoreNextActivationNoteId = getActiveNode().data.noteId;
|
||||
|
||||
await getTree().reload(notes);
|
||||
}
|
||||
|
||||
@@ -722,7 +736,7 @@ messagingService.subscribeToSyncMessages(syncData => {
|
||||
utils.bindShortcut('ctrl+o', async () => {
|
||||
const node = getActiveNode();
|
||||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = treeUtils.getParentProtectedStatus(node);
|
||||
const isProtected = await treeUtils.getParentProtectedStatus(node);
|
||||
|
||||
if (node.data.noteId === 'root' || node.data.noteId === await hoistedNoteService.getHoistedNoteId()) {
|
||||
return;
|
||||
@@ -760,6 +774,8 @@ async function checkFolderStatus(node) {
|
||||
}
|
||||
|
||||
async function reloadNote(noteId) {
|
||||
await treeCache.reloadChildren(noteId);
|
||||
|
||||
for (const node of getNodesByNoteId(noteId)) {
|
||||
await node.load(true);
|
||||
|
||||
@@ -773,11 +789,12 @@ utils.bindShortcut('ctrl+p', createNoteInto);
|
||||
|
||||
utils.bindShortcut('ctrl+.', scrollToActiveNote);
|
||||
|
||||
$(window).bind('hashchange', function() {
|
||||
$(window).bind('hashchange', async function() {
|
||||
if (isNotePathInAddress()) {
|
||||
const notePath = getHashValueFromAddress();
|
||||
const noteId = notePath.split("/").pop();
|
||||
|
||||
if (notePath !== '-' && getActiveNotePath() !== notePath) {
|
||||
if (noteId !== '-' && noteId !== getActiveNode().data.noteId) {
|
||||
console.debug("Switching to " + notePath + " because of hash change");
|
||||
|
||||
activateNote(notePath);
|
||||
@@ -816,5 +833,6 @@ export default {
|
||||
getNodesByNoteId,
|
||||
checkFolderStatus,
|
||||
reloadNote,
|
||||
loadTreeCache
|
||||
loadTreeCache,
|
||||
expandToNote
|
||||
};
|
||||
@@ -5,6 +5,9 @@ import infoService from "./info.js";
|
||||
import messagingService from "./messaging.js";
|
||||
import server from "./server.js";
|
||||
|
||||
/**
|
||||
* TreeCache keeps a read only cache of note tree structure in frontend's memory.
|
||||
*/
|
||||
class TreeCache {
|
||||
constructor() {
|
||||
this.init();
|
||||
@@ -17,8 +20,12 @@ class TreeCache {
|
||||
}
|
||||
|
||||
init() {
|
||||
/** @type {Object.<string, string>} */
|
||||
this.parents = {};
|
||||
/** @type {Object.<string, string>} */
|
||||
this.children = {};
|
||||
|
||||
/** @type {Object.<string, string>} */
|
||||
this.childParentToBranch = {};
|
||||
|
||||
/** @type {Object.<string, NoteShort>} */
|
||||
@@ -46,6 +53,45 @@ class TreeCache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload children of given noteId.
|
||||
*/
|
||||
async reloadChildren(noteId) {
|
||||
const resp = await server.post('tree/load', { noteIds: [noteId] });
|
||||
|
||||
for (const childNoteId of this.children[noteId] || []) {
|
||||
this.parents[childNoteId] = this.parents[childNoteId].filter(p => p !== noteId);
|
||||
|
||||
const branchId = this.getBranchIdByChildParent(childNoteId, noteId);
|
||||
|
||||
delete this.branches[branchId];
|
||||
delete this.childParentToBranch[childNoteId + '-' + noteId];
|
||||
}
|
||||
|
||||
this.children[noteId] = [];
|
||||
|
||||
delete this.notes[noteId];
|
||||
|
||||
this.addResp(resp.notes, resp.branches, resp.relations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads parents of given noteId - useful when new note is created to make sure note is loaded
|
||||
* in a correct order.
|
||||
*/
|
||||
async reloadParents(noteId) {
|
||||
// to be able to find parents we need first to make sure it is actually loaded
|
||||
await this.getNote(noteId);
|
||||
|
||||
for (const parentNoteId of this.parents[noteId] || []) {
|
||||
await this.reloadChildren(parentNoteId);
|
||||
}
|
||||
|
||||
// this is done to load the new parents for the noteId
|
||||
await this.reloadChildren(noteId);
|
||||
}
|
||||
|
||||
/** @return {Promise<NoteShort[]>} */
|
||||
async getNotes(noteIds, silentNotFoundError = false) {
|
||||
const missingNoteIds = noteIds.filter(noteId => this.notes[noteId] === undefined);
|
||||
|
||||
@@ -53,6 +99,10 @@ class TreeCache {
|
||||
const resp = await server.post('tree/load', { noteIds: missingNoteIds });
|
||||
|
||||
this.addResp(resp.notes, resp.branches, resp.relations);
|
||||
|
||||
for (const note of resp.notes) {
|
||||
await this.reloadParents(note.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
return noteIds.map(noteId => {
|
||||
@@ -67,7 +117,14 @@ class TreeCache {
|
||||
}).filter(note => note !== null);
|
||||
}
|
||||
|
||||
/** @return NoteShort */
|
||||
/** @return {Promise<boolean>} */
|
||||
async noteExists(noteId) {
|
||||
const notes = await this.getNotes([noteId], true);
|
||||
|
||||
return notes.length === 1;
|
||||
}
|
||||
|
||||
/** @return {Promise<NoteShort>} */
|
||||
async getNote(noteId) {
|
||||
if (noteId === 'none') {
|
||||
return null;
|
||||
|
||||
@@ -110,11 +110,11 @@ async function getTopLevelItems(event) {
|
||||
items: insertChildNoteEnabled ? getNoteTypeItems("insertChildNote") : null,
|
||||
enabled: insertChildNoteEnabled },
|
||||
{ title: "Delete <kbd>Delete</kbd>", cmd: "delete", uiIcon: "trash",
|
||||
enabled: isNotRoot && parentNote.type !== 'search' },
|
||||
enabled: isNotRoot && !isHoisted && parentNote.type !== 'search' },
|
||||
{ title: "----" },
|
||||
isHoisted ? null : { title: "Hoist note <kbd>Ctrl-H</kbd>", cmd: "hoist", uiIcon: "arrow-up" },
|
||||
isHoisted ? null : { title: "Hoist note <kbd>Ctrl-H</kbd>", cmd: "hoist", uiIcon: "empty" },
|
||||
!isHoisted || !isNotRoot ? null : { title: "Unhoist note <kbd>Ctrl-H</kbd>", cmd: "unhoist", uiIcon: "arrow-up" },
|
||||
{ title: "Edit branch prefix <kbd>F2</kbd>", cmd: "editBranchPrefix", uiIcon: "pencil",
|
||||
{ title: "Edit branch prefix <kbd>F2</kbd>", cmd: "editBranchPrefix", uiIcon: "empty",
|
||||
enabled: isNotRoot && parentNote.type !== 'search'},
|
||||
{ title: "----" },
|
||||
{ title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check" },
|
||||
@@ -129,14 +129,14 @@ async function getTopLevelItems(event) {
|
||||
{ title: "Paste after", cmd: "pasteAfter", uiIcon: "clipboard",
|
||||
enabled: clipboardIds.length > 0 && isNotRoot && parentNote.type !== 'search' },
|
||||
{ title: "----" },
|
||||
{ title: "Export", cmd: "export", uiIcon: "arrow-up-right",
|
||||
{ title: "Export", cmd: "export", uiIcon: "empty",
|
||||
enabled: note.type !== 'search' },
|
||||
{ title: "Import into note", cmd: "importIntoNote", uiIcon: "arrow-down-left",
|
||||
{ title: "Import into note", cmd: "importIntoNote", uiIcon: "empty",
|
||||
enabled: note.type !== 'search' },
|
||||
{ title: "----" },
|
||||
{ title: "Collapse subtree <kbd>Alt+-</kbd>", cmd: "collapseSubtree", uiIcon: "align-justify" },
|
||||
{ title: "Force note sync", cmd: "forceNoteSync", uiIcon: "refresh" },
|
||||
{ title: "Sort alphabetically <kbd>Alt+S</kbd>", cmd: "sortAlphabetically", uiIcon: "arrows-v" }
|
||||
{ title: "Sort alphabetically <kbd>Alt+S</kbd>", cmd: "sortAlphabetically", uiIcon: "empty" }
|
||||
].filter(row => row !== null);
|
||||
}
|
||||
|
||||
@@ -156,13 +156,13 @@ async function getContextMenuItems(event) {
|
||||
return items;
|
||||
}
|
||||
|
||||
function selectContextMenuItem(event, cmd) {
|
||||
async function selectContextMenuItem(event, cmd) {
|
||||
// context menu is always triggered on current node
|
||||
const node = treeService.getActiveNode();
|
||||
|
||||
if (cmd.startsWith("insertNoteAfter")) {
|
||||
const parentNoteId = node.data.parentNoteId;
|
||||
const isProtected = treeUtils.getParentProtectedStatus(node);
|
||||
const isProtected = await treeUtils.getParentProtectedStatus(node);
|
||||
const type = cmd.split("_")[1];
|
||||
|
||||
treeService.createNote(node, parentNoteId, 'after', {
|
||||
|
||||
@@ -109,8 +109,8 @@ const keyBindings = {
|
||||
|
||||
return false;
|
||||
},
|
||||
"backspace": node => {
|
||||
if (!utils.isRootNode(node)) {
|
||||
"backspace": async node => {
|
||||
if (!await hoistedNoteService.isRootNode(node)) {
|
||||
node.getParent().setActive().then(treeService.clearSelectedNodes);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import utils from './utils.js';
|
||||
import hoistedNoteService from './hoisted_note.js';
|
||||
import treeCache from "./tree_cache.js";
|
||||
|
||||
const $tree = $("#tree");
|
||||
|
||||
function getParentProtectedStatus(node) {
|
||||
return utils.isRootNode(node) ? 0 : node.getParent().data.isProtected;
|
||||
async function getParentProtectedStatus(node) {
|
||||
return await hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected;
|
||||
}
|
||||
|
||||
function getNodeByKey(key) {
|
||||
@@ -21,10 +22,15 @@ function getNoteIdFromNotePath(notePath) {
|
||||
return path[path.length - 1];
|
||||
}
|
||||
|
||||
function getNotePath(node) {
|
||||
async function getNotePath(node) {
|
||||
if (!node) {
|
||||
console.error("Node is null");
|
||||
return "";
|
||||
}
|
||||
|
||||
const path = [];
|
||||
|
||||
while (node && !utils.isRootNode(node)) {
|
||||
while (node && !await hoistedNoteService.isRootNode(node)) {
|
||||
if (node.data.noteId) {
|
||||
path.push(node.data.noteId);
|
||||
}
|
||||
@@ -32,7 +38,7 @@ function getNotePath(node) {
|
||||
node = node.getParent();
|
||||
}
|
||||
|
||||
path.push('root');
|
||||
path.push(node.data.noteId); // root or hoisted noteId
|
||||
|
||||
return path.reverse().join("/");
|
||||
}
|
||||
|
||||
@@ -60,14 +60,6 @@ function assertArguments() {
|
||||
}
|
||||
}
|
||||
|
||||
function isTopLevelNode(node) {
|
||||
return isRootNode(node.getParent());
|
||||
}
|
||||
|
||||
function isRootNode(node) {
|
||||
return node.data.noteId === "root";
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return $('<div/>').text(str).html();
|
||||
}
|
||||
@@ -211,8 +203,6 @@ export default {
|
||||
isElectron,
|
||||
isMac,
|
||||
assertArguments,
|
||||
isTopLevelNode,
|
||||
isRootNode,
|
||||
escapeHtml,
|
||||
stopWatch,
|
||||
formatValueWithWhitespace,
|
||||
|
||||
@@ -928,4 +928,9 @@ a.external:after, a[href^="http://"]:after, a[href^="https://"]:after {
|
||||
.card {
|
||||
background-color: inherit !important;
|
||||
border-color: var(--main-border-color) !important;
|
||||
}
|
||||
|
||||
.jam-empty {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
const dateNoteService = require('../../services/date_notes');
|
||||
|
||||
async function getDateNote(req) {
|
||||
return await dateNoteService.getDateNote(req.params.date);
|
||||
}
|
||||
|
||||
async function getMonthNote(req) {
|
||||
return await dateNoteService.getMonthNote(req.params.month);
|
||||
}
|
||||
|
||||
async function getYearNote(req) {
|
||||
return await dateNoteService.getYearNote(req.params.year);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getDateNote,
|
||||
getMonthNote,
|
||||
getYearNote
|
||||
};
|
||||
@@ -14,7 +14,7 @@ async function returnImage(req, res) {
|
||||
else if (image.type !== 'image') {
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
else if (image.data === null) {
|
||||
else if (image.isDeleted || image.data === null) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
return res.send(fs.readFileSync(RESOURCE_DIR + '/db/image-deleted.png'));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,17 @@ const searchService = require('../../services/search');
|
||||
async function searchNotes(req) {
|
||||
const noteIds = await searchService.searchForNoteIds(req.params.searchString);
|
||||
|
||||
return noteIds.map(noteCacheService.getNotePath).filter(res => !!res);
|
||||
try {
|
||||
return {
|
||||
success: true,
|
||||
results: noteIds.map(noteCacheService.getNotePath).filter(res => !!res)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
success: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function searchFromNote(req) {
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ async function login(req, res) {
|
||||
}
|
||||
|
||||
req.session.loggedIn = true;
|
||||
res.redirect('/');
|
||||
res.redirect('..');
|
||||
});
|
||||
}
|
||||
else {
|
||||
@@ -44,7 +44,7 @@ function logout(req, res) {
|
||||
req.session.regenerate(() => {
|
||||
req.session.loggedIn = false;
|
||||
|
||||
res.redirect('/');
|
||||
res.redirect('login');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ const scriptRoute = require('./api/script');
|
||||
const senderRoute = require('./api/sender');
|
||||
const filesRoute = require('./api/file_upload');
|
||||
const searchRoute = require('./api/search');
|
||||
const dateNotesRoute = require('./api/date_notes');
|
||||
|
||||
const log = require('../services/log');
|
||||
const express = require('express');
|
||||
@@ -153,6 +154,10 @@ function register(app) {
|
||||
apiRoute(GET, '/api/attributes/names', attributesRoute.getAttributeNames);
|
||||
apiRoute(GET, '/api/attributes/values/:attributeName', attributesRoute.getValuesForAttribute);
|
||||
|
||||
apiRoute(GET, '/api/date-notes/date/:date', dateNotesRoute.getDateNote);
|
||||
apiRoute(GET, '/api/date-notes/month/:month', dateNotesRoute.getMonthNote);
|
||||
apiRoute(GET, '/api/date-notes/year/:year', dateNotesRoute.getYearNote);
|
||||
|
||||
route(GET, '/api/images/:noteId/:filename', [auth.checkApiAuthOrElectron], imageRoute.returnImage);
|
||||
route(POST, '/api/images', [auth.checkApiAuthOrElectron, uploadMiddleware, csrfMiddleware], imageRoute.uploadImage, apiResultHandler);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const build = require('./build');
|
||||
const packageJson = require('../../package');
|
||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||
|
||||
const APP_DB_VERSION = 131;
|
||||
const APP_DB_VERSION = 133;
|
||||
const SYNC_VERSION = 8;
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -99,10 +99,24 @@ function BackendScriptApi(currentNote, apiParams) {
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns ${Promise<Note[]>}
|
||||
* @returns {Promise<Note[]>}
|
||||
*/
|
||||
this.searchForNotes = searchService.searchForNotes;
|
||||
|
||||
/**
|
||||
* This is a powerful search method - you can search by attributes and their values, e.g.:
|
||||
* "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
|
||||
*
|
||||
* @method
|
||||
* @param {string} searchString
|
||||
* @returns {Promise<Note|null>}
|
||||
*/
|
||||
this.searchForNote = async searchString => {
|
||||
const notes = await searchService.searchForNotes(searchString);
|
||||
|
||||
return notes.length > 0 ? notes[0] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves notes with given label name & value
|
||||
*
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = { buildDate:"2019-04-01T21:50:32+02:00", buildRevision: "f47f3461e666d007668e03282f86b028012f7bef" };
|
||||
module.exports = { buildDate:"2019-04-22T22:53:04+02:00", buildRevision: "eac5ec6e267a64c77aa6a1f791f95b15cc549869" };
|
||||
|
||||
@@ -67,8 +67,8 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
|
||||
const params = [];
|
||||
|
||||
for (const filter of filters) {
|
||||
if (filter.name.toLowerCase() === 'orderby') {
|
||||
continue; // orderby is not real filter
|
||||
if (['orderby', 'limit'].includes(filter.name.toLowerCase())) {
|
||||
continue; // orderby and limit are not real filters
|
||||
}
|
||||
|
||||
where += " " + filter.relation + " ";
|
||||
@@ -82,18 +82,8 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
|
||||
where += `${accessor} IS NULL`;
|
||||
}
|
||||
else if (filter.operator === '=' || filter.operator === '!=') {
|
||||
if (filter.name === 'text') {
|
||||
const safeSearchText = utils.sanitizeSql(filter.value);
|
||||
const not = filter.operator.includes("!") ? "NOT" : "";
|
||||
|
||||
// fulltext needs to use subselect because fulltext doesn't support OR operations at all
|
||||
// which makes it impossible to combine more operations together
|
||||
where += `notes.noteId ${not} IN (SELECT noteId FROM note_fulltext WHERE note_fulltext MATCH '${safeSearchText}')`;
|
||||
}
|
||||
else {
|
||||
where += `${accessor} ${filter.operator} ?`;
|
||||
params.push(filter.value);
|
||||
}
|
||||
where += `${accessor} ${filter.operator} ?`;
|
||||
params.push(filter.value);
|
||||
}
|
||||
else if (filter.operator === '*=' || filter.operator === '!*=') {
|
||||
where += `${accessor}`
|
||||
@@ -106,9 +96,17 @@ module.exports = function(filters, selectedColumns = 'notes.*') {
|
||||
+ ` LIKE ` + utils.prepareSqlForLike('', filter.value, '%');
|
||||
}
|
||||
else if (filter.operator === '*=*' || filter.operator === '!*=*') {
|
||||
where += `${accessor}`
|
||||
+ (filter.operator.includes('!') ? ' NOT' : '')
|
||||
+ ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '%');
|
||||
const columns = filter.name === 'text' ? [getAccessor("title"), getAccessor("content")] : [accessor];
|
||||
|
||||
let condition = "(" + columns.map(column =>
|
||||
`${column}` + ` LIKE ` + utils.prepareSqlForLike('%', filter.value, '%'))
|
||||
.join(" OR ") + ")";
|
||||
|
||||
if (filter.operator.includes('!')) {
|
||||
condition = "NOT(" + condition + ")";
|
||||
}
|
||||
|
||||
where += condition;
|
||||
}
|
||||
else if ([">", ">=", "<", "<="].includes(filter.operator)) {
|
||||
let floatParam;
|
||||
|
||||
@@ -5,7 +5,6 @@ const sqlInit = require('./sql_init');
|
||||
const log = require('./log');
|
||||
const messagingService = require('./messaging');
|
||||
const syncMutexService = require('./sync_mutex');
|
||||
const noteFulltextService = require('./note_fulltext');
|
||||
const repository = require('./repository');
|
||||
const cls = require('./cls');
|
||||
const syncTableService = require('./sync_table');
|
||||
@@ -358,42 +357,6 @@ async function findLogicIssues() {
|
||||
|
||||
logFix(`Removed link ${linkId} because target note ${targetNoteId} is also deleted.`);
|
||||
});
|
||||
|
||||
// this doesn't try to find notes for which the fulltext doesn't exist at all - reason is the "archived" label
|
||||
// which is inheritable and not easy to filter out such rows in consistency check which would mean that it would
|
||||
// find some false positives.
|
||||
await findAndFixIssues(`
|
||||
SELECT
|
||||
noteId
|
||||
FROM
|
||||
notes
|
||||
JOIN note_contents USING(noteId)
|
||||
JOIN note_fulltext USING(noteId)
|
||||
WHERE
|
||||
notes.isDeleted = 0
|
||||
AND notes.isProtected = 0
|
||||
AND (note_fulltext.noteId IS NULL
|
||||
OR note_fulltext.titleHash != notes.hash
|
||||
OR note_fulltext.contentHash != note_contents.hash)`,
|
||||
async ({noteId}) => {
|
||||
noteFulltextService.triggerNoteFulltextUpdate(noteId);
|
||||
|
||||
logFix(`Triggered fulltext update of note ${noteId} since it was out of sync.`);
|
||||
});
|
||||
|
||||
await findAndFixIssues(`
|
||||
SELECT
|
||||
noteId
|
||||
FROM
|
||||
notes
|
||||
JOIN note_fulltext USING(noteId)
|
||||
WHERE
|
||||
(notes.isDeleted = 1 OR notes.isProtected = 1)`,
|
||||
async ({noteId}) => {
|
||||
noteFulltextService.triggerNoteFulltextUpdate(noteId);
|
||||
|
||||
logFix(`Triggered fulltext update of note ${noteId} since it was out of sync.`);
|
||||
});
|
||||
}
|
||||
|
||||
async function runSyncRowChecks(entityName, key) {
|
||||
@@ -430,6 +393,7 @@ async function runSyncRowChecks(entityName, key) {
|
||||
|
||||
async function findSyncRowsIssues() {
|
||||
await runSyncRowChecks("notes", "noteId");
|
||||
await runSyncRowChecks("note_contents", "noteId");
|
||||
await runSyncRowChecks("note_revisions", "noteRevisionId");
|
||||
await runSyncRowChecks("branches", "branchId");
|
||||
await runSyncRowChecks("recent_notes", "branchId");
|
||||
|
||||
@@ -36,6 +36,10 @@ const DIR_NAME = 'trilium-data';
|
||||
|
||||
function getTriliumDataDir() {
|
||||
if (process.env.TRILIUM_DATA_DIR) {
|
||||
if (!fs.existsSync(process.env.TRILIUM_DATA_DIR)) {
|
||||
fs.mkdirSync(process.env.TRILIUM_DATA_DIR, 0o700);
|
||||
}
|
||||
|
||||
return process.env.TRILIUM_DATA_DIR;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const eventService = require('./events');
|
||||
const scriptService = require('./script');
|
||||
const treeService = require('./tree');
|
||||
const messagingService = require('./messaging');
|
||||
const log = require('./log');
|
||||
const Attribute = require('../entities/attribute');
|
||||
|
||||
@@ -29,9 +28,6 @@ eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async note => {
|
||||
for (const parent of parents) {
|
||||
if (await parent.hasLabel("sorted")) {
|
||||
await treeService.sortNotesAlphabetically(parent.noteId);
|
||||
|
||||
messagingService.refreshTree();
|
||||
break; // sending the message once is enough
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,13 @@ async function shrinkImage(buffer, originalName) {
|
||||
log.error("Failed to optimize image '" + originalName + "\nStack: " + e.stack);
|
||||
finalImageBuffer = resizedImage;
|
||||
}
|
||||
|
||||
// if resizing & shrinking did not help with size then save the original
|
||||
// (can happen when e.g. resizing PNG into JPEG)
|
||||
if (finalImageBuffer.byteLength >= buffer.byteLength) {
|
||||
finalImageBuffer = buffer;
|
||||
}
|
||||
|
||||
return finalImageBuffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -376,6 +376,16 @@ eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @param noteId
|
||||
* @returns {boolean} - true if note exists (is not deleted) and is not archived.
|
||||
*/
|
||||
function isAvailable(noteId) {
|
||||
const notePath = getNotePath(noteId);
|
||||
|
||||
return !!notePath;
|
||||
}
|
||||
|
||||
eventService.subscribe(eventService.ENTER_PROTECTED_SESSION, () => {
|
||||
if (loaded) {
|
||||
loadProtectedNotes();
|
||||
@@ -388,5 +398,6 @@ module.exports = {
|
||||
findNotes,
|
||||
getNotePath,
|
||||
getNoteTitleForPath,
|
||||
isAvailable,
|
||||
load
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
const sql = require('./sql');
|
||||
const repository = require('./repository');
|
||||
const html2plaintext = require('html2plaintext');
|
||||
|
||||
const noteIdQueue = [];
|
||||
|
||||
async function updateNoteFulltext(note) {
|
||||
if (note.isDeleted || note.isProtected || await note.hasLabel('archived')) {
|
||||
await sql.execute(`DELETE
|
||||
FROM note_fulltext
|
||||
WHERE noteId = ?`, [note.noteId]);
|
||||
} else {
|
||||
let content = null;
|
||||
let contentHash = null;
|
||||
|
||||
if (['text', 'code'].includes(note.type)) {
|
||||
content = await note.getContent();
|
||||
|
||||
if (note.type === 'text' && note.mime === 'text/html') {
|
||||
content = html2plaintext(content);
|
||||
}
|
||||
|
||||
contentHash = note.contentHash;
|
||||
}
|
||||
|
||||
// optimistically try to update first ...
|
||||
const res = await sql.execute(`UPDATE note_fulltext SET title = ?, titleHash = ?, content = ?, contentHash = ? WHERE noteId = ?`, [note.title, note.hash, content, contentHash, note.noteId]);
|
||||
|
||||
// ... and insert only when the update did not work
|
||||
if (res.stmt.changes === 0) {
|
||||
await sql.execute(`INSERT INTO note_fulltext (title, titleHash, content, contentHash, noteId)
|
||||
VALUES (?, ?, ?, ?, ?)`, [note.title, note.hash, content, contentHash, note.noteId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function triggerNoteFulltextUpdate(noteId) {
|
||||
if (!noteIdQueue.includes(noteId)) {
|
||||
noteIdQueue.push(noteId);
|
||||
}
|
||||
|
||||
while (noteIdQueue.length > 0) {
|
||||
await sql.transactional(async () => {
|
||||
if (noteIdQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const noteId = noteIdQueue.shift();
|
||||
const note = await repository.getNote(noteId);
|
||||
|
||||
await updateNoteFulltext(note);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
triggerNoteFulltextUpdate,
|
||||
updateNoteFulltext
|
||||
};
|
||||
@@ -12,6 +12,7 @@ const Link = require('../entities/link');
|
||||
const NoteRevision = require('../entities/note_revision');
|
||||
const Branch = require('../entities/branch');
|
||||
const Attribute = require('../entities/attribute');
|
||||
const hoistedNoteService = require('../services/hoisted_note');
|
||||
|
||||
async function getNewNotePosition(parentNoteId, noteData) {
|
||||
let newNotePos = 0;
|
||||
@@ -364,7 +365,10 @@ async function deleteNote(branch) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (branch.branchId === 'root' || branch.noteId === 'root') {
|
||||
if (branch.branchId === 'root'
|
||||
|| branch.noteId === 'root'
|
||||
|| branch.noteId === await hoistedNoteService.getHoistedNoteId()) {
|
||||
|
||||
throw new Error("Can't delete root branch/note");
|
||||
}
|
||||
|
||||
|
||||
@@ -43,22 +43,45 @@ function calculateSmartValue(v) {
|
||||
}
|
||||
|
||||
module.exports = function (searchText) {
|
||||
searchText = searchText.trim();
|
||||
|
||||
// if the string doesn't start with attribute then we consider it as just standard full text search
|
||||
if (!searchText.trim().startsWith("@")) {
|
||||
return [
|
||||
{
|
||||
if (!searchText.startsWith("@")) {
|
||||
// replace with space instead of empty string since these characters are probably separators
|
||||
const filters = [];
|
||||
|
||||
if (searchText.startsWith('"') && searchText.endsWith('"')) {
|
||||
// "bla bla" will search for exact match
|
||||
searchText = searchText.substr(1, searchText.length - 2);
|
||||
|
||||
filters.push({
|
||||
relation: 'and',
|
||||
name: 'text',
|
||||
operator: '=',
|
||||
value: searchText
|
||||
},
|
||||
{
|
||||
relation: 'or',
|
||||
name: 'noteId',
|
||||
operator: '=',
|
||||
operator: '*=*',
|
||||
value: searchText
|
||||
});
|
||||
}
|
||||
else {
|
||||
const tokens = searchText.split(/\s+/);
|
||||
|
||||
for (const token of tokens) {
|
||||
filters.push({
|
||||
relation: 'and',
|
||||
name: 'text',
|
||||
operator: '*=*',
|
||||
value: token
|
||||
});
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
filters.push({
|
||||
relation: 'or',
|
||||
name: 'noteId',
|
||||
operator: '=',
|
||||
value: searchText
|
||||
});
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
const filters = [];
|
||||
|
||||
@@ -42,6 +42,21 @@ async function getNote(noteId) {
|
||||
return await getEntity("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
}
|
||||
|
||||
/** @returns {Promise<Note[]>} */
|
||||
async function getNotes(noteIds) {
|
||||
// this note might be optimised, but remember that it must keep the existing order of noteIds
|
||||
// (important e.g. for @orderBy in search)
|
||||
const notes = [];
|
||||
|
||||
for (const noteId of noteIds) {
|
||||
const note = await getNote(noteId);
|
||||
|
||||
notes.push(note);
|
||||
}
|
||||
|
||||
return notes;
|
||||
}
|
||||
|
||||
/** @returns {Promise<Branch|null>} */
|
||||
async function getBranch(branchId) {
|
||||
return await getEntity("SELECT * FROM branches WHERE branchId = ?", [branchId]);
|
||||
@@ -125,6 +140,7 @@ module.exports = {
|
||||
getEntities,
|
||||
getEntity,
|
||||
getNote,
|
||||
getNotes,
|
||||
getBranch,
|
||||
getAttribute,
|
||||
getOption,
|
||||
|
||||
@@ -71,9 +71,6 @@ async function executeScript(script, params, startNoteId, currentNoteId, originE
|
||||
}
|
||||
|
||||
async function execute(ctx, script) {
|
||||
// scripts run as "server" sourceId so clients recognize the changes as "foreign" and update themselves
|
||||
cls.namespace.set('sourceId', sourceIdService.getCurrentSourceId());
|
||||
|
||||
return await (function() { return eval(`const apiContext = this;\r\n(${script}\r\n)()`); }.call(ctx));
|
||||
}
|
||||
|
||||
|
||||
+18
-12
@@ -3,20 +3,12 @@ const sql = require('./sql');
|
||||
const log = require('./log');
|
||||
const parseFilters = require('./parse_filters');
|
||||
const buildSearchQuery = require('./build_search_query');
|
||||
const noteCacheService = require('./note_cache');
|
||||
|
||||
async function searchForNotes(searchString) {
|
||||
const filters = parseFilters(searchString);
|
||||
const noteIds = await searchForNoteIds(searchString);
|
||||
|
||||
const {query, params} = buildSearchQuery(filters);
|
||||
|
||||
try {
|
||||
return await repository.getEntities(query, params);
|
||||
}
|
||||
catch (e) {
|
||||
log.error("Search failed for " + query);
|
||||
|
||||
throw e;
|
||||
}
|
||||
return await repository.getNotes(noteIds);
|
||||
}
|
||||
|
||||
async function searchForNoteIds(searchString) {
|
||||
@@ -25,7 +17,21 @@ async function searchForNoteIds(searchString) {
|
||||
const {query, params} = buildSearchQuery(filters, 'notes.noteId');
|
||||
|
||||
try {
|
||||
return await sql.getColumn(query, params);
|
||||
const noteIds = await sql.getColumn(query, params);
|
||||
|
||||
const availableNoteIds = noteIds.filter(noteCacheService.isAvailable);
|
||||
|
||||
const limitFilter = filters.find(filter => filter.name.toLowerCase() === 'limit');
|
||||
|
||||
if (limitFilter) {
|
||||
const limit = parseInt(limitFilter.value);
|
||||
|
||||
return availableNoteIds.splice(0, limit);
|
||||
}
|
||||
else {
|
||||
return availableNoteIds;
|
||||
}
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
log.error("Search failed for " + query);
|
||||
|
||||
@@ -14,13 +14,19 @@ async function createConnection() {
|
||||
return await sqlite.open(dataDir.DOCUMENT_PATH, {Promise});
|
||||
}
|
||||
|
||||
const dbConnection = new Promise(async (resolve, reject) => {
|
||||
// no need to create new connection now since DB stays the same all the time
|
||||
const db = await createConnection();
|
||||
sql.setDbConnection(db);
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
let dbReadyResolve = null;
|
||||
const dbReady = new Promise(async (resolve, reject) => {
|
||||
dbReadyResolve = resolve;
|
||||
|
||||
// no need to create new connection now since DB stays the same all the time
|
||||
const db = await createConnection();
|
||||
sql.setDbConnection(db);
|
||||
await dbConnection;
|
||||
|
||||
initDbConnection();
|
||||
});
|
||||
@@ -165,6 +171,7 @@ dbReady.then(async () => {
|
||||
|
||||
module.exports = {
|
||||
dbReady,
|
||||
dbConnection,
|
||||
schemaExists,
|
||||
isDbInitialized,
|
||||
initDbConnection,
|
||||
|
||||
@@ -49,7 +49,11 @@ async function sync() {
|
||||
catch (e) {
|
||||
proxyToggle = !proxyToggle;
|
||||
|
||||
if (e.message && (e.message.includes('ECONNREFUSED') || e.message.includes('ERR_CONNECTION_REFUSED'))) {
|
||||
if (e.message &&
|
||||
(e.message.includes('ECONNREFUSED') ||
|
||||
e.message.includes('ERR_CONNECTION_REFUSED') ||
|
||||
e.message.includes('Bad Gateway'))) {
|
||||
|
||||
log.info("No connection to sync server.");
|
||||
|
||||
return {
|
||||
@@ -263,9 +267,7 @@ async function getEntityRow(entityName, entityId) {
|
||||
const entity = await sql.getRow(`SELECT * FROM ${entityName} WHERE ${primaryKey} = ?`, [entityId]);
|
||||
|
||||
if (!entity) {
|
||||
console.log(entityName, entityId);
|
||||
|
||||
console.log(`SELECT * FROM ${entityName} WHERE ${primaryKey} = '${entityId}'`);
|
||||
throw new Error(`Entity ${entityName} ${entityId} not found.`);
|
||||
}
|
||||
|
||||
if (['note_contents', 'note_revisions'].includes(entityName) && entity.content !== null) {
|
||||
|
||||
@@ -3,7 +3,6 @@ const log = require('./log');
|
||||
const eventLogService = require('./event_log');
|
||||
const syncTableService = require('./sync_table');
|
||||
const eventService = require('./events');
|
||||
const noteFulltextService = require('../services/note_fulltext');
|
||||
|
||||
async function updateEntity(sync, entity, sourceId) {
|
||||
const {entityName} = sync;
|
||||
@@ -62,8 +61,6 @@ async function updateNote(entity, sourceId) {
|
||||
await syncTableService.addNoteSync(entity.noteId, sourceId);
|
||||
});
|
||||
|
||||
noteFulltextService.triggerNoteFulltextUpdate(entity.noteId);
|
||||
|
||||
log.info("Update/sync note " + entity.noteId);
|
||||
}
|
||||
}
|
||||
@@ -78,8 +75,6 @@ async function updateNoteContent(entity, sourceId) {
|
||||
await sql.replace("note_contents", entity);
|
||||
|
||||
await syncTableService.addNoteContentSync(entity.noteId, sourceId);
|
||||
|
||||
noteFulltextService.triggerNoteFulltextUpdate(entity.noteId);
|
||||
});
|
||||
|
||||
log.info("Update/sync note content for noteId=" + entity.noteId);
|
||||
|
||||
+14
-9
@@ -5,6 +5,7 @@
|
||||
<title>Trilium Notes</title>
|
||||
</head>
|
||||
<body class="desktop theme-<%= theme %>" style="--main-font-size: <%= mainFontSize %>%; --tree-font-size: <%= treeFontSize %>%; --detail-font-size: <%= detailFontSize %>%;">
|
||||
<noscript>Trilium requires JavaScript to be enabled.</noscript>
|
||||
<div id="container" style="display: none; grid-template-columns: minmax(<%= leftPaneMinWidth %>px, <%= leftPaneWidthPercent %>fr) <%= rightPaneWidthPercent %>fr">
|
||||
<div id="header" class="hide-toggle">
|
||||
<div id="history-navigation" style="display: none;">
|
||||
@@ -61,12 +62,6 @@
|
||||
Sync (<span id="outstanding-syncs-count">0</span>)
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" id="show-help-button">
|
||||
<span class="jam jam-help"></span>
|
||||
Show Help
|
||||
<kbd>F1</kbd>
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" id="open-dev-tools-button">
|
||||
<span class="jam jam-terminal"></span>
|
||||
Open Dev Tools
|
||||
@@ -79,8 +74,20 @@
|
||||
<kbd>ALT+O</kbd>
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" id="reload-frontend-button" title="Reload can help with some visual glitches without restarting the whole app.">
|
||||
<span class="jam jam-empty"></span>
|
||||
Reload frontend
|
||||
<kbd>CTRL-R</kbd>
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" id="show-help-button">
|
||||
<span class="jam jam-help"></span>
|
||||
Show Help
|
||||
<kbd>F1</kbd>
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item" id="show-about-dialog-button">
|
||||
<span class="jam jam-info"></span>
|
||||
<span class="jam jam-empty"></span>
|
||||
About Trilium Notes
|
||||
</a>
|
||||
|
||||
@@ -241,8 +248,6 @@
|
||||
<% include dialogs/note_info.ejs %>
|
||||
</div>
|
||||
|
||||
<webview class="electron-in-page-search-window" nodeintegration disablewebsecurity src="libraries/electron-in-page-search/search-window.html"></webview>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.baseApiUrl = 'api/';
|
||||
window.device = "desktop";
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/images/app-icons/ios/apple-touch-icon.png">
|
||||
</head>
|
||||
<body class="mobile">
|
||||
<noscript>Trilium requires JavaScript to be enabled.</noscript>
|
||||
<div class="row" id="container-row" style="display: none;">
|
||||
|
||||
<div id="left-pane" class="d-sm-flex d-md-flex d-lg-flex d-xl-flex col-12 col-sm-5 col-md-4 col-lg-4 col-xl-4">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<title>Setup</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>Trilium requires JavaScript to be enabled.</noscript>
|
||||
<div class="container">
|
||||
<div id="setup-dialog" class="col-md-12 col-lg-8 col-xl-6 mx-auto" style="padding-top: 25px; font-size: larger; display: none;">
|
||||
<h1>Trilium Notes setup</h1>
|
||||
|
||||
@@ -35,6 +35,14 @@ async function startTrilium() {
|
||||
app.set('port', usedPort);
|
||||
|
||||
if (config['Network']['https']) {
|
||||
if (!config['Network']['keyPath'] || !config['Network']['keyPath'].trim().length) {
|
||||
throw new Error("keyPath in config.ini is required when https=true, but it's empty");
|
||||
}
|
||||
|
||||
if (!config['Network']['certPath'] || !config['Network']['certPath'].trim().length) {
|
||||
throw new Error("certPath in config.ini is required when https=true, but it's empty");
|
||||
}
|
||||
|
||||
const options = {
|
||||
key: fs.readFileSync(config['Network']['keyPath']),
|
||||
cert: fs.readFileSync(config['Network']['certPath'])
|
||||
|
||||
Reference in New Issue
Block a user