Александр Чеснавский,
консультант по продуктам InterSystems Corporation
alexander@intersystems.ru

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

Архитектура

Архитектура СУБД Cache показана на рис. 1. Сердце системы - сервер многомерных данных (Multidimensional Data Server, MDS), позволяющий компактно и эффективно хранить данные произвольной сложности. Для доступа к сложноструктурированным данным не требуется изощренных и дорогостоящих операций соединения, что положительно сказывается на общей производительности СУБД и, в совокупности с транзакционной многомерной моделью Cache и встроенными средствами многопользовательской работы, позволяет создавать промышленные приложения, лишенные недостатков реляционных СУБД.

Fig.1 Рис. 1. Архитектура СУБД Cache.

В Cache реализована концепция единой архитектуры данных. Ко всем данным, которыми управляет сервер многомерных данных Cache, существует три способа доступа: прямой, объектный и реляционный. Прямой доступ к данным (Cache Direct) обеспечивает максимальную производительность. Разработчики приложений получают непосредственный доступ к многомерным структурам (так называемым глобалам) Cache, что позволяет при достаточной квалификации создавать высокопроизводительные решения. Для построения отчетов и совместимости с реляционными продуктами СУБД Cache предоставляет реляционный доступ, в основе которого лежит стандарт SQL 92. Однако наиболее интересен объектный доступ. С этой точки зрения Cache соединяет традиционную технологию проектирования баз данных с объектной моделью. Применение такого подхода оказывается достаточно полезным в CAD/CAE, CASE-технологиях и других областях, где приходится манипулировать значительными объемами данных с разнообразным семантическим содержанием. Более того, объектная модель Cache гарантирует согласованное объединение данных и бизнес-логики, что в реляционных системах обеспечивается сложной системой триггеров, которые изначально разделяют систему на "логику" и "данные".

Способы взаимодействия с Cache

СУБД Cache - это открытая система; она предоставляет огромное количество интерфейсов для взаимодействия с внешним миром, которые можно разделить в соответствии с типом доступа: прямой, реляционный и объектный. Отметим, однако, что подобное разбиение достаточно условно, и некоторые способы взаимодействия Cache с внешним миром можно отнести сразу к нескольким категориям.

Механизмы для Windows

Чаще всего для создания GUI-приложений в среде Windows используется механизм объектной фабрики Cache, в основе которой лежит Cache ObjectServer, представляющий собой OLE In-Process Automation Server. Он позволяет хранить на клиенте копии серверных объектов. Иначе говоря, если в приложении на VB средствами ObjectServer открывается объект, то идентичный объект открывается и на сервере. При изменении какого-либо свойства на стороне клиента соответствующее свойство у серверного объекта изменяется автоматически, вызов метода влечет за собой его выполнение на сервере с передачей результатов на клиентскую часть.

Архитектура ObjectServer подразумевает разделение приложения на две части: клиентскую и серверную. И здесь сразу же возникает вопрос: каким образом клиент будет получать метаданные серверных объектов? Здесь существует два подхода: раннее и позднее связывание. Раннее связывание означает, что на клиенте в явном виде хранятся определения классов. Иными словами, если клиент взаимодействует с серверным классом, то приложению заранее известна структура этого класса, описания свойств и сигнатуры методов, благодаря чему при компиляции можно создавать более эффективные способы обращения к экземплярам данного класса. Если с сервером связано более одного клиента, то, естественно, информацию о серверных классах необходимо продублировать на каждом клиенте, что в случае сильно распределенной системы может оказаться довольно трудоемкой задачей. Однако основной недостаток такого подхода заключается в синхронизации изменений серверных классов с соответствующими определениями на клиентах. При изменении одного свойства необходимо провести корректировку и перекомпиляцию всех классов, а их может быть тысячи и даже сотни тысяч.

Альтернатива раннему связыванию - механизм позднего связывания. В этом случае клиенту необходим всего лишь единственный класс Factory, который, согласно паттерну проектирования Abstract Factory, берет на себя ответственность за создание объектов, инкапсулируя всю логику формирования экземпляров класса на стороне клиента. В совокупности с преимуществами технологии OLE (а именно, использования Variant) объектная фабрика избавляет клиента от необходимости хранить определения всех используемых серверных классов (см. приведенный ниже листинг).

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

Dim Factory As CacheObject.Factory
Set Factory = CreateObject("CacheObject.Factory")
If Not Cache.Connect
("cn_iptcp:127.0.0.1[1972]:TEST") Then
        MsgBox "Cannot connect to Cache"
        End
End If
Dim Dog As Object
Set Dog = Factory.New("Dog")
Dog.Name = "Tuzik"
Dog.sys_Save

Механизмы на базе Java

Механизм Cache ObjectFactory используется для создания GUI-приложений исключительно в среде Windows. При создании же кросс-платформенных решений разработчики часто используют технологию Java - она тоже очень легко интегрируется с СУБД Cache с помощью таких механизмов, как Cache Java Binding, Cache EJB Binding и относящийся к реляционному способу доступа JDBC-драйвер, поддерживающий JDBC API 2.0.

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

  • Cache Java Class Generator - специальное расширение компилятора классов Cache, позволяющее из описаний классов в Cache Class Dictionary получать описания классов на Java;
  • Cache Java Class Package - набор Java-классов, которые в связке с классами, сгенерированными Cache Java Class Generator, обеспечивают прозрачную работу с объектами, сохраненными на сервере Cache;
  • Cache Object Server - специальный серверный процесс, обеспечивающий взаимодействие между Java-клиентом и сервером Cache по протоколу TCP/IP.

Таким образом, Cache Java Class Generator из определений классов Cache создает Java-проекции, которые во время выполнения взаимодействуют с соответствующими классами на сервере Cache. Общая схема взаимодействия приведена на рис. 2.

Fig.2 Рис. 2. Схема функционирования Cache Java Binding.

Как было сказано выше, Cache Java Binding - это не единственный способ доступа к Cache из Java. Существует еще механизм EJB Binding, позволяющий EJB-компонентам взаимодействовать с серверными объектами. Аналогично механизму Java Binding, EJB Binding автоматически создает для каждого указанного класса EJB Entity bean, хранящийся и исполняющийся непосредственно на сервере Cache. Этот подход дает следующие преимущества.

Отсутствие объектно-реляционного несоответствия. Благодаря тому, что Cache естественным образом работает с объектами, не требуется проводить дорогостоящие объектно-реляционные преобразования.

Быстрая разработка. СУБД Cache автоматизирует операции, связанные с генерацией EJB-компонентов, созданием скриптов для развертывания и тестирования компонентов.

Гибкость. Внутри EJB-компонента можно использовать произвольное сочетание объектного и реляционного доступа к СУБД Cache и все дополнительные возможности Cache, связанные с доступом к устройствам, внешним системам и т. д.

Проецирование в классы C++

Наряду с Java и EJB Binding, СУБД Cache позволяет проецировать классы Cache в классы C++. Архитектура C++ binding сходна с проецированием в Java и, наряду с отображением классов Cache в классы C++, заботится о конкурентном доступе к объектам и о транзакционности. Кроме того, стоит отметить, что проецирование в C++ (как и все остальные виды проецирования) оптимизировано под распределенные архитектуры и использует механизм кэширования для минимизации трафика между приложениями на C++ и сервером Cache.

Рассмотрим простейший пример использования классов Cache из C++:

d_ref<Sample_Person> p1 = Sample_Person::openid(&db, L"1");
p1->setDOB(1970,2,1);

Библиотека C++, поставляемая вместе с Cache, содержит шаблонный класс d_ref<>, инкапсулирующий логику обращения к промежуточным классам и реализованный по концепции smart pointer, что позволяет вызывать методы промежуточных классов через "->" синтаксис, копировать d_ref<> таким образом, чтобы два экземпляра указывали на один объект, передавать экземпляр d_ref<> в промежуточный метод по ссылке и т. п.

Обращение Cache к внешним приложениям

Все рассмотренные выше способы доступа ориентированы на обращение к Cache извне. Однако нередко встречаются ситуации, когда на основе данных, хранящихся в Cache, необходимо сформировать отчет в виде привычной таблицы Excel, сгенерировать документ в формате Word, PDF или выполнить еще какое-нибудь действие, связанное с обращением к COM-объектам. В этом случае может оказаться полезным специальный механизм Cache Activate, позволяющий взаимодействовать с компонентами ActiveX как с обычными объектами Cache. Методика использования Cache Activate очень проста: с помощью Cache Activate Wizard для конкретного COM-компонента создается специальный класс (таких классов может быть несколько), экземпляр которого затем используется в приложении для доступа к соответствующему компоненту.

Рассмотрим пример использования компонента Microsoft SysInfo Control. В первую очередь воспользуемся Cache Activate Wizard для создания "обертки" вокруг компонента ActiveX (рис. 3).

Fig.3
Рис. 3. Использование мастера Cache Activate.

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

	Set obj = ##Class(Activate.SysInfoLib.SysInfo).%New()
	Write !,obj.BatteryLifePercent
	Write !,obj.BatteryLifeTime

Аналогичным способом можно получать информацию от любого другого доступного компонента. Однако у этого подхода есть один большой недостаток - он функционирует только на платформах, поддерживающих ActiveX. Чтобы вызывать внешние приложения на других платформах, в Cache существует механизм callout, позволяющий выполнять команды таких ОС, как Unix, MS-DOS, OpenVMS. С практической точки зрения существует несколько вариантов вызова внешних команд. Если достаточно интерактивного взаимодействия с ОС из терминала Cache, то можно воспользоваться утилитой %CLI. В тех случаях, когда обращение к внешней среде необходимо встроить непосредственно в программную логику, можно использовать синхронную функцию $zf(-1) или ее асинхронный аналог $zf(-2). Простейший пример использования функции $zf(-1) выглядит так:

	Set status = $ZF(-1,"mkdir test")

Отличительная черта механизма callout - возможность вызова разделяемых библиотек (в Windows это DLL, в Unix - shared library, в OpenVMS - shared executable). Поскольку такие библиотеки сильно зависят от платформы, детали реализации следует согласовывать с документацией Cache. Нужно отметить, что в дополнение к механизму callout существует противоположный ему по действию механизм callin. Задача последнего - эффективное выполнение команд Cache из программ, написанных на С, что позволяет применять его не только в GUI-приложениях для взаимодействия клиентской части с серверной, но и в высокопроизводительных телеметрических системах, где в режиме реального времени регистрируются показания приборов и датчиков, которые затем передаются в Cache для дальнейшей обработки.

Обмен данными в распределенных системах

В последнее время не угасает интерес к сервисно-ориентированным архитектурам (SOA), в которых все функции системы реализованы как независимые сервисы. Последовательность вызова этих сервисов определяет тот или иной бизнес-процесс. Зачастую архитектуры, ориентированные на сервисы, отождествляют с Web-сервисами, базирующимися на стандартах XML, SOAP и HTTP. Протокол SOAP (Simple Object Access Protocol) предоставляет простой механизм для обмена структурированной и типизированной информацией между узлами децентрализованной распределенной системы - посредством обмена XML-сообщениями. В качестве транспортного протокола в большинстве случаев используется HTTP. Cache обеспечивает полную и прозрачную поддержку Web-сервисов, не требуя установки какого-либо промежуточного ПО или расширений.

Механизм Cache SOAP позволяет создавать поставщиков сервисов и их потребителей на основе единой объектной модели Cache, благодаря чему каждый класс Cache без изменений может стать и Web-сервисом, если к списку родительских классов добавить %SOAP.WebService. В таком случае все методы этого класса, помеченные ключевым словом WebMethod, становятся доступными в рамках Web-сервиса, и при компиляции класса из списка этих методов автоматически генерируется набор SOAP-интерфейсов. Общая схема механизма Cache SOAP представлена на рис. 4.

Fig.4 Рис. 4. Архитектура Cache SOAP.

В качестве еще одного способа создания распределенных систем можно предложить использование так называемых федеративных баз данных, размытых по гетерогенной среде, где каждый узел может функционировать на различных программных и аппаратных платформах. В качестве протокола взаимодействия между узлами используется ODBC или JDBC. Кроме того, СУБД Cache предлагает дополнительный механизм SQL Gateway (рис. 5), предоставляющий объектный доступ к внешним реляционным СУБД. Допустим, во внешнем отношении Person хранится информация о сотрудниках фирмы. Cache позволяет автоматически (с помощью Link Table Wizard) создать специальный класс Person, инкапсулирующий логику обращения к внешней РСУБД, и использовать его экземпляры точно так же, как обычные классы Cache.

Fig.5
Рис. 5. Принцип функционирования Cache SQL Gateway.

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

* * *

Описанных выше способов взаимодействия с COM, Java, C, с реляционными системами уже достаточно, чтобы утверждать, что СУБД Cache никак не может считаться "черным ящиком" и способна служить ядром для высокопроизводительных систем с открытой архитектурой. Более того, в данной статье мы сознательно не рассматривали аспекты интеграции с протоколами FTP, HTTP, SMTP, POP3, LDAP, TCP/IP, очередями сообщений IBM MQ Series и многим другим, что в совокупности с возможностями встроенного языка Cache Object Script позволяет организовать взаимодействие практически с любой системой.