Докомпиляция интерфейсов Назад В начало Вперед

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

Для докомпиляции интерфейса необходимо наличие в ресурсе символьной информации (так же как и для наследования). Включение необходимой информации в ресурс управляется параметром Compilers.InhSaveLevel.

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

Если задать Compilers.InhSaveLevel = 3, то символьная информация будет генерироваться для всех интерфейсов. Однако надо помнить, что запись символьной информации для каждого интерфейса сильно увеличит размер ресурсного файла.

Докомпилировать можно только те элементы интерфейса (методы, потоки и т.д.), для которых указан квалификатор public и есть символьная информация в ресурсе.

Описание докомпиляции похоже на описание интерфейса, но добавляются ключевые слова alter и fix:

<докомпиляция-интерфейса> = alter interface <имя-интерфейса>
  [ ( [ fix ] <служебная-информация> ) ]
  <элемент-докомпиляции> { <элемент-докомпиляции> }
  end.

Ключевое слово fix означает исправление ошибки и смысловой нагрузки не несёт.

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

<элемент-докомпиляции> =
  overload <перекрытый-элемент> { <перекрытый-элемент> } end;
  | <расширение-логической-таблицы>
  | <расширение-обработчика-событий>

<перекрытый-элемент> - объявление перекрытых потока данных, функции или процедуры. Соответствующая реализация приводится в теле интерфейса, за пределами секции overload.

<перекрытый-элемент> =
  datastream <имя-потока-данных> ;
  | <перегрузка-функции>
  | <перегрузка-процедуры>

Конструкция datastream <имя-потока-данных> объявляет расширяемый поток данных. Реализация расширяемого потока в основном описывается так же, как и реализация исходного потока (см. "Реализация потока данных. "). Но в описании элемента потока добавляется ключевое слово inherited:

<элемент-потока> =
  [ [ <имя-поля> ] ] <выражение> ;
  | table <имя-таблицы> [ onClick ( <ключевое-поле> ) ]
	( <элемент-потока> {, <элемент-потока> } ) ;
  | table inherited::<имя-таблицы-предка>
	( <элемент-потока> {, <элемент-потока> } ) ;
  | dataset <имя-датасета> [ onClick (<ключевое-поле>) ]
	( <элемент-потока> {, <элемент-потока> } ) ;
  | dataset inherited::<имя-датасета-предка>
	( <элемент-потока> {, <элемент-потока> } ) ;

<имя-поля> - уникальное для элемента потока имя поля, доступное в генераторе отчётов и т.д. Хотя указание имени поля необязательно, рекомендуется всегда указывать его. В случае, если имя не указано - полю будет автоматически присвоено сгенерированное имя и компилятор выдаст предупреждение.

<выражение> - вычисляемое выражение в текущем контексте.

<имя-таблицы> - уникальное в пределах потока данных имя элемента потока. Должно соответствовать имени одной из таблиц интерфейса. Не должно совпадать ни с одним из имён потока данных-предка. Для использования в генераторе отчётов и т.д.

<имя-датасета> - уникальное в пределах потока данных имя элемента потока. Не должно совпадать ни с одним из имён потока данных-предка. Для использования в генераторе отчётов и т.д.

<ключевое-поле> - поле элемента потока, значение которого используется для навигации. При обработке событий номер поля можно взять из переменной Target, а значение ключевого поля - из переменной ExprFieldValue. По значению ключевого поля можно выяснить текущую запись элемента потока. Ключевое поле должно быть соответствующим образом описано.

<имя-таблицы-предка> - уникальное в пределах потока данных имя элемента потока. Должно соответствовать имени одной из таблиц интерфейса и совпадать с именем расширяемого элемента потока данных-предка.

<имя-датасета-предка> - уникальное в пределах потока данных имя элемента потока. Должно совпадать с именем расширяемого элемента потока данных-предка.

<перегрузка-функции> - объявление перекрываемой функции. Синтаксис описания такой же, как и при наследовании.

<перегрузка-процедуры> - объявление перекрываемой процедуры. Синтаксис описания такой же, как и при наследовании.

<расширение-логической-таблицы> - см. "Расширение логических таблиц. ".

<расширение-обработчика-событий> - см. "Расширение обработчиков событий. ".

Ограничение  Докомпиляция интерфейса должна проводится в ресурс, отличный от того, откуда загружается докомпилируемый интерфейс.

Примеры

Пример 1. Перегрузка функции и расширение обработчика событий.

alter interface vTest (fix 'исправление грамматической ошибки')
					'Проверка';
  overload
	function iTest.Func1 ( var vUglUskR : integer ) : boolean;
  end;

  function iTest.Func1 ( var vUglUskR : integer ) : boolean;
  {
	result := false;
	if (inherited :: Func1 (vUglUskR)) then
	 ...
  }

  handleEvent
	cmValue19: {
	...
	inherited :: handleEvent (cmValue18);
	...
}
  end;
end.

Пример 2. Расширение потока данных.

Создадим файл dstream2.vip (докомпилируемый интерфейс должен находиться в другом исходном файле, относительно оригинального):

// -- dstream2.vip --
#include dstream.vih

alter interface SampleInterface2;
  create view as select * from x$files;
  dataStream SampleStream
	(
	// Изменение существующего элемента потока
	table inherited::x$files
	(
		[ SMPLTXT2 ] "Поле xf$name: " + xf$name;
	);
	// Добавление в поток данных нового элемента
	table x$users
	(
		[ SMPLNAME ] xu$loginname;
	);
	)
  end;
end.

Версия

Атлантис 5.0.

Расширение потоков данных введено начиная с Атлантис 5.1.2x.