Использование API

Untitled-1.png

Особенностью работы с данными в Mozart можно считать то, что оперировать с ними в системе надо как с объектами. Представьте себе все таблицы Базы Данных, их связи как набор объектов терминологического поля, связанных между собой. Этим объектам можно дать "человеческие" названия и построить граф, как на рисунке выше. Вы можете ознакомиться со статьей "Архитектура предметной области в CMF/CMS системах" в нашем блоге, в которой кратко рассказывается, какие алгоритмы использует Mozart в такой архитектуре.

Простая жизненная ситуация по созданию системы для оператора мобильной связи может быть изображена как набор объектов реальной жизни, связанных между собой. На графе описывается ситуация с сотовой связью: оператор - регион - тариф - симкарта(номер) - контракт - телефон - брэнд - человек - где прописан.

На основании такой структуры мы можем строить произвольные запросы для получения данных. Возьмем для примера несколько ситуаций, в которых используются различные условия:

Каким брэндом пользуются люди, чей возраст от 20 до 30 лет:

<newt:base>
 <request>
  <set object="user" attr="age" min="20" max="30">
   <get object="brand" />
  </set>
 </request>
</newt:base>

Для ограничения возраста Человека мы использовали операторы min и max. Выставив их объекту user мы вложили внутрь выборку объекта brand. Вложенность связывает условие и выборку, Mozart строит связь между этими двумя объектами через связывающий их объект Телефон (посмотрите, как они связаны на графе выше).

Список людей, пользующихся услугами конкретного оператора:

<newt:base>
 <request>
  <set object="operator" attr="name" value="Example">
   <get object="user" />
  </set>
 </request>
</newt:base>

Здесь мы использовали оператор равенства для выставления параметру name объекта operator конкретного значения. Вложенный объект user будет выбран с учетом условия по оператору. Если посмотреть на граф, то можно увидеть, что Оператор и Человек связаны двумя разными маршрутами. Mozart при построении связей выбирает кратчайший. Подробнее об этом можно почитать в статье "Архитектура предметной области в CMF/CMS системах" в нашем блоге.

Список людей, чья фамилия содержит заданную последовательность символов:

<newt:base>
 <request>
  <set object="user" attr="first_name" context-attr="Ива">
   <get object="user" />
  </set>
 </request>
</newt:base>

context-attr, используемый нами в этом примере, указывает подстроку, которая должна содержаться в параметре first_name объекта Человек. Это своего рода контекстный поиск.

Выше мы упомянули, как Mozart пытается построить связь между несмежными объектами. Углубимся в этот момент немного подробнее. Например, во втором примере, когда мы выбирали Человека по Оператору, мы предположили, что Mozart может строить связь по двум маршрутам (через Прописку или через Регион, как это видно на графе). Если, нам, например, требуется изменить алгоритм Mozart и указать ему, что короткий маршрут нас в конкретной ситуации не устраивает, мы можем использовать оператор path-exclude для инструкции get, указав список объектов, которые мы точно не хотим включать в связывающие (по аналогии есть оператор path-include). Ниже исключим объект Телефон:

<newt:base>
 <request>
  <set object="operator" attr="name" value="Example">
   <get object="user" path-exclude="phone"/>
  </set>
 </request>
</newt:base>

Возможно, у кого-то может возникнуть вопрос об эффективности работы такой системы, которая пытается строить связи сразу по нескольким маршрутам, тратя на это процессорное время и память, а значит тормозя приложение. В этом смысле все решается очень просто: при проектировании схемы объектов нам следует избегать закольцованности. В нашем случае, вполне вероятно, объект Прописка следует пометить в конфигурации базы, как нетранзитный, т.е. такой объект, который является всегда конечным при построении связей.

Поговорим теперь о вложенности одних инструкций get и set в другие. Рассмотрим 2 примера:

<newt:base>
 <request>
  <get object="user" >
   <get object="phone">
    <get object="brand"/>
   </get>
  </get>
 </request>
</newt:base>

и

<newt:base>
 <request>
  <get object="brand" >
   <get object="phone">
    <get object="user"/>
   </get>
  </get>
 </request>
</newt:base>

Оба примера оперируют с 3-мя объектами: brand, phone и user, которые связаны.

Первый пример нам выведет всех пользователей, по каждому из них будет выведен список моделей телефона, которые этот человек использует. По каждому телефону будет выведен брэнд телефона. Получится структура:

<user name="1">
 <phone name="example123">
  <brand name="Super Brand" />
 </phone>
 <phone name="345example">
  <brand name="Super Brand" />
 </phone>
 <phone name="678example678">
  <brand name="Brand N 1" />
 </phone>
</user>
<user name="2">
 <phone name="example123">
  <brand name="Super Brand" />
 </phone>
</user>
<user name="3">
 <phone name="345example">
  <brand name="Super Brand" />
 </phone>
</user>

Второй пример покажет нам список всех брэндов, по каждому выведет список всех телефонов этого брэнда. А уже внутри каждого телефоны мы получим список людей, который пользуются данной моделью телефона.

<brand name="Super Brand">
 <phone name="example123">
  <user name="1"/>
  <user name="2"/>
 </phone>
 <phone name="345example">
  <user name="1"/>
  <user name="3"/>
 </phone>
</brand>
<brand name="Brand N 1">
 <phone name="678example67">
  <user name="1"/>
 </phone>
</brand>

Если, например, вы захотите по каким-то причинам в первом примере для телефона выводить не его брэнд, а вообще весь список брэндов, для этого можно использовать инструкцию unset.

<newt:base>
 <request>
  <get object="user" >
   <get object="phone">
    <unset object="brand">
     <get object="brand"/>
    </unset>
   </get>
  </get>
 </request>
</newt:base>

Т.е. мы сняли с объекта brand все выше выставленные на него условия, тем самым это просто выборка из объекта всех данных.

Если же мы хотим вывести список всех пользователей, всех моделей и марок телефонов, то просто избавимся от вложенности и напишем инструкции get последовательно:

<newt:base>
 <request>
  <get object="brand" />
  <get object="phone" />
  <get object="user" />
 </request>
</newt:base>

Выше мы говорили о выборке объекта и инструкциях get. А что же происходит в ситуации, когда необходимо не выбрать последовательно несколько объектов, а выбрать всего один объект, при этом выставив ограничения по нескольким другим? Вернемся к нашему второму примеру (где выбирался Брэнд, его Телефон и использующий его Человек). Переделаем его в такой:

<newt:base>
 <request>
  <set object="brand" attr="name" value="Brand N 1">
   <set object="phone" attr="name" value="678example67">
    <get object="user"/>
   </set>
  </set>
 </request>
</newt:base>

Мы заменили get объектов Брэнд и Телефон на set, т.е. на выставление ограничения по ним. Структура вложенности осталась прежняя. Тем самым мы указали накопить ограничения для самого последнего по вложенности get, который выбирает объект Человек с учетом выше установленных инструкций set, в которые он вложен.

В результате мы получим список пользователей, которые пользуются указанными телефонами:

<user name="1"/>
<user name="10"/>
<user name="11"/>

Выводы

Как мы увидели, API системы Mozart имеет очевидную структуру и обладает простотой, которая позволяет оперировать с выборкой данных и их классификацией неискушенным разработчикам. Результат получения данных представляет собой структурированный формат XML, структура которого полностью зависит от ваших запросов. Вы можете добавить в нее некоторую избыточность, можете нет. У вас есть возможность получать такие деревья XML, какие будут удобны не только для последующей обработки в XSLT, но и для обычного визуального восприятия, ведь именно простота разработки проекта является основополагающим при выборе системы разработки.

Терминологическое поле объектов помогает проще понять структуру проекта, связи между его данными. Избавивших от технических терминов, SQL запросов и прочих низкоуровневых тонкостей вы получаете среду, которая очень схожа с окружающим миром, оперируете в ней как в реальном мире.

* This source code was highlighted with Source Code Highlighter.

 

  Наполнение сайта данными      |      Установка Mozart