即時與無介面
每次呼叫時,伺服器都會透過各編輯器在 ~/.erd-editor/ide/ 中保留的鎖定檔案,尋找持有該文件的編輯器。
裝有 ERD Editor 的每個 VS Code 視窗和每個 Obsidian 儲存庫視窗各保留一個,而 JetBrains IDE 則為整個 IDE 保留一個,其中列出在該 IDE 中開啟的每個專案。
編輯器關閉時會移除其鎖定檔案。
伺服器找到的結果決定編輯會送往何處。
| 找到的結果 | 編輯的行為 |
|---|---|
| 工作區、儲存庫或已開啟的專案包含該文件的編輯器,或已開啟該文件的編輯器 | 即時。必要時在 ERD Editor 中開啟文件,加入編輯工作階段,並在其中套用變更。編輯會立即出現,並會像您自己的編輯一樣由編輯器儲存,請參閱儲存。 |
| 沒有編輯器 | 無介面。載入檔案、套用變更,然後取代該檔案。erd_save 無事可做。 |
| hub 已關閉的編輯器 | 拒絕。讀取仍可運作,會從磁碟讀取。在編輯器開啟該檔案時寫入檔案的變更,可能會被該編輯器的下一次儲存覆寫,因此伺服器不會寫入任何內容。 |
hub 已開啟,但使用的協定與伺服器不同的編輯器:搭配伺服器 1.0.0 時,為 3.x 的 VS Code 擴充功能、0.x 的 Obsidian 外掛程式,或 0.9.0 或 0.10.0 的 JetBrains 外掛程式;搭配 1.0.0 之前的伺服器時,為 4.0.0 或更新版本的擴充功能,或 1.0.0 或更新版本的外掛程式 | 拒絕,包括讀取,錯誤碼為 protocolMismatch。訊息會指出需要更新的一方:擴充功能或外掛程式,或是伺服器,請參閱更新。 |
在 Windows 上,以同一檔案的另一個路徑持有該文件的編輯器:代理程式透過這台電腦的網路共用或對應的網路磁碟機指定該文件,例如 \\localhost\C$\…,而編輯器以其磁碟機路徑持有它,或反之亦然 | 拒絕,包括讀取,錯誤碼為 invalidPath。訊息會指出編輯器持有該文件所用的路徑;請以該路徑再呼叫一次。 |
| 在 Windows 上,Windows 不讓代理程式存取的編輯器:在代理程式並非以系統管理員身分執行時以系統管理員身分啟動的編輯器,或代理程式在沙箱中執行時的任何編輯器 | 拒絕,包括讀取,錯誤碼為 hubUnreachable,並附上說明原因的訊息。請以相同的權限執行編輯器和代理程式,例如不以系統管理員權限重新啟動編輯器。 |
編輯的結果會指出其執行時的模式,即 live 或 headless,而被拒絕的編輯會說明原因。
每次呼叫都會重新尋找,因此開啟或關閉編輯器後,下一次呼叫也會隨之改變去向。
當有多個編輯器持有該文件時,已開啟該文件的編輯器優先於僅為包含該文件的資料夾提供服務的編輯器;而在為資料夾提供服務的編輯器之間,資料夾位於最深層的編輯器優先。 平手時,例如兩個編輯器都已開啟該文件,由鎖定檔案最後變更的編輯器優先。 因此,位於 VS Code 工作區資料夾內的 Obsidian 儲存庫中的文件會交給 Obsidian,除非 VS Code 已開啟該文件而 Obsidian 沒有。
對同一份文件的呼叫會依其送達伺服器的順序逐一執行。對不同文件的呼叫則會同時執行。
即時
代理程式會像多一位協作者一樣加入編輯器。 它的編輯會立即送達每個開啟該文件的編輯器,而它的焦點會像協作者的焦點一樣,繪製在它正在編輯的資料表和儲存格上,請參閱 focusTracker。
讀取絕不會開啟編輯器。文件尚未開啟時,編輯會在 ERD Editor 中開啟該文件,且不會奪走鍵盤焦點。
儲存
每個編輯器儲存代理程式編輯的方式,都與儲存您自己的編輯相同。
在 VS Code 中,代理程式的編輯會像您自己的編輯一樣將分頁標示為已修改,且只有在文件儲存時才會寫入磁碟。
erd_save 會像 VS Code 本身的儲存命令一樣,透過 VS Code 儲存文件。您也可以改為自行儲存,使用 Ctrl + S (Windows/Linux) 或 ⌘ + S (Mac)。
在仍有未儲存的代理程式編輯時關閉編輯器,會像其他任何未儲存的變更一樣,詢問是否要儲存這些編輯。
Obsidian 會在編輯停止約兩秒後儲存代理程式的編輯,而關閉分頁時會直接儲存,不會詢問。
JetBrains IDE 會在編輯停止後不到一秒內寫入這些編輯,而關閉分頁時會寫入仍待處理的內容;分頁絕不會顯示為已修改。
在這兩者中,erd_save 都會立即寫入這些編輯。
erd_save 會先等待最多兩秒,直到編輯器持有代理程式所做的每一項編輯。
當編輯器無法確認這一點,或未寫入檔案時,它會以 notSaved 被拒絕:檔案在磁碟上已變更時,VS Code 會讓分頁保持未儲存,而 JetBrains IDE 則是無法寫入檔案,例如在對話方塊開啟期間,或檔案無法寫入時。
在 VS Code 和 JetBrains IDE 中,對沒有任何待儲存內容的文件呼叫 erd_save 會成功,並讓檔案保持原樣。
每項編輯都已儲存後就屬於這種情況(JetBrains IDE 會自行儲存),而只要之後的每項變更都是被鎖定擋在檔案之外的變更,例如在 Viewport 鎖定時捲動或縮放,或在 Canvas Type 鎖定時切換索引標籤,情況就會維持如此。所有鎖定預設為開啟。
即使如此,JetBrains IDE 無法寫入的檔案仍會被拒絕。
若編輯器在代理程式最後一次編輯之後關閉了該文件,代理程式的下一次呼叫會附上一則說明:只有在編輯器關閉前已儲存,這些編輯才會存在於檔案中。
復原
erd_undo 會還原代理程式所做的最後一次編輯,絕不會還原您的編輯,而 erd_redo 會重新套用該編輯。
編輯器本身的復原則正好相反:它會還原您的編輯,絕不會還原代理程式的編輯,因為從其他編輯器送達的變更不會記錄在您的歷程記錄中。
有幾種編輯不會在編輯器中產生復原步驟:設定工具中的 erd_set_database 和 erd_set_database_name,以及 erd_resize_memo。
將群組總共移動不到 20 像素(水平與垂直距離相加)的 erd_move_table_group 也不會產生復原步驟,不過群組會停留在移動後的位置。
未變更任何內容的呼叫也不會產生復原步驟:erd_set_column_primary_key、erd_set_column_unique、erd_set_column_not_null、erd_set_column_auto_increment、erd_set_index_unique 或 erd_set_index_column_order 設定的值與文件已有的值相同;erd_add_index_column 加入的欄位已在索引中;erd_set_table_group 指定的資料表已在該群組中(或在 groupId 為 null 時,已不在任何群組中);erd_move_table_group 移動到群組已在的位置;erd_resize_table_group 調整成群組已有的矩形;在沒有任何資料表的文件上呼叫 erd_sort_tables;或 mode 為 append 且未帶入任何資料表的匯入(對 erd_import_json 而言,是未帶入任何資料表也未帶入任何備忘錄)。
erd_undo 會略過這些編輯,並在其結果中列出它們。
其他編輯,例如 erd_change_relationship_type、erd_change_relationship_on_delete、erd_change_relationship_on_update、erd_change_table_group_name、erd_change_table_group_color 和 erd_set_ddl_script,即使設定的值與文件已有的值相同,也會產生復原步驟。
發生以下情況時,代理程式的復原歷程記錄會結束,並在結果中附上一則說明:
- 代理程式重新加入文件,例如在編輯器將代理程式從文件中移除之後。
- 編輯器結束,或關閉該文件並停止為其提供服務,而代理程式繼續編輯磁碟上的檔案。
- 某個編輯器接手了代理程式原本在磁碟上編輯的文件。
伺服器也會關閉代理程式 30 分鐘未呼叫過的文件,復原歷程記錄也會隨之消失,且不會附上說明。
編輯器關閉時
只要有編輯器持有文件,伺服器就絕不會自行改用檔案。 連線中斷時,伺服器會重新連線。 只有在編輯器已結束,或已關閉該文件且不再列出該文件或包含它的資料夾時,伺服器才會編輯檔案,並在結果中說明這一點。 這種情況發生於:關閉位於編輯器所服務的所有資料夾之外的圖表時(在 VS Code 中,即從工作區外開啟的圖表)、在 Obsidian 中關閉 ERD Editor 外掛程式時,以及在 JetBrains IDE 中關閉持有該文件的專案,或在其中關閉該外掛程式時。 位於編輯器所服務資料夾內的圖表即使已關閉,仍歸該編輯器管理,代理程式的下一次編輯會重新開啟它。
仍在執行,但鎖定檔案已消失,且連線在其尚未關閉該文件時就已中斷的編輯器,會以 hubGone 拒絕下一次編輯。
訊息會說明如何釋放該文件:在 VS Code 中,重新載入該視窗,或關閉它讓代理程式直接編輯檔案;在 Obsidian 中,重新開啟 ERD Editor 外掛程式,或關閉該視窗;在 JetBrains IDE 中,重新開啟該外掛程式,或結束 IDE。
在兩種情況下,讀取會改為讀取磁碟上的檔案,並附上一則說明,指出尚未在編輯器中儲存的編輯不會包含在內:持有該文件的編輯器的 hub 已關閉時,以及上述 hubGone 的情況。
無法連線到編輯器 hub 的讀取,會與編輯一樣以 hubUnreachable 被拒絕。
無介面
沒有編輯器為該文件提供服務時,每次編輯都會載入檔案、套用變更,然後將檔案寫回。
寫入會先寫到文件旁一個名為 .<name>.<id>.tmp 的暫存檔案,再以它取代文件,因此文件絕不會處於寫到一半的狀態,但下文所述 Windows 上就地寫入的情況除外。
在最後這一步之前,伺服器會檢查檔案在呼叫期間是否已在磁碟上變更。
若已變更,則不會寫入任何內容,檔案會重新載入,且該呼叫會以 conflict 被拒絕。代理程式會再呼叫一次。
在兩次呼叫之間變更的檔案只會重新載入,而代理程式在此之前的復原歷程記錄會被捨棄。
唯讀檔案會保持原樣,且編輯會以 readonly 被拒絕:擁有者沒有寫入權限的檔案,或在 Windows 上具有唯讀屬性的檔案,例如尚未簽出的 Perforce 或 TFVC 檔案。
請將檔案設為可寫入,然後再呼叫一次。讀取仍可運作。
若在代理程式編輯磁碟上的文件期間,有編輯器開始為該文件提供服務,該次編輯會以 hubAppeared 被拒絕,且不會寫入任何內容。下一次呼叫會透過該編輯器進行編輯。
在 Windows 上,另外適用兩條規則:
- 具有與其資料夾不同之專屬權限的文件會就地寫入,而不是被取代,以保留這些權限,且暫存檔案會在之後移除。在寫入期間讀取該文件的程式,可能會讀到無法剖析的文字。
- 被其他程式開啟佔用的檔案無法被取代,因此伺服器會在最多兩秒內重試。每次重試都會先重新尋找編輯器,而在此期間開始為該文件提供服務的編輯器會以
hubAppeared拒絕寫入,若其 hub 已關閉則以blocked拒絕。若兩秒後檔案仍被佔用,則不會寫入任何內容,檔案會重新載入,且該呼叫會失敗,並附上引述系統錯誤的訊息。
拒絕
即使 hub 已關閉,VS Code 視窗仍會保留其鎖定檔案:dineug.erd-editor.agentHub.enabled 關閉時、工作區不受信任時,或其 hub 無法監聽時。
Obsidian 儲存庫視窗在 Coding agents 關閉時,以及其 hub 無法監聽時,會在 hub 關閉的狀態下保留其鎖定檔案。
JetBrains IDE 在 Coding agents 關閉時、其 hub 無法監聽時,以及 IDE 結束期間,會在 hub 關閉的狀態下保留其鎖定檔案。
對這類文件的編輯會以 blocked 被拒絕,因為開啟中的編輯器可能會在下一次儲存時,覆寫寫入檔案的變更。
讀取仍可運作,會從磁碟上的檔案讀取。
若要讓代理程式編輯,請依照訊息針對該編輯器的說明重新開啟 hub:在 VS Code 中,信任該工作區並開啟該設定,或重新載入視窗;在 Obsidian 中,開啟 Coding agents,或重新載入 Obsidian;在 JetBrains IDE 中,開啟 Coding agents,或在其已開啟時重新啟動 IDE。
JetBrains IDE 也會以 hubDisabled 拒絕變更僅由其不信任的專案所持有的文件。
代理程式仍可讀取這類文件,且 erd_list_documents 會將其列為 readonly。請信任該專案,然後再呼叫一次。
不保留鎖定檔案的編輯器不會提供任何保護,即使圖表在該編輯器中開啟,代理程式也會編輯磁碟上的檔案。
在 Linux 上以 Flatpak 安裝的 Obsidian 或 JetBrains IDE、沒有 JCEF 的 JetBrains IDE,以及 hub 無法啟動的 JetBrains IDE 都屬於這種情況,請參閱設定 Obsidian 和設定 JetBrains IDE。
3.0.0 之前的 VS Code 擴充功能和 0.9.0 之前的 JetBrains 外掛程式也不保留鎖定檔案,因為它們沒有 hub。
文件
文件以 path 指定,可以是絕對路徑,或相對於伺服器工作目錄的路徑。
- 新文件為
.erd.json。使用create的erd_open_document會建立檔案,並為沒有副檔名的名稱加上.erd.json。與編輯器中的新圖表一樣,新文件的每個鎖定都處於開啟狀態,因此在編輯器中捲動、縮放、切換索引標籤,或選擇其他程式碼產生器語言、名稱大小寫或引號類型,都絕不會變更檔案。沒有任何工具能單獨開啟或關閉某個鎖定:這需在編輯器的「設定」索引標籤中進行。replace模式的erd_import_json會將所有鎖定取代為其載入之文件的鎖定,請參閱匯入。 - 現有的
.erd、.vuerd和.vuerd.json檔案也能開啟。具有其他任何副檔名的路徑會以invalidPath被拒絕。 - 在 Windows 上,包含 Windows 不會依原樣儲存之名稱的路徑,會在讀取或寫入文件之前以
invalidPath被拒絕,包括讀取:含有冒號或其他 Windows 拒絕之字元的名稱,例如orders:v2.erd;裝置名稱,例如NUL.erd或CON.erd,不論大小寫;或以句點或空格結尾的名稱。請重新命名,例如以-取代:。 - 不是編輯器可讀取之文件的檔案,例如殘留合併衝突標記的檔案,會以
invalidDocument被拒絕並保持原樣。它絕不會被當作空白圖表載入後再寫回。
代理程式只會透過工具變更文件,且會被告知絕不要自行寫入檔案。
erd_list_documents 會列出文件及其 path、open、active、dirty 和 readonly。
它會詢問為工作目錄提供服務的編輯器(選擇方式與文件相同),並先列出在其中開啟的圖表,再列出它所服務的 ERD 檔案:VS Code 視窗之工作區資料夾中的檔案、Obsidian 儲存庫中的檔案,或 JetBrains IDE 中開啟的每個專案中的檔案。
否則,它會列出工作目錄下的 ERD 檔案,其中唯讀檔案會標示為 readonly,而在 Windows 上,Windows 不會依原樣儲存的名稱會被省略。