Разработки          Услуги          О компании          Контакты  

Материал из биософт-м

Перейти к: навигация, поиск

  !   Данная информация предназначена только только для IT-специалистов по системной интеграции модулей БИОСОФТ-М. (см. Руководства пользователя к программным продуктам)

Проперти типа dblist<CXxxItem> _x_... у CDb-объекта связывает с этим объектом подмножество записей типа CXxxItem.

Что это

Это виртуальный проперти (_x_) в котором в самом ничего не хранится. В соответствии с реляционной моделью привязка CXxxItem-ов к контейнеру происходит хранением ключа этого контейнера в каждом экземпляре CXxxItem.

Ключ контейнера не нужно декларировать явно, он наследуется от dbobject:

class dbobject
 
    key GetDbContainerKey();
    void InitDbContainerKey(
            key keyContainer);
    void ForceChangeDbContainerKey(
            key keyContainer);

Мы можем запрашивать CXxxItem-ы из dblist как будто перебирая элементы массива, хранящегося внутри объекта. На самом же деле в запрос с указанием x_dblist-проперти автоматически добавляется фильтр item.keyContainer = ?.

Это не SQL

В стандартном SQL не существует абстракции непосредственно соответствующей dblist в Udb. SQL требует всегда явно указывать идентификаторы иерархии контейнеров во всех запросах, не понимая вообще таких понятий как "иерархия" или "контейнер" по определению.

Мотивация его появления

Нам требуется инкапсуляция независимых секторов БД друг от друга. Этой инкапсуляции противоречит реляционная традиция хранения всех записей одного типа в одной общей таблице вне зависимости от принадлежности этих записей разным контейнерам.

Использование dblist позволяет изолировать один набор айтемов от другого набора того же класса (== с тем же набором колонок) оставляя их в одной таблице в БД.

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

Это не array!

Не в коем случае в декларациях CDb-классов не надо автоматически транслировать прикладные array<> в dblist! Где то между ними есть соответствие, где то нет и реляционная технология требует иной структуры классов хранилища нежели ООП в контроллере.

Если есть сомнения и не понятно, то в простой БД для начала можно поступить чисто по реляционному и все _x_dblist разместить в Root-классе. То есть все объекты каждого типа будут находится в своей таблице вне зависимости от того к чему они относятся. Это будет работать. Это будет работать в отличие от ошибочной трансляции всех array<> мемберов ООП классов в множество локальных dblist без ясного понимания зачем это делается.

Пока хранилище простое не будет никаких проблем с тем что все dblist в корне. Нужно только в каждом запросе не забывать в явном виде указывать критерии выборки этих объектов с учетом логической иерархии и того к чему они относятся.

Однако по мере развития приложения нарушения инкапсуляции и досадные влияния одного модуля на другой проявятся с появлением новых логических контейнеров для айтемов того же самого типа. Появление каждого нового независимого контейнера для айтемов может потребовать модифицировать все запросы к айтемов из всех модулей чтобы выбирать только айтемы, относящиеся к данному модулю.

Очевидно здесь будем иметь нарушение приватности данных когда они замешаны в одной таблице и нужно не забывать их выфильтровывать в каждом модуле с учетом модификации всех остальных модулей.

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

Примеры

1)

Предположим у нас есть БД пациентов и у каждого пациента таблица с индексами обследования. Каждая запись об обследовании содержит ключ пациента, который был обследован. Записи можно посмотреть в контексте пациента, а можно в списке всех обследований не по пациентам а по датам.

Теперь предположим потребовалась хранить глобальную запись о нормативных значениях индексов. Эти нормы не связаны ни с каким конкретным пациентом. Но записи имеют ту же структуру, тот же CDb класс, и частитчно ту же логику отображения.

Проблема в том что мы не можем реализовать эту независимую от списка пациентов фичу не исправив все существующие запросы к спискам обследований чтобы исключить глобальные записи.

Однако если мы разместили обследования пациентов в одном dblist и добавим независмый dblist для норм то коллизий и смешения индексов не возникнет. В каждом запрое обязательно неявно будет присутствовать ключ контейнера, в котором объявлен _x_dblist и запросы будут относится только к приватным данным соответствующего модуля приложения: либо к обследованиям общего списка, либо к нормативным.

2)

Предположим софтина обрабатывает набор изображений у каждого из которых своя палитра цветов (как спектры в доплере). Каждый CDbImage может иметь свой _x_dblist<CDbColor> и работать с ним никогда не боясь зацепить цвет из другой картинки. Не смотря на то что все Color реально хранятся в одной таблице БД и запросы к ним унифицированы.

Предположим в придачу понадобилось хранить набор цветов по умолчанию. Это глобальная настройка не относящаяся к картинкам. Как и в первом примере добавляем глобальный dblist<CDbColor> _x_dblistDefautColor. И вся логика работы с ним оказывается изолированной от картинок, все данные приватны.


Эта категория в данный момент пуста.

www.biosoft-m.ru



Просмотры
Личные инструменты