Model

Связи
  • jandcode.core.dbm.Model (class)
  • jandcode.core.dbm.ModelService (class)
  • jandcode.core.dbm.ModelDef (class)

Введение

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 этой модели. Обычно используется только в экземплярах модели.