Табличные объекты |
При разработке пользовательского интерфейса внутри компонента имеется возможность доступа к данным только своих или общеупотребительных таблиц. К остальным таблицам следует обращаться через соответствующий объектный интерфейс (табличный объект).
Табличный объект реализует объектную таблицу, которая является полным аналогом таблицы БД. Синтаксически использование обычных таблиц и объектных таблиц никак не отличается. Объектные таблицы могут использоваться при описании логической таблицы, для обращения к базе через операторы SQL, для проверки ссылочной целостности, для описания структуры в операторе record as table и т.д.
Поля и индексы объектной таблицы представляются свойствами (см. "Реализация свойств. ") и объектными индексами (см. "Реализация индексов. "). Для их заполнения табличный объект может обращаться к одной или нескольким физическим таблицам (см. пример 2). Для взаимодействия с физической таблицей табличный объект должен реализовывать интерфейс IModify (см. "Интерфейс модификации объекта в БД. ").
Объектная таблица представляется переменной типа objInterface, реализующей табличный объект. Имя этой переменной используется в соответствующих конструкциях SQL вместо имени физической таблицы.
Требования к переменной:
переменная должна быть указана в секции from логической таблицы;
переменная должна быть либо автоинициализируемая, либо прикладной программист должен позаботиться об ее инициализации до момента первого, реально необходимого факта использования этой переменной;
если одна и та же переменная используется для обращения к разным таблицам, то vipInterface, реализующий соответствующий табличный объект, должен работать таким образом, что бы результат одного обращения по его объектным индексам не зависел от другого.
При компиляции конструкций SQL имя таблицы ищется среди таблиц, видимых в текущем компоненте. Если такая таблица нашлась, то используется она. Если таблица с указанным именем не найдена, то выполняется поиск среди переменных типа objInterface. Если переменная найдена, то она используется в качестве объектной таблицы.
Поскольку синтаксически использование таблиц и табличных объектов никак не отличается, есть возможность потенциальных ошибок. Например, неверно указано имя компонента при сборке. Поэтому надо внимательно следить за предупреждениями компилятора.
Для полного контроля ситуации прикладными разработчиками вводятся ключевые слова table и objref оператора select (см. "Список таблиц для выборки. ").
Пример 1.
Описание табличного объекта (файл IX$FILES.vih):
#ifndef __X$FILES__VIH__ #define __X$FILES__VIH__ #include IModify.vih public objInterface objX$FILES; property XF$CODE : word read write; property XF$NAME : string[20] read write; index FILEBYCODE = XF$CODE(unique); index FILEBYNAME = XF$NAME; end; public vipInterface vipX$FILES implements objX$FILES, IModify licensed(free); #endif
Реализация табличного объекта (файл twX$FILES.vip):
#include objX$FILES.vih interface vipX$FILES; create view as select * from X$FILES; property objX$FILES.XF$CODE : word absolute X$FILES.XF$CODE read write; property objX$FILES.XF$NAME : string[20] absolute X$FILES.XF$NAME read write; function IModify.doInsert : Word; { Result := insert current X$FILES; } implementation IModify.doUpdate abstract; implementation IModify.doDelete abstract; implementation IModify.doFlush abstract; index objX$FILES.FILEBYCODE auto; index objX$FILES.FILEBYNAME auto; end.
Использование табличного объекта:
#include IX$FILES.vih interface TblObjTest1; var varX$Files1 : objX$Files (vipX$Files); create view as select * from varX$Files1; panel panStageMemo; browse brw; fields varX$Files1.XF$CODE 'Код' : [10], protect; varX$Files1.XF$NAME 'Наименование' : [50], protect; end; end; end.
Пример 2.
Описание табличного объекта (файл IAttributes.vih):
#ifndef __ATTRIBUTES__VIH__ #define __ATTRIBUTES__VIH__ public objInterface IAttributes; property Name : string[80] read; property AttrType : string[15] read; property Value : string[120] read; index AttrByName = Name; end; public vipInterface twAttributes implements IAttributes; #endif
Реализация табличного объекта (файл twAttributes.vip):
#include IAttributes.vih interface twAttributes; create view as select * from AttrVal, AttrNam where (( root == AttrVal.NRec and AttrVal.cAttrNam == AttrNam.NRec )); property IAttributes.Name : string[80] absolute AttrNam.Name read; property IAttributes.AttrType : string[15] read if (AttrNam.AttrType = 0, 'string', if (AttrNam.AttrType = 1, 'double', if (AttrNam.AttrType = 2, 'date', if (AttrNam.AttrType = 3, 'time', 'неопределенный')))); property IAttributes.Value : string[120] read if (AttrNam.AttrType = 0, AttrVal.Vstring, if (AttrNam.AttrType = 1, DoubleToStr(AttrVal.Vdouble,'9999999999.99999'), if (AttrNam.AttrType = 2, String(AttrVal.Vdate), if (AttrNam.AttrType = 3, String(AttrVal.Vtime), '')))); index IAttributes.AttrByName auto; end.
Использование табличного объекта:
#include IAttributes.vih interface TblObjTest2; var varAttrs : IAttributes (twAttributes); create view as select * from objref varAttrs; panel panStageMemo; browse brw; fields varAttrs.Name 'Наименование' : [30], protect; varAttrs.AttrType 'Тип' : [10], protect; varAttrs.Value 'Значение' : [30], protect; end; end; end.