Миграция
Информационная система, разработанная на базе платформы lsFusion, использует в качестве постоянного хранилища данных реляционную систему управления базами данных. При этом необходимо учитывать, что после определенных изменений логики системы платформа не может определить, каким образом нужно мигрировать данные. В таких случаях разработчик обязан явно указывать способ миграции путем создания специального миграционного файла migration.script
, который должен находиться в CLASSPATH сервера приложения.
Миграционный файл состоит из блоков, которые описывают изменения, произведенные в указанной версии структуры базы данн ых. При старте сервера применяются все изменения из миграционного файла, которые имеют версию выше, чем версия, хранящаяся в базе данных. Изменения применяются в соответствии с версией, от меньшей версии к большей. Если изменение структуры БД происходит успешно, то максимальная версия из всех примененных блоков записывается в базу данных в качестве текущей. Синтаксис описания каждого блока выглядит следующим образом:
V<номер версии> {
изменение1
...
изменениеN
}
Номер версии представляет собой набор из одного или нескольких чисел разделенных точкой. При сравнении номеров двух версий сравниваются сначала первые числа версий, при их равенстве вторые и т. д. Если в одном номере версии меньше чисел, чем в другом, то при сравнении версия с меньшим количеством чисел дополняется нолями. То есть номер версии 1.3
эквивалентен номеру 1.3.0.0
, а версия 1.2
больше версии 1.1.3
. В миграционном файле номер версии указывается вместе с заглавной буквой V
: V1.0
, V2.0.11
.
Миграционный файл позволяет обрабатывать изменения канонических имен элементов системы, которые происходят при переименовании и/или переносе в другое пространство имен. Изменения бывают следующих типов:
PROPERTY oldNS.oldName[class1,...,classN] -> newNS.newName[class1,...,classN]
STORED PROPERTY oldNS.oldName[class1,...,classN] -> newNS.newName[class1,...,classN]
FORM PROPERTY oldNS.oldFormName.oldName(object1,...,objectN) -> newNS.newFormName.newName(object1,...,objectN)
CLASS oldNS.oldName -> newNS.newName
OBJECT oldNS.oldClassName.oldName -> newNS.newClassName.newName
TABLE oldNS.oldName -> newNS.newName
NAVIGATOR oldNS.oldName -> newNS.newName
Изменение имени свойства или действия
При переименовании свойства (действия) и/или при переносе его в другое пространство имен происходит изменение канонического имени этого свойства (действия). Добавление изменения типа PROPERTY
в файл миграции с указанием старого и нового канонических имен позволит сохранить настройки политики безопасности, а также настройки из таблицы Reflection.properties
. Если же свойство является первичным, то для сохранения данных при изменении канонического имени такого свойства необходимо добавить изменение типа STORED PROPERTY
. Тогда при запуске сервера соответствующее этому свойству поле в таблице БД будет переименовано. В противном случае старое поле будет переименовано в поле с именем <старый идентификатор>_deleted
, как в случае удаления свойства, а новое поле будет создано с пустыми значениями. В остальном тип STORED PROPERTY
эквивалентен типу PROPERTY
.
В правой части изменений типа STORED PROPERTY
и PROPERTY
необязательно указывать сигнатуру, в этом случае сигнатура автоматически возьмется из левой части.
Изменение имени свойства (действия) на форме
При изменении имени свойства на форме с помощью миграционного файла можно сохранить информацию из настройки таблиц для этого свойства (действия) на форме, для этого иcпользуется тип изменения FORM PROPERTY
. В качестве старого и нового имен выступают имя пространства имен формы, имя формы и имя свойства на форме, перечисленные через точку. Также с помощью этого типа изменения можно сохранить информацию из настройки таблиц при изменении канонического имени формы. Для этого необходимо добавить в миграционный файл изменения типа FORM PROPERTY
для всех свойств (действий) на форме с измененным каноническим именем формы.
Изменение имени пользовательского класса
При переименовании пользовательского класса и/или переносе его в другое пространство имен происходит изменение канонического имени этого класса. В этом случае необходимо отразить эти изменения в миграционном файле, чтобы сохранить объекты этого класса и все связанные с этими объектами данные. Для этого нужно добавить в миграционный файл изменение типа CLASS
с указанием старого и нового канонических имен класса. Это также автоматически переименует статические объекты этого класса, если они существуют.
При изменении канонического имени класса необходимо учитывать, что это может повлечь за собой изменения канонических имен первичных свойств. На данный момент автоматически эти изменения не отслеживаются, и их необходимо также добавлять в миграционный файл.
Изменение имени статического объекта
При переименовании статического объекта используется изменение типа OBJECT
, которое позволяет сохранить данные, связанные с этим объектом. В качестве старого и нового имен выступают имя пространства имен класса, имя класса и имя объекта, перечисленные через точку.
Изменение имени таблицы
При переименовании таблицы и/или переносе ее в другое пространство имен происходит изменение канонического имени таблицы. В этом случае система после создания таблицы с новым именем автоматически перенесет отдельным запросом все записи из таблицы со старым именем. Однако, если добавить в миграционный файл изменение типа TABLE
с указанием старого и нового канонических имен таблицы, то будет выполнен запрос на переименование старой таблицы, что будет значительно быстрее.
Изменение имени элемента навигатора
При переименовании элемента навигатора и/или переносе его в другое пространство имен происходит изменение канонического имени этого элемента. Для того, чтобы сохранить связанные с этим элементом настройки политики безопасности, нужно добавить в миграционный файл изменение типа NAVIGATOR
с указанием старого и нового канонических имен элемента навигатора.
Изменение имени пространства имен
Так как имя пространства имен используется в канонических именах элементов системы, то его изменение приводит к изменению канонических имен элементов системы, которые в него входят. Таким образом, в случае изменения имени пространства имен необходимо поместить в файл миграции информацию о всех вышеописанных элементах. То же самое нужно делать при перемещении элементов системы между разными пространствами имен.
Пример
migration.script
V0.3.1 {
STORED PROPERTY Item.gender[Item.Article] -> Item.dataGender[Item.Article] // измен ение имени DATA свойства
PROPERTY System.SIDProperty[Reflection.Property] -> Reflection.dbNameProperty[Reflection.Property] // одновременный перенос в другое пространство имен и изменение имени свойства
FORM PROPERTY Item.itemForm.name(i) -> Item.itemForm.itemName(i)
}
V0.4 {
FORM PROPERTY Document.documentForm.name(i) -> Document.itemForm.itemName(i)
FORM PROPERTY Item.itemForm.itemName(i) -> Item.itemForm.iname // добавление явного имени для свойства на форме: iname = itemName(i)
CLASS Date.DateInterval -> Date.Interval
OBJECT Geo.Direction.North -> Geo.Direction.north
TABLE User.oldTable -> User.newTable
}