Режимы Live и Headless
При каждом вызове сервер ищет редактор, в котором находится документ, по файлам блокировки, которые редакторы хранят в ~/.erd-editor/ide/.
Свой файл хранит каждое окно VS Code и каждое окно хранилища Obsidian с ERD Editor, а IDE JetBrains хранит один файл на всю IDE и перечисляет в нем все открытые в ней проекты.
При закрытии редактор удаляет свой файл блокировки.
От того, что найдет сервер, зависит, куда пойдет правка.
| Что найдено | Что делает правка |
|---|---|
| Редактор, в рабочей области, хранилище или открытом проекте которого находится документ, либо редактор, в котором он открыт | Live. При необходимости открывает документ в ERD Editor, подключается к сеансу редактирования и применяет изменение там. Правки появляются сразу и сохраняются так же, как редактор сохраняет ваши собственные, — см. Сохранение. |
| Редактора нет | Headless. Загружает файл, применяет изменение и заменяет файл до ответа, поэтому в результате указано saved: true, а инструменту erd_save нечего делать. |
| Редактор с выключенным хабом | Отказ. Чтение по-прежнему работает — с диска. Изменение, записанное в файл в обход открытого редактора, может быть перезаписано при следующем сохранении в этом редакторе, поэтому сервер ничего не записывает. |
Редактор, хаб которого включен, но который использует протокол, отличный от протокола сервера: с сервером версии 1.0.0 или новее — расширение VS Code версии 3.x, плагин Obsidian версии 0.x или плагин JetBrains версии 0.9.0 или 0.10.0; с сервером до версии 1.0.0 — расширение версии 4.0.0 или новее либо плагин версии 1.0.0 или новее | Отказ, в том числе при чтении, с кодом protocolMismatch. В сообщении указано, какую сторону нужно обновить: расширение или плагин либо сервер, — см. Обновление. |
В Windows — редактор, в котором документ числится под другим путем к тому же файлу: агент указал его через общий сетевой ресурс или подключенный сетевой диск этого компьютера, например \\localhost\C$\…, а в редакторе он числится по пути с буквой диска, или наоборот | Отказ, в том числе при чтении, с кодом invalidPath. В сообщении указан путь, под которым документ числится в редакторе; повторите вызов с этим путем. |
| В Windows — редактор, к которому Windows не допускает агента: редактор, запущенный от имени администратора, когда агент запущен без этих прав, или любой редактор, когда агент работает в песочнице | Отказ, в том числе при чтении, с кодом hubUnreachable и сообщением, в котором объяснена причина. Запустите редактор и агента с одинаковыми правами, например перезапустив редактор без прав администратора. |
В результате правки указан режим, в котором она выполнялась, — live или headless, а отклоненная правка сообщает причину отказа.
Поиск выполняется заново при каждом вызове, поэтому от открытия или закрытия редактора зависит, куда пойдет следующий вызов.
Если документ находится сразу в нескольких редакторах, редактор, в котором он открыт, имеет приоритет перед редактором, который только обслуживает содержащую его папку, а среди редакторов, обслуживающих папку, выигрывает тот, чья папка вложена глубже всех. При равенстве, например если документ открыт в двух редакторах, выбирается тот, чей файл блокировки изменился последним. Поэтому документ в хранилище Obsidian, которое лежит в папке рабочей области VS Code, достается Obsidian, кроме случая, когда он открыт в VS Code, но не открыт в Obsidian.
Вызовы для одного документа выполняются по одному в том порядке, в котором они поступили на сервер. Вызовы для разных документов выполняются параллельно.
Live
Агент подключается к редактору как еще один соавтор. Его правки сразу доходят до всех редакторов, в которых открыт документ, а его фокус отображается на таблице и ячейке, которые он редактирует, так же как фокус соавтора, — см. focusTracker.
Чтение никогда не открывает редактор. Правка открывает документ в ERD Editor, если он еще не открыт, и при этом не забирает фокус клавиатуры.
Редактор с расширением VS Code до версии 4.2.0 или плагином Obsidian или JetBrains до версии 1.2.0 по-прежнему принимает правки агента вживую, но не показывает и не сохраняет логические имена, привязки к доменам и строки словарей, которые записывает агент, — см. Обновление.
При расширении VS Code версии 4.3.0 или новее либо плагине Obsidian или JetBrains версии 1.3.0 или новее импорт в режиме replace и erd_undo или erd_redo такого импорта завершают рисуемую в редакторе связь, какой бы ни была версия сервера — см. Создание связи.
В более ранних версиях рисование оставалось активным, и щелчок по таблице мог добавить связь от таблицы, которой в диаграмме уже нет.
Импорт в режиме append оставляет рисование активным.
Открытый вами редактор заметки, имени группы таблиц или ячейки остается открытым, пока диаграмма по-прежнему содержит то, что он редактирует, и показывает это.
Правки, сделанные в один и тот же момент
Если сервер версии 1.2.0 или новее, а в редакторе установлено расширение VS Code версии 4.3.0 или новее либо плагин Obsidian или JetBrains версии 1.3.0 или новее, правки, которые вы и агент в один и тот же момент вносите в одно и то же, приходят к одному результату в редакторе, в сохраняемом им файле и в том, что erd_list, erd_get и erd_read выдают агенту.
Это относится к имени или другому полю таблицы, столбца, связи, индекса, заметки, группы таблиц или строки словаря, имени базы данных и скриптам перед таблицами и после них, а также к положению или размеру таблицы, заметки или группы таблиц, но не к цвету, порядку столбцов в таблице или индексе и не к базе данных.
Две правки одного имени или поля, два перемещения или два изменения размера заканчиваются на одной из двух правок, а не на их смеси: побеждает правка, сделанная после того, как другая дошла до ее стороны, а из двух правок, сделанных в один и тот же момент, побеждает одна и та же на каждой стороне, какая бы ни пришла первой.
Два изменения цвета одной таблицы, заметки или группы таблиц, сделанные в один и тот же момент, например ваше и erd_change_table_color агента, могут закончиться по-разному, а то и поменяться местами, так как каждая сторона сохраняет цвет, который получила последним.
Изменение порядка столбцов, ваше или erd_move_column либо erd_move_index_column агента, применяется на каждой стороне в порядке прихода, поэтому два таких изменения, сделанные в один и тот же момент в одной таблице или индексе, могут оставить столбцы в разном порядке.
Изменение базы данных, ваше или erd_set_database агента, тоже применяется в порядке прихода, поэтому два таких изменения, сделанные в один и тот же момент, могут оставить редактор и агента на разных базах данных.
Ваше перетаскивание и erd_move_table, erd_move_tables, erd_move_memo, erd_move_table_group и erd_sort_tables агента передаются как точки, в которых они заканчиваются, поэтому два перемещения одной таблицы, заметки или группы таблиц заканчиваются там, куда ее поставило одно из них, и никогда — в сумме обоих.
erd_move_table_group отправляет точку группы и каждой из ее таблиц одним пакетом, как перетаскивание строки заголовка группы.
Изменение размера записывает положение и размер вместе, поэтому перемещение и изменение размера одной заметки или группы таблиц, сделанные в один и тот же момент, например erd_resize_memo, пока вы перетаскиваете эту заметку, заканчиваются одним и тем же прямоугольником на обеих сторонах: прямоугольником изменения размера или, если побеждает перемещение, точкой перемещения с размером из изменения размера.
Перемещение меньше чем на 20 пикселей, не создающее шага отмены, тоже отправляется как точка, в которой оно заканчивается, поэтому оно может победить перемещение другой стороны, будь то короткий erd_move_table_group или ваше короткое перетаскивание, например щелчок, сдвигающий таблицу на несколько пикселей.
Более ранние версии по-прежнему подключаются, так как сервер версии 1.2.0 использует протокол хаба 2, как и версии с 1.0.0 по 1.1.1.
При сервере до версии 1.2.0, расширении до версии 4.3.0 или плагине до версии 1.3.0 перемещение или изменение размера одной таблицы, заметки или группы таблиц, сделанное в один и тот же момент, может оставить редактор и агента с разными позициями.
Редактор более старой версии отправляет ваше перетаскивание как пройденное расстояние, и сервер до версии 1.2.0 отправляет erd_move_table_group так же.
Другая сторона прибавляет это расстояние к точке, которая у нее есть.
Сторона с более старой версией к тому же применяет точки другой стороны в порядке их прихода.
Тогда агент читает и редактирует эту таблицу, заметку или группу таблиц исходя из собственной позиции, а не той, которую показывает и сохраняет редактор.
Так продолжается, пока более позднее ее перемещение не будет передано как точка, например ваше перетаскивание в более новом редакторе или erd_move_table агента, или пока агент не подключится к документу заново, как после того, как редактор отключил его, или после 30 минут без вызовов для документа.
Кроме цвета, порядка столбцов и базы данных, имя или другое поле, измененное в один и тот же момент, по-прежнему приходит к одному результату, когда более старая версия только у одной стороны, почти всегда — к правке более новой стороны.
Если более старые версии у обеих сторон, результаты все же могут разойтись.
Ничто из этого не относится к правке в режиме Headless, которая записывает только файл.
Сохранение
Каждый редактор сохраняет правки агента так же, как ваши собственные.
В VS Code правки агента, как и ваши собственные, помечают вкладку как измененную и попадают на диск только при сохранении документа.
Инструмент erd_save сохраняет его через VS Code, как это делает собственная команда сохранения VS Code. Вместо этого можно сохранить документ самостоятельно с помощью Ctrl + S (Windows/Linux) или ⌘ + S (Mac).
Если закрыть редактор с несохраненными правками агента, появится вопрос, сохранить ли их, как и для любого другого несохраненного изменения.
Obsidian сохраняет правки агента примерно через две секунды после окончания редактирования, а при закрытии вкладки сохраняет их без вопросов.
IDE JetBrains записывает их через долю секунды после окончания редактирования, а при закрытии вкладки записывает то, что еще ожидает записи; вкладка никогда не помечается как измененная.
В обоих случаях инструмент erd_save записывает их сразу.
Инструмент erd_save сначала ждет до двух секунд, пока в редакторе не окажутся все правки, сделанные агентом.
Вызов отклоняется с кодом notSaved, если редактор не смог это подтвердить или не записал файл: VS Code оставляет вкладку несохраненной, если файл изменился на диске, а IDE JetBrains не смогла его записать, например пока было открыто окно или когда файл недоступен для записи.
В VS Code и IDE JetBrains вызов erd_save для документа, в котором уже нечего сохранять, завершается успешно и оставляет файл без изменений.
Так бывает, как только все правки сохранены, что IDE JetBrains делает самостоятельно, и так остается, пока каждое последующее изменение — из тех, которые блокировка не пропускает в файл, например прокрутка или масштабирование при включенной блокировке Viewport, переключение вкладок при включенной блокировке Canvas Type или переключение режима отображения имен при включенной блокировке Name View. Все блокировки включены по умолчанию.
Если IDE JetBrains не может записать файл, вызов отклоняется даже в этом случае.
Если редактор закрывает документ после последней правки агента, следующий вызов агента содержит примечание о том, что эти правки есть в файле, только если они были сохранены до закрытия редактора.
Отмена изменений
Инструмент erd_undo отменяет последнюю правку, сделанную агентом, но никогда не ваши правки, а erd_redo применяет ее снова.
Собственная Отмена редактора работает наоборот: она отменяет ваши правки и никогда — правки агента, поскольку изменения, поступающие из другого редактора, не записываются в вашу историю изменений.
Некоторые правки не создают в редакторе шага отмены: erd_set_database и erd_set_database_name из инструментов настроек, а также erd_resize_memo.
Не создает его и вызов erd_move_table_group, который сдвигает группу в сумме меньше чем на 20 пикселей, если сложить сдвиг по горизонтали и по вертикали, хотя группа остается там, куда ее сдвинули.
Шага отмены не создает и вызов, который ничего не меняет: 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 с таблицами, которые уже входят в эту группу (или уже не входят ни в одну, при значении null аргумента groupId); erd_move_table_group в точку, где группа уже находится; erd_resize_table_group с прямоугольником, который у группы уже есть; erd_sort_tables для документа без таблиц; erd_set_table_logical_name или erd_set_column_logical_name с логическим именем, которое уже есть у таблицы или столбца, если формирование имени по нему ничего бы не изменило; erd_set_column_domain с доменом, к которому столбец уже привязан, если у столбца уже есть тип этого домена и Синхронизация типа данных в связях не изменила бы тип ни одного столбца вдоль его связей; erd_update_word, erd_update_term или erd_update_domain только со значениями, которые уже есть в строке, кроме случая, когда термину без физического имени передается аргумент name и его слова составляют физическое имя; erd_derive_physical_names, если каждое охватываемое им имя, у которого есть логическое имя, уже содержит то, что дают ему словари, и помечено как сформированное; или импорт, который при значении append аргумента mode не добавляет ни одной таблицы (для 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 — диаграммы, открытой не из рабочей области), при выключении плагина ERD Editor в Obsidian, а также при закрытии проекта с этим документом в IDE JetBrains или выключении плагина там. Закрытая диаграмма внутри папки, которую обслуживает редактор, остается за редактором, и следующая правка агента снова ее открывает.
Редактор, который все еще работает, но у которого пропал файл блокировки, а соединение закрылось, хотя он не закрыл документ, отклоняет следующую правку с кодом hubGone.
В сообщении сказано, что освободит документ: в VS Code перезагрузите это окно или закройте его, чтобы агент редактировал файл напрямую; в Obsidian снова включите плагин ERD Editor или закройте это окно; в IDE JetBrains снова включите плагин или закройте IDE.
Чтение вместо редактора обращается к файлу на диске — с примечанием, что в нем нет правок, еще не сохраненных в редакторе, — в двух случаях: когда у редактора, в котором находится документ, выключен хаб, и в описанном выше случае с hubGone.
Чтение, которое не может подключиться к хабу редактора, отклоняется с кодом hubUnreachable, так же как и правка.
Headless
Если документ не обслуживает ни один редактор, каждая правка загружает файл, применяет изменение и записывает файл обратно до ответа, поэтому в ее результате указано saved: true — см. Результаты.
Запись идет во временный файл .<name>.<id>.tmp рядом с документом, и затем этот файл заменяет документ, поэтому документ никогда не остается записанным наполовину, кроме описанного ниже случая записи на месте в Windows.
Перед этим последним шагом сервер проверяет, не изменился ли файл на диске во время вызова.
Если изменился, ничего не записывается, файл загружается заново, а вызов отклоняется с кодом conflict. Агент повторяет вызов.
Файл, изменившийся между двумя вызовами, просто загружается заново, а предшествующая этому история изменений агента отбрасывается.
Файл только для чтения остается без изменений, а правка отклоняется с кодом readonly: это файл без права на запись для владельца или с атрибутом «только для чтения» в Windows, например файл Perforce или TFVC, который не извлечен для редактирования.
Сделайте его доступным для записи, затем повторите вызов. Чтение по-прежнему работает.
Если редактор начинает обслуживать документ, пока агент редактирует его на диске, эта одна правка отклоняется с кодом hubAppeared и ничего не записывается. Следующий вызов уже редактирует через редактор.
В Windows действуют еще два правила:
- Документ с собственными разрешениями, отличающимися от разрешений его папки, записывается на месте, а не заменяется, чтобы сохранить их, а временный файл после этого удаляется. Программа, которая читает документ во время такой записи, может получить текст, который не удается разобрать.
- Файл, который держит открытым другая программа, нельзя заменить, поэтому сервер повторяет попытки в течение не более двух секунд. Каждая попытка сначала снова ищет редактор, и редактор, который за это время начал обслуживать документ, отклоняет запись с кодом
hubAppearedили, если его хаб выключен, с кодомblocked. Если через две секунды файл все еще занят, ничего не записывается, файл загружается заново, а вызов завершается ошибкой с сообщением, в котором приведена системная ошибка.
Сервер до версии 1.1.0 читает документ без логических имен, привязок столбцов к доменам и без слов, терминов и доменов, поэтому первая же правка, которую он записывает в файл, их не сохраняет. Обновите сервер — см. Обновление.
Отказ
Окно VS Code оставляет свой файл блокировки, даже когда его хаб выключен: когда выключена настройка dineug.erd-editor.agentHub.enabled, когда рабочая область не является доверенной или когда его хаб не смог начать прослушивание.
Окно хранилища Obsidian оставляет свой файл блокировки при выключенном хабе, когда выключен параметр Coding agents, а также когда его хаб не смог начать прослушивание.
IDE JetBrains оставляет свой файл блокировки при выключенном хабе, когда выключен параметр Coding agents, когда ее хаб не смог начать прослушивание, а также пока IDE завершает работу.
Правка такого документа отклоняется с кодом blocked, так как открытый редактор может перезаписать изменение, записанное в файл, при своем следующем сохранении.
Чтение по-прежнему работает — из файла на диске.
Чтобы агент мог редактировать, снова включите хаб так, как сказано в сообщении для этого редактора: в VS Code отметьте рабочую область как доверенную и включите настройку или перезагрузите окно; в Obsidian включите параметр Coding agents или перезагрузите Obsidian; в IDE JetBrains включите параметр Coding agents или, если он уже включен, перезапустите IDE.
Кроме того, IDE JetBrains отказывается — с кодом hubDisabled — изменять документ, который находится только в проектах, которым она не доверяет.
Агенты по-прежнему могут читать такой документ, а инструмент erd_list_documents выводит его с пометкой readonly. Отметьте проект как доверенный, затем повторите вызов.
Редактор, у которого нет файла блокировки, ничего не защищает, и агент редактирует файл на диске, даже пока диаграмма в нем открыта.
Так обстоит дело с Obsidian или IDE JetBrains, установленными как Flatpak в Linux, с IDE JetBrains без JCEF и с IDE JetBrains, хаб которой не смог запуститься, — см. Настройка Obsidian и Настройка IDE JetBrains.
Расширение VS Code до версии 3.0.0 и плагин JetBrains до версии 0.9.0 тоже не создают такого файла, так как у них нет хаба.
Документы
Документ задается аргументом path — абсолютным путем или путем относительно рабочего каталога сервера.
- Новые документы — это файлы
.erd.json. Инструментerd_open_documentс аргументомcreateсоздает файл, добавляя.erd.jsonк имени без расширения. Как и у новой диаграммы в редакторе, у нового документа включены все блокировки, поэтому прокрутка, масштабирование, переключение вкладок, переключение режима отображения имен или выбор другого языка Генератора кода, стиля имен или типа кавычек в редакторе никогда не меняют файл. Ни один инструмент не включает и не выключает отдельную блокировку: это делается на вкладке «Настройки» редактора. Инструментerd_import_jsonв режимеreplaceзаменяет их все блокировками загружаемого документа — см. Импорт. - Существующие файлы
.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 или во всех проектах, открытых в IDE JetBrains.
В противном случае он выводит ERD-файлы в рабочем каталоге, причем файл только для чтения помечается как readonly, а файл с именем, которое Windows не сохраняет в том виде, в каком оно написано, в Windows не отображается.