воскресенье, 10 апреля 2016 г.

Вызываем Cache!

Данный материал является справочным. Статья ни в коем случае не призвана заменить официальную документацию Intersystems и предназначена только для использования в качестве CookBook.

Основным общедоступным механизмом доступа к объектам Cache по стратегии Intersystems является набор COM объектов, организованный в библиотеку CacheObject.dll. Библиотека располагается в каталоге установки Cache c:\cachesys\bin. При корректной инсталляции все необходимые интерфейсы регистрируются в системе и библиотека доступна к использованию. Описание интерфейсов библиотеки находится в c:\cachesys\docs\activexref\index.html. Каталоги указаны в том виде, в котором они предлагаются инсталлятором по умолчанию.


Механизм доступа основан на схеме коннект - служебный объект. Коннект обеспечивает взаимодействие с серверным процессом, служебные объекты обеспечивают взаимодействие с частными объектами в рамках этого процесса.

В силу того, что коннект выполнен в виде COM объекта, его можно вызвать из различных языков программирования, которые поддерживают обращение к COM объектам. Естественно, что VB, архитектурно построенный на COM технологии, поддерживает такой доступ. И основная демонстрация обращения к CacheObject в документации Intersystems подробно описывает этот способ. Мы же приведем способы обращения к Cache на других языках.

В дальнейшем предполагается демонстрация обращений к объекту класса NewClass1, имеющего два строковых свойства NewPorperty1 и NewProperty2. В демонстрационнах примерах будет показано подкючение к базе, заведение нового объекта, присовение его свойствам некоторых значений и сохранение объекта. По аналогии выполняются и остальные действия.

Delphi.

Создаем форму как обычно. Или юнит, ответственный за обращение к Cache, или DataModule. В секцию uses добавляем модуль ComObj. Заводим переменную типа Variant. Она будет реализовать собой объект коннекта. Составляем обработчик события подключения и одновременно создания нового объекта:
procedure TForm1.FormShow(Sender: TObject);
var
  Connect: Variant;
  Obj: Variant;
begin
  Connect := CreateOleObject( 'CacheObject.Factory');
  Connect.Connect( 'cn_iptcp:127.0.0.1[1972]:USER');

  obj := Connect.New( 'NewClass1');
  obj.NewProperty1 := 'wef';
  obj.NewProperty2 := 'ervdfv';
  obj.sys_Save;
  obj.sys_Close;

  obj := Null;
  Connect := Null;
end;
Разберем код по строкам. Вызов CreateOleObject создает новый объект коннекта. Вызов Connect.Connect производит соединение с указанным сервером. Вызов Connect.New создает в рамках этого же процесса объект указанного класса. Присвоение свойств вариантам в Delphi поддерживается на уровне языка, поэтому указываем свойства. Компилятор автоматически транслирует такие вызовы в обращения к интерфейсу IDispatch. Вызовы функций sys_Save и sys_Close заслуживают отдельного описания. Дело в том, что на стороне Cache эти функции декларированы с символом процента в имени, что не может быть смаршаллено как есть, поэтому библиотека CacheObject использует соглашение, что префикс sys_ означает обращение к соответствующей процентной функции. В этом примере вызывается сохранение объекта и его закрытие. Присвоение объектам obj и Connect значения Null Delphi рассматривает как отпускание COM объекта. Для объекта Connect это означает дисконнект от сервера.

Часто задаваемые вопросы по связке CacheObject - Delphi или краткая документация с примерами.

С++ Builder.

Создаем форму так же, как это делается в обычном проекте BCB. Как и в случае Delphi, планируем размещение объектов коннекта и служебных объектов. В модуль включаем объявления:
#include <atl/atlvcl.h>
#include <ComObj.hpp>
#include "Ole2Auto.hpp"
Модуль Ole2Auto берем из библиотеки RX. В силу некоторой недоработанности BCB в области вызова COM объектов придется либо самостоятельно писать обращения в интерфейсам автоматизации, либо использовать стороннюю библиотеку. В нашем случае используем стороннюю. Можно использовать также любую другую, которая реализует обращение к интерфейсам автоматизации.

Составляем обработчик события подключения и создания объекта на сервере:
void __fastcall TForm1::FormShow(TObject *Sender)
{
  Variant Connect = CreateOleObject("CacheObject.Factory");

  Variant Result = Connect.OleFunction(
    "Connect", "cn_iptcp:127.0.0.1[1972]:USER");

  TOleController* Controller = new TOleController;
  Controller->AssignIDispatch( Connect);

  Variant Object = Controller->CallFunction( "New",
    OPENARRAY( TVarRec,( "NewClass1")));
  TOleController* ObjectController = new TOleController;
  ObjectController->AssignIDispatch( Object);

  ObjectController->SetProperty( "NewProperty1",
    OPENARRAY( TVarRec, ( "qwerty123")));
  ObjectController->SetProperty( "NewProperty2",
    OPENARRAY( TVarRec, ( "qwerty456")));

  ObjectController->CallFunctionNoParams( "sys_Save");
  ObjectController->CallFunctionNoParams( "sys_Close");

  delete ObjectController;
  delete Controller;
  Object = Null;
  Result = Null;
  Connect = Null;
}


Здесь объекты автоматизации удерживаются в переменных типа Variant, но управляются через присоединенный OLE контроллер. В остальном же код полностью эквивалентен вышеприведенному для Delphi.

Perl for Win32.

В скрипте Perl, ответственном за соединение с сервером и создание нового объекта, добавляем использование модуля OLE автоматизации:
use Win32::OLE;
Составляем обработчик подключения к серверу и заведения нового объекта:
#!usr/bin/perl

use Win32::OLE;

$connect = Win32::OLE->new( 'CacheObject.Factory');
$connect->Connect( 'cn_iptcp:127.0.0.1[1972]:USER');

$obj = $connect->New( 'NewClass1');
$obj->{NewProperty1} = "perl data 1";
$obj->{NewProperty2} = "perl data 2";
$obj->sys_Save();
$id = $obj->sys_Id();
print "Created object with id = $id\n";
$obj->sys_Close();
Здесь переменная $connect отвечает за соединение с серверным процессом, а переменная $obj - за конкретный объект. Отличие от вышеприведенных двух примеров - только в синтаксисе языка. Здесь сначала заводится объект коннекта к базе, потом производится соединение, создание нового объекта класса NewClass1 и присвоение его свойствам значений, после чего объект сохраняется и показывается (для отчетности) что действительно был создан новый экземпляр. По окончании работы скрипта все переменный отключаются и соединение автоматически разрывается. Если требуется освободить объекты явно, то следует вызвать их освобождение как undef $obj; undef $connect.

Приведенная техника является только демонстрационной и не претендует на полноту. За подробным списком поддерживаемого функционала библиотекой CacheObject следует обратиться к документации c:\cachesys\docs\activexref\index.html. Ссылка дана по используемой при написании заметки версии Cache, в других версиях ссылки на документацию могут отличаться.

Комментариев нет:

Отправить комментарий