Model
Введение
Model
- это объект, который является проекцией физической базой данных
в приложении. Он связан с определенной базой данных и предоставляет
доступ к ней (например выполнение запросов). А также является
хранилищем логических знаний о своей базе данных.
Описание модели
Пример описания:
<root>
<dbm>
<!-- прототип модель -->
<model name="jandcode.examples5.dbm1">
<include name="jandcode.core.dbm"/>
<x-include path="model/index.cfx"/>
</model>
<!-- экземпляр модели -->
<model name="default" instance="jandcode.examples5.dbm1">
<dbsource name="default" dbdriver="mysql"/>
</model>
</dbm>
</root>
Существует 2 варианта описания модели:
- прототип модели. Экземпляры таких моделей обычно не создаются и не используются. Имя модели обычно уникальное, длинное и чаще всего совпадает с именем модуля, в котором модель описана. Можно рассматривать как "абстрактный класс модели".
- экземпляр модели. Экземляры таких моделей непосредственно используются
в приложении. Такая модель обычно в приложении одна, по соглашению имеет имя
default
. Можно рассматривать как "экземпляр объекта".
Основное отличие экземпляра модели от прототипа модели: экземпляр модели не должен определять никакие дополнительные объекты, влияющие на структуру модели.
Описание модели можно рассматривать как некий "пакет", в рамках которого собирается информация об объектах модели:
<root>
<dbm>
<model name="my-model1">
<field name="name.long" parent="string" size="255"/>
<domain name="domain1">
<field name="f1" parent="string"/>
<field name="f2" parent="string"/>
</domain>
<domain name="domain2">
<field name="f1" parent="string"/>
<field name="f2" parent="string"/>
</domain>
</model>
</dbm>
</root>
Обычно так конечно писать не нужно. Объекты модели включаются в модель посредством
тега x-include
, который обычно указывает на файл model/model.cfx
, который уже
и загружает все объекты этой модели.
Зависимости моделей
Зависимости моделей реализованы посредством "включения" одной модели в другую.
Для этого используется тег include
, где в атрибуте name
указывается имя
включаемой модели.
Пример:
<root>
<dbm>
<model name="my-model1">
</model>
<model name="my-model2">
</model>
<model name="my-model3">
<include name="my-model1"/>
</model>
<model name="my-model4">
<include name="my-model1"/>
<include name="my-model3"/>
</model>
<model name="my-model5">
<include name="my-model2"/>
<include name="my-model4"/>
</model>
<model name="my-model6-inst" instance="my-model5">
</model>
</dbm>
</root>
При загрузке такого описание мы имеем 5 моделей, каждая из которых включает только
то, что непосредствено описано в теге model
, в том числе перечисление
включаемых моделей.
При создании экземляра модели jandcode.core.dbm.Model
по описанию в теге model
происходит последовательное объединениние всех включаемых моделей в одну структуру
Conf
, по которой уже создается экземпляр jandcode.core.dbm.Model
.
В приведенном выше примере, при создании модели для my-model5
, происходит следующее:
- формируется список всех моделей, явно или неявно включенных в
my-model5
. В данном случае этот список выглядет так:my-model2
- явно включена, не имеет зависимостейmy-model1
- включена не явно, через включение вmy-model4
my-model3
- включена не явно, через включение вmy-model4
my-model4
- явно включена, зависимости уже в спискеmy-model5
- рассматриваемая модель, последняя в списке
- создается новый пустой объект
Conf
- в этот объект последовательно накладываются структуры всех моделей из сформированного списка зависимости моделей
- по объединенной структуре создается экземпляр объекта
jandcode.core.dbm.Model
При созданиеи экземпляра модели (в примере my-model6-inst
), список зависимостей
формируется для модели, указанной в атрибуте instance
и к этому списку добавляется
искомая модель.
В приведенном выше примере, при создании модели для my-model6-inst
список
зависимостей будет выглядеть так:
my-model2
my-model1
my-model3
my-model4
my-model5
my-model6-inst
Параметры базы данных
Экземпляр модели может иметь только одну базу данных.
Параметры базы данных указываются в теге <dbsource name="default"/>
.
Атрибут dbdriver
определяет драйвер базы данных. От драйвера
зависит набор свойств, которые допустимы при конфигурировании базы данных.
Среди прочих атрибутов, у dbsource
имеется атрибут cfg
, в котором указывается
conf-путь, откуда брать конфигурацию базы данных модели.
По умолчанию значение атрибута cfg="cfg/dbsource/${modelName}"
, т.е. конфигурация
базы данных хранится в теге cfg/dbsource/ИМЯ-МОДЕЛИ
.
В атрибуте cfg
можно использовать подстановки ${ATTR}
, где ATTR
- значение
атрибута из тега dbsource
в модели.
На практике dbsource
должна настраиваться только в экземплярах модели.
Кроме того, в файле module.cfx
не нужно указывать никакие конкретные свойства
базы данных (например host, username и т.д.). Все эти настройки нужно выносить
в app.cfx
(или _app.cfx
).
Пример настройки базы данных модели:
<root>
<!-- module.cfx -->
<dbm>
<model name="default" instance="jandcode.examples5.dbm1">
<dbsource name="default" dbdriver="mariadb"/>
</model>
</dbm>
<!-- app.cfx -->
<cfg>
<dbsource name="default"
host="localhost"
database="jandcode_examples5_dbm1__DEV"
username="root"
/>
</cfg>
</root>
Конфигурация module.cfx
dbm/model
Описание модели.
Формат:
<root>
<dbm>
<!-- прототип модели -->
<model name="MODEL-NAME">
<include name="MODEL-NAME"/>
<x-include path="PATH"/>
</model>
<!-- экземпляр модели -->
<model name="MODEL-NAME" instance="MODEL-NAME">
<dbsource name="default" dbdriver="DRIVER-NAME"/>
</model>
</dbm>
</root>
Атрибуты:
instance
- при наличии этого атрибута модель является экземпляром модели, указанной в значении атрибута
Дочерние элементы:
<include name="MODEL-NAME"/>
- включение зависимости от другой модели. Используется только в прототипах модели.<dbsource name="default"/>
- свойстваDbSource
этой модели. Обычно используется только в экземплярах модели.