[
Выше] [Начало_этой_части] [Конец_этой_части] [Далее]===========================================
Глава 3 – Спецификация класса
Эта глава содержит следующие темы:
Модификаторы классов
Параметры классов
Поведение объекта: методы
Состояние объекта: свойства
Отбор объектов: запросы
Оптимизация объектов: индексы
Обработка событий: триггеры (Triggers) и методы обратной связи (Callback Methods)
Спецификация класса определяет, что является классом и как он себя ведет. Эта глава описывает, как использовать классы и их элементы в Cache.
Спецификация класса для объекта – это определение его свойств (которые характеризуют состояние объекта) и методов (которые являются способом реализации его поведения). Спецификация для класса-типа_данных – это определение только методов, так как классы этого типа имеют только литеральные значения
(и не имеют свойств).Имеются также другие элементы спецификации класса, включая параметры класса и модификаторы класса. Свойства, методы, параметры и модификаторы описаны ниже.
Определить класс (создать специфицию класса) можно с помощью Cache Object Architect или Class Definition Language.
Элементами спецификации класса являются:
Примечание: имена элементов класса должны быть отличны друг от друга. См.
"Чувствительность к регистру и уникальность" и главу 4, "Введение в Cache ObjectScript".Определение класса можно изменить с помощью одного или большего количества модификаторов класса. Каждый модификатор необязателен и, если не указан явно, имеет значение по умолчанию.
Разрешается использовать следующие модификаторы класса:
ABSTRACT |
Определяет, что класс не может иметь экземпляров; для типов данных, определяет, что класс не может использоваться как атрибут типа. По умолчанию, классы не являются абстрактными. Подклассы не наследуют значение модификатора ABSTRACT. |
ARRAY |
Определяет атрибут-массив, принадлежащий классу. По умолчанию, классы не содержат никаких массивов. Наследование массивов управляется с помощью определения массива. |
ATTRIBUTE |
Определяет атрибут класса. По умолчанию, классы не имеют атрибутов. Наследование однозначных атрибутов управляется с помощью определения атрибута. |
BINARYSTREAM |
Определяет атрибут-бинарный_поток, принадлежащий классу. По умолчанию, классы не содержат никакие бинарные потоки. Наследование бинарных потоков управляется с помощью определения потока. |
CHARACTERSTREAM |
Определяет атрибут-символьный_поток, принадлежащий классу. По умолчанию, классы не содержат никаких символьных потоков. Наследование символьных потоков управляется с помощью определения потока. |
CLIENTDATATYPE |
Определяет тип, используемый классом-типом_данных при отображении через ActiveX или Java. Не имеется никакого значения по умолчанию. Классы-типы_данных должны определять клиентский тип данных. Подклассы наследуют значение модификатора CLIENTDATATYPE и могут его изменять. |
DATATYPE |
Определяет, что класс является классом-типом_данных. По умолчанию, классы не являются классом-типом_данных. Подклассы не наследуют модификатор DATATYPE. |
DESCRIPTION |
Обеспечивает необязательное описание класса; Cache не использует это описание. По умолчанию классы не имеют никакого описания. Подклассы не наследуют значение модификатора DESCRIPTION. |
DISPLAYNAME |
Определяет псевдоним имени класса для отображения в формах, созданных Cache Object Form Wizard (Мастер Объектных Форм Cache). По умолчанию, классы не имеют никакого имени для отображения. Модификатор не наследуется подклассами. |
FINAL |
Определяет, что класс не может иметь подклассы. По умолчанию, классы могут иметь подклассы. |
FOREIGNKEY |
Определяет внешний ключ, принадлежащий классу. По умолчанию, класс не содержит никакие внешние ключи. Подклассы наследуют все внешние ключи, принадлежащие их суперклассам. |
INCLUDE |
Определяет внешний код, на который нужно сослаться из класса. По умолчанию, классы не включают никакой внешний код. Подклассы наследуют значение модификатора INCLUDE от их суперклассов. |
INDEX |
Определяет индекс, принадлежащий классу. По умолчанию, класс не содержит индексы. Подклассы наследуют любые индексы, принадлежащие их суперклассам. |
LIST |
Определяет атрибут-список. По умолчанию, классы не содержат атрибутов-списков. Наследование управляется с помощью определения атрибута-списка. |
METHOD |
Определяет метод. По умолчанию, классы не содержат методы. Наследование управляется с помощью определения метода. |
MODIFIED |
Определяет, как контролировать, изменились ли атрибуты класса со времени последнего сохранения. По умолчанию. |
ODBCTYPE |
Определяет тип данных, используемый классом при представлении через ODBC. Не имеется никакого значения по умолчанию. Классы-типы_данных должны определить тип ODBC. Подклассы наследуют значение модификатора ODBCTYPE и могут изменять его. |
PERSISTENT |
Определяет, что объект хранимый, и задает используемый способ хранения. По умолчанию, классы не хранимы. Подклассы наследуют модификатор PERSISTENT от их суперклассов. |
QUERY |
Определяет запрос. По умолчанию, классы не содержат никакие запросы. Подклассы наследуют любые запросы, принадлежащие их суперклассам. |
SERIAL |
Определяет способ хранения встраиваемых объектов, связанных с классом. По умолчанию встраиваемые объекты сохраняются в формате $LIST. Подклассы наследуют способы хранения, принадлежащие их суперклассам. |
SQLCATEGORY |
Определяет тип, используемый для вычислений в SQL. Не имеется никакого значения по умолчанию. Классы типа данных должны определить SQLCATEGORY. Подклассы наследуют модификатор SQLCATEGORY и могут изменять его. |
SQLROUTINEPREFIX |
Определяет имена программ для доступа к данным SQL. По умолчанию, SQLROUTINEPREFIX ClassName, где ClassName – имя класса. SQLROUTINEPREFIX не наследуется. |
SQLTABLENAME |
Определяет имя таблицы, чтобы идентифицировать класс при его проецировании в SQL. По умолчанию, Cache использует имя класса как имя его таблицы в SQL. Модификатор SQLTABLENAME не наследуется. |
SQLTRIGGER |
Определяет триггер SQL, принадлежащий классу. По умолчанию, класс не содержит никакие триггеры. Подклассы наследуют любые триггеры, принадлежащие их суперклассам. |
STORAGE |
Определяет способ хранения класса. По умолчанию, Cache использует заданный по умолчанию способ хранения, основанный на %CacheStorage, если класс хранимый. Если класс не хранимый, то способ хранения не определен. Подклассы наследуют любые способы хранения, принадлежащие их суперклассам. |
SUPER |
Определяет один или большее количество суперклассов для класса. По умолчанию, классы не имеют никаких суперклассов. Суперклассы наследуются. |
SYSTEM |
Определяет, что класс является внутренним системным классом объектов Cache. Не следует отмечать этим модификатором пользовательские классы. |
Параметр класса определяет специальное постоянное значение для всех объектов данного класса. При задании спецификации класса (или в любой момент перед компиляцией) можно устанавливать значения параметров класса. По умолчанию, значение каждого параметра – пустая строка (до тех пор, пока явно не задано соответствующее значение). Во время компиляции значение параметра устанавливается для всех экземпляров класса. Это значение не может быть изменено во время выполнения.
Подклассы класса могут перекрывать значение параметра класса и могут добавлять дополнительные параметры класса. Например, если атрибут класса назначает параметр типа данных класса, то объекты подклассов наследуют назначенное значение.
Параметры класса можно использовать в различных целях. Методы-генераторы, как правило, используют параметры класса во время компиляции класса, чтобы определить поведение классов-типов_данных или управлять генерацией метода другим способом. Параметры класса могут также использоваться для проверки правильности значения как описано ниже.
Каждый класс-тип_данных имеет параметры класса. Атрибуты типа данных (атрибуты, содержащие литеральные значения, соответствующие указанному типу данных) могут отменять параметры класса типа данных, настраивая правила, наложенные на атрибут. Например, класс типа данных %Integer имеет параметр класса MAXVAL, который определяет максимальное значение %Integer для экземпляра класса. MAXVAL использует генератор метода типа данных IsValidDT(), чтобы сгенерировать метод проверки правильности значения типа данных, удовлетворяющих также MAXVAL. Предположим, что пользователь определяет класс с атрибутом NumKids следующим образом:
ATTRIBUTE NumKids { Type = %Integer(MAXVAL=10); }
Эта спецификация генерирует метод по имени NumKidsIsValidDT() который проверяет, превышает ли значение NumKids 10.
Без параметров класса создание таких функциональных возможностей потребовало бы определения класса IntegerLessThanTen.
Методы – это действия, которые можно выполнить над объектом.
Каждый метод имеет имя, формальную спецификацию аргументов и программу, реализующую метод. Имя метода должно быть уникальным в пределах его класса.
В этом разделе описываются методы, их назначение и как их создать. Раздел содержит следующие темы:
Значения, возвращаемые методом
Аргументы метода
Модификаторы методов
Типы методов
Примечание: Слово “Метод” относится к методам экземпляра класса, или к методам, которые действуют на определенный экземпляр класса. Cache также поддерживает методы класса, или методы, которые не действуют на экземпляр класса.
Значения, возвращаемые методом
Назначение метода – получение возвращаемого им значения (например, данных). В приложении методы могут возвращать любой заданный тип данных. Чтобы включить в метод обработку ошибок, можно использовать тип возвращаемого значения %Status и макрокоманды.
Методы работают с переменными, которые они получают через их аргументы. Метод может иметь любое число аргументов. При определении метода задаются требуемые аргументы и тип данных каждого аргумента.
Например, метод Calculate имеет три аргумента:
METHOD Calculate(&count:%Integer,name,state:%String="CA") {
где
count и state объявлены как %Integer и %String соответственно. По умолчанию, аргументы имеют тип данных %String, так, что аргумент неопределенного типа – %String; name по умолчанию имеет тип %String.Примечание: InterSystems рекомендует определять тип данных каждого аргумента метода.
Если аргументу предшествует амперсанд ("&"), это называется ссылкой. Это позволяет устанавливать новое значение для переменной аргумента во время выполнения метода. Если аргументу не предшествует амперсанд, аргумент не может меняться во время выполнения метода.
Чтобы устанавить значение параметра по умолчанию, нужно задать его равным желаемому значению.
Изменять определение метода можно с помощью одного или большего количества модификаторов методов. Каждый модификатор необязателен и, если не указан явно, имеет значение по умолчанию.
Разрешено использовать следующие модификаторы методов:
CALL |
Когда вызывается метод, определяет реализующую его программу. По умолчанию, метод – не является методом-вызовом. Любые методы-вызовы наследуются подклассами класса. |
CLASSMETHOD |
Определяет, что метод является методом класса. По умолчанию, методы – методы экземпляра. Подклассы наследуют и не могут изменять модификатор CLASSMETHOD. |
CODE |
Определяет код на Cache ObjectScript, который будет выполнен при вызове метода. По умолчанию, метод – это метод-типа CODE не содержащий кода. Любые методы наследуются подклассами класса типа CODE. |
DESCRIPTION |
Обеспечивает необязательное описание метода; Cache не использует это описание. По умолчанию, методы не имеют никакого описания. Подклассы не наследуют модификатор DESCRIPTION. |
DISPLAYNAME |
Определяет псевдоним для метода в формах, созданных Cache Object Form Wizard. По умолчанию, методы не имеют никакого псевдонима. Модификатор не наследуется подклассами. |
EXPRESSION |
Определяет выражение, вычисляемое при вызове метода. По умолчанию, методы – не методы-выражения. Любые методы-выражения наследуются подклассами. |
FINAL |
Определяет, что подклассы не могут перекрывать метод. По умолчанию, методы не FINAL. Модификатор FINAL наследуется подклассами. |
GENERATOR |
Определяет программу, которая в комбинации с параметрами класса, генерирует другие методы. По умолчанию, методы – не методы-генераторы. Любые генераторы метода наследуются подклассами. |
PRIVATE |
Определяет, что метод может быть только вызван другими методами его класса или подклассами. (Если метод не PRIVATE, не имеется никаких ограничений на то, где он может быть вызван.) Подклассы наследуют методы PRIVATE и могут изменять модификатор PRIVATE. По умолчанию, метод не PRIVATE (общий). |
RETURNTYPE |
Определяет тип данных значения, возвращенного методом. Установка RETURNTYPE в пустую строку ("") означает, что не имеется никакого возвращаемого значения. По умолчанию, метод не имеет никакого возвращаемого значения. Модификатор RETURNTYPE наследуется подклассами и может изменяться подклассами. |
SQLPROC |
Определяет, что метод – хранимая процедура SQL. По умолчанию, метод не являетяся хранимой процедурой. Храненимые процедуры наследуются подклассами. |
В большинстве случаев термин "метод" относится к методам экземпляра. Метод экземпляра – метод, который вызван из объекта класса и выполняет некоторое действие, связанное с этим объектом. Все методы в предыдущих примерах в этой главе – методы экземпляра.
В дополнение к методам экземпляра, Cache поддерживает методы класса. В отличие от методов экземпляра, которые вызываются из специфического объекта и выполняют действия, связанные с этим объектом, метод класса не обязательно связан со специфическим объектом.
Вызывать метод класса можно двумя способоми:
Без объектной ссылки
Из определенного экземпляра, чтобы действовать на один или большее количество объектов класса
Метод класса может обратиться к другим методам класса, но не может обратиться к свойствам или методам экземпляра класса. Например,
Set x=##class(Invoice).%Open(oid)
Set x=##class(Patient).%New()
Cache поддерживает четыре типа методов:
Методы-коды (Code Methods)
Методы-выражения (Expression Methods)
Методы-вызовы (Call Methods)
Методы-генераторы (Method Generators)
Тип метода определяет способ написания кода (программы) для метода.
Метод-код (или простой метод) – метод, который использует программный синтаксис Cache ObjectScript.
Например, следующий код (программа) Cache ObjectScript определяет метод-код Speak() для класса Dog:
CLASS Dog {
SUPER = %Persistent;
PERSISTENT;
METHOD Speak() {
CODE = {
QUIT "Woof, Woof"
}
}
}
Метод-код может содержать любой разрешенный Cache ObjectScript код, включая встроенный SQL и встроенный HTML.
Предложим, что dog - это объект класса Dog. Тогда выше описанный метод можно вызвать следующим образом:
WRITE dog.Speak() -> Woof, Woof
Методы-выражения (Expression Methods)
Метод-выражение – метод, который, будучи вызван, выполняет вычисление указанного выражения.
Например, можно преобразовывать метод Speak) класса Dog из предыдущего примера в метод выражения:
METHOD Speak() {
EXPRESSION = "Woof, Woof";
}
Предложим, что dog - это объект класса Dog. Тогда выше описанный метод можно вызвать следующим образом:
WRITE dog.Speak()
который приводит к следующему коду:
WRITE "Woof, Woof"
Intersystems Corporation настоятельно рекомендует, чтобы все формальные переменные метода-выражения имели значения по умолчанию. Это предотвратит возможные проблемы замены формальных переменных на фактические и пропуска фактических переменных во время выполнения.
Например:
METHOD xyz(a=0,b=0,c=1) {
RETURNTYPE = %Integer;
EXPRESSION = a+b*c;
}
WRITE x.xyz(1,2,3)-> WRITE 1+2*3
WRITE x.xyz(a,^b)-> WRITE a+^b*1
WRITE x.xyz()-> WRITE 0+0*1
Примечание: В Cache нельзя использовать макрокоманды в методах-выражениях. Также, нельзя применять "передачу параметра по ссылке" для методов-выражений.
При определении метода можно указать, что при его запуске будет вызываться программа. Синтаксис для методов-вызовов:
call = tag^routine
где tag^routine определяет ссылку на метку tag программы routine.
Методы-вызовы полезны для включения существующего кода Cache ObjectScript в методы.
Методы-генераторы (Method Generators)
Методы-генераторы – методы, скорее не являются выполнимым кодом, а определяют во время компиляции класса выполняемый код (программу) метода. Это делается с помощью мощных средств наследования методов, которые позволяют производить высокоэффективный, специализированный код (программу), построенный в соответствии с требованиями наследования класса или свойства.
Главным образом методы-генераторы используются с классами-типами_данных и классами хранения.
Свойства определяют состояние объекта. Способ, которым можно обращаться и управлять значениями свойств объекта, зависит от определения объекта класса.
Имеются два вида свойств:
Свойства-атрибуты, которые имеют значения.
Свойства-отношения, которые устанавливают зависимости между объектами.
Cache в настоящее время поддерживает только свойства-атрибуты.
Многие объектные языки, например, Java и C++, не имеют истинных свойств, но имеют переменные, управляющие общими методами доступа. В Cache свойства отличны от переменных. Имеется большой выбор свойств, при этом:
Свойства могут быть литеральными значениями, ссылками к независимо хранимым и встраиваемым объектам, потокам или коллекциям литеральных значений и объектов.
Свойства автоматически имеют набор методов свойства, поддерживающих проверку правильности и способы хранения.
Свойства могут вызывать сложные преобразования и другие расширенные функциональные возможности поиска и хранения данных.
Как только свойства упомянуты, они вызывают автоматическую загрузку встраиваемых и хранимых объектов в память. Это называется свизлингом (swizzling).
Каждое свойство имеет имя, тип, необязательный набор изменяемых модификаторов и необязательный набор параметров для типа. Имя свойства должно быть уникальным в рамках его класса.
Можно изменять определение свойства с помощью одного или большего модификаторов свойств. Каждый модификатор необязателен и, если не указан явно, имеет значение по умолчанию.
Разрешено использовать следующие модификаторы свойств:
CALCULATED |
Определяет, что свойство не может храниться в отведенной для него оперативной памяти, когда имеющий это свойство объект является текущим. По умолчанию, атрибут не CACLULATED. Подклассы наследуют модификатор CACLULATED и не могут отменять его. |
DESCRIPTION |
Обеспечивает необязательное описание свойства; Cache не использует это описание. По умолчанию свойства не имеют никакого описания. Подклассы не наследуют модификатор DESCRIPTION. |
DISPLAYNAME |
Определяет условное имя отображения в формах, созданных мастером форм объекта (Cache Object Form Wizard). По умолчанию, свойства не имеют имени отображения. Свойства имени отображения не наследуются подклассами. |
FINAL |
Определяет, что подклассы не могут отменять свойство. По умолчанию, свойства не FINAL. Модификатор FINAL наследуется подклассами. |
INITIAL |
Определяет начальное значение для свойства. По умолчанию, свойства не имеют никакого начального значения. Подклассы наследуют модификатор INITIAL и могут отменять его. |
MULTIDIMENSIONAL |
Определяет, что атрибут имеет характеристики многомерного массива. По умолчанию, атрибут не многомерен. Подклассы наследуют модификатор MULTIDIMENSIONAL и не могут отменять его. |
PRIVATE |
Определяет, что свойство частно, то есть доступно только определенному классу. По умолчанию, свойства не частные. Подклассы наследуют модификатор PRIVATE и не могут отменять его. |
REQUIRED |
Определяет, что значение свойства должно быть установлено прежде, чем объект будет сохранен на диске. По умолчанию, свойства не требуют установки перед сохранением объекта на диске. Подклассы наследуют модификатор REQUIRED и могут отменять его. |
TRANSIENT |
Определяет, что свойство не хранится в базе данных. По умолчанию, свойства хранимы. Подклассы наследуют модификатор TRANSIENT и не могут отменять его. |
TYPE |
Определяет тип свойства, связанного со свойством класса-типа_данных, хранимого класса или встраиваемого класса. По умолчанию, тип свойства – %String. Подклассы наследуют модификатор TYPE. |
Свойства могут быть определены как общие или частные. Если свойства частные, к ним можно обращаться только методами объекта, которому принадлежат эти свойства. Если свойства общие, к ним можно обращаться методами других объектов.
В объектах Cache частные свойства всегда наследуются и видимы подклассами класса, который определяет свойство. В других языках это часто называют защищенными свойствами.
Свойства имеют некоторые автоматически ассоциируемые с ними методы. Эти методы не наследуются через стандартные механизмы наследования. Они используют специальный механизм поведения свойства для генерации ряда методов для каждого свойства.
Каждое свойство наследует набор методов от:
Хранимого класса, который обеспечивает некоторые встроенные методы, типа Get(), Set() и код проверки правильности.
Класса-типа_данных, если атрибут метода - атрибут типа данных. Многие из этих методов – методы-генераторы.
Классы методов свойства – системные классы. Нельзя определить или изменить метод свойства.
Например, пусть определен класс Person с тремя атрибутами:
CLASS Person
{
SUPER = %Persistent;
PERSISTENT;
ATTRIBUTE Name { TYPE = %String; }
ATTRIBUTE Age { TYPE = %Integer; }
ATTRIBUTE DOB { TYPE = %Date; }
}
Скомпилированный класс Person имеет набор методов, автоматически сгенерированных для каждого его атрибута. Эти методы унаследованы от системного класса Persistent, а также от класса-типа_данных, связанного с атрибутом. Имя метода – имя свойства, объединенное с именем метода от
унаследованного класса. Например, некоторые из методов, связанных с свойством Dob:person.DobIsValid()
person.DobLogicalToDisplay()
где IsValid () – метод класса Property , а LogicalToDisplay () – метод класса типа данных %Date.
Объектный синтаксис для свойств – правила обозначений для использования набора методов поиска и присвоения значений. Для каждого свойства, всякий раз, когда программа содержит синтаксис oref.Prop (где oref – объект, а Prop – свойство), система неявно устанавливает метод oref. PropGet() или метод oref. PropSet(new). Например:
Set person.DOB=x
вызывает:
Do person.DOBSet(x)
в то время как:
WRITE person.Name
вызывает:
WRITE person.NameGet()
Вычисляемое свойство не имеет значения, хранящегося в памяти, поэтому такое свойство следует обеспечить одним или обоими из PropGet() и PropSet() методами, выполняющими вычисление свойства.
Например, если класс Car имеет атрибут Weight:
ATTRIBUTE Weight {TYPE = %Integer; }
и вычисляемый атрибут WeightInKilos, не хранящийся в памяти:
ATTRIBUTE WeightInKilos {TYPE = %Integer; CALCULATED;}
а метод WeightInKilosGet() – метод, возвращающий значение, зависящее от текущего значения Weight:
METHOD WeightInKilosGet()
RETURNTYPE = %Integer;
CODE = {
QUIT ..Weight/2.2
}
}
тогда для объекта Car разрешен следующий код:
SET car.Weight=2200
WRITE car.WeightInKilos
1000
Если нужно обратиться к хранимому в оперативной памяти значению свойства из метода экземпляра класса, можно использовать следующий синтаксис для значений, хранящихся в памяти:
Set %Name="Carl"
Эта команда непосредственно устанавливает свойство Name, равным хранимому значению "Carl", обходя логику NameSet.
Использовать синтаксис значения, хранящегося в памяти, можно только в особых случаях.
Атрибут свойства – значение, связанное с объектом. Атрибуты, обычно, определяют состояние определенного объекта.
Тип атрибута определяется связанным с ним классом (или, в случае коллекции и многомерных атрибутов, модификатором). По умолчанию, атрибуты используют тип данных %String.
Имеются несколько типов атрибутов:
Атрибуты-типы данных (Data Type Attributes)
Атрибуты-ссылки к объектам (Object-Valued Attributes)
Атрибуты-коллекции (Collection Attributes)
Атрибуты-потоки (Stream Attributes)
Многомерные атрибуты (Multidimensional Attributes)
Атрибуты-типы данных (Data Type Attributes)
Самый простой атрибут – атрибут-тип данных. Это - литеральное значение, чье поведение управляется классом-типом_данных, связанным с атрибутом.
Например, класс может определять атрибут Count, используя тип данных %Integer:
ATTRIBUTE Count { TYPE = %Integer; }
где %Integer – класс-тип_данных, Count – атрибут-тип_данных.
Параметры типа данных можно использовать, чтобы поместить связи в разрешенные значения атрибутов-типов_данных. Можно определить значения для параметра класса-типа_данных следующим образом:
ATTRIBUTE Count { TYPE = %Integer(MAXVAL=100); }
Атрибуты-ссылки к объектам (Object-Valued Attributes)
Атрибут-ссылка – ссылка к другому объекту. Этот объект может быть встраиваемым или хранимым. В обоих случаях значение атрибута – OREF, как в памяти. На диске ссылка к хранимому объекту становится OID, в то время как встраиваемый объект становится единственной строкой, содержащей свойства всего встраиваемого объекта.
Например, если атрибут-ссылка Doc имеет тип Doctor (где Doctor является встраиваемым объектом), определение Doc было бы:
ATTRIBUTE Doc { TYPE = Doctor; }
Атрибуты-коллекции (collection Attributes)
Атрибут может быть определен как атрибут-коллекция с размещением признака коллекции в начале определения атрибута. Коллекции бывают: список (List) и массив (Array). Тип атрибута определяет содержание коллекции. Например, можно определить атрибут Colors, который является списком значений %String:
LIST ATTRIBUTE Colors { TYPE = %String; }
Можно также определить атрибут Doctor, который является массивом ссылок к объектам Doctor:
ARRAY ATTRIBUTE Doctors { TYPE = Doctor; }
Объекты-коллекции используются для манипулирования коллекциями. Тип используемого объекта-коллекции зависит от класса и типа коллекции, связанного с атрибутом. Это показано в следующей таблице:
Тип объекта |
Коллекция массива |
Коллекция списка |
Объект класса-типа_данных |
%ArrayOfDataTypes |
%ListOfDataTypes |
Встраиваемый объект |
%ArrayOfObjects |
%ListOfObjects |
Хранимый объект |
%ArrayOfObjects |
%ListOfObjects |
Управлять атрибутом коллекции можно, используя методы коллекции объекта, связанные с объектом. Например, учитывая атрибут Colors, который был определен ранее, можно использовать методы, поддерживаемые классом %ListOfDataTypes:
Do obj.Colors.Insert("Red")
Do obj.Colors.Insert("Green")
Do obj.Colors.Insert("Blue")
Атрибуты-потоки (Stream Attributes)
Для сохранения большого количества данных можно определить поток. Имеются два типа потоков: двоичные (бинарные) и символьные потоки. Бинарные потоки могут использоваться для сохранения больших бинарных объектов, например, изображений. Символьные потоки могут использоваться, чтобы сохранить информацию большого объема, например, текстовый файл.
Чтобы создать атрибуты-потоки, можно использовать модификаторы класса CHARACTERSTREAM и BINARYSTREAM следующим образом:
CLASS JournalEntry {
ATTRIBUTE Date {TYPE=%Date;}
BINARYSTREAM PictureOfTheDay;
CHARACTERSTREAM EventsOfTheDay;
}
Атрибутами-потоками можно управлять с помощью объекта %Stream. Потоки имеют внутренний указатель позиции в пределах данных. Метод Write() добавляет данные к потоку с текущей позиции указателя:
SET entry=##class(JournalEntry).%New()
DO entry.EventsOfTheDay.Write("Я пошел к доктору.")
; Добавляется определенный текст в конец EventsOfTheDay.
Метод Read() возвращает заданное число байтов или символов в строке:
SET events=entry.EventsOfTheDay.Read(100)
; Возвращает до 100 символов, хранимых в EventsOfTheDay.
; В данном случае events= "Я пошел к доктору."
Метод Rewind() возвращает указатель потока на его начало. Этот метод не требует первоначального вызова, но при использовании потока должен вызываться. Например:
SET events=entry.EventsOfTheDay.Read(100)
; Возвращает до 100 символов, хранимых в EventsOfTheDay.
; В данном случае events= "Я пошел к доктору."
SET events=entry.EventsOfTheDay.Read(100)
: events=”” , так как указатель находится в конце потока
DO entry.EventsOfTheDay.Rewind()
SET events=entry.EventsOfTheDay.Read(100)
: И снова events= "Я пошел к доктору."
%Stream содержит другие методы, используемые для непосредственного доступа к объектам потока, но они не применимы к атрибутам-потокам.
Многомерные атрибуты (Multidimensional Attributes)
Атрибуты могут быть отмечены как многомерные. Этот атрибут имеет переменную экземпляра, связывающую атрибут со всеми характеристиками узла массива и с которой операции над массивом могли бы работать подобно $ORDER.
Если abc – многомерный атрибут:
ATTRIBUTE abc { MULTIDIMENSIONAL; }
то можно использовать abc:
$DATA(abc)
$DATA((abc(3))
$GET((abc(3))
$ORDER((abc("hello",3))
KILL abc
Методы свойства и классы-типы_данных не используются для генерации методов с многомерными атрибутами. Таким образом, многомерный атрибут по имени Kids не имеет методов KidsGet(), KidsSet() или KidsLogicalToDisplay(). Не делается никакой проверки правильности при установке атрибута со значением.
Объектный синтаксис не может использоваться для многомерных атрибутов. Многомерные атрибуты не могут быть сохранены в таблицах SQL или представлены через таблицы SQL.
Фильтр не выполняет операции, если не выполняются указанные критерии. Запросы определяют комплексный набор правил для выбора объектов, основанных на одном или большем количестве атрибутов. Результат запроса – набор объектов, удовлетворяющих атрибутам (критериям) запроса. Cache имеет интерфейсы для обработки результатов запросов в Cache ObjectScript, ActiveX и Java.
Запросы могут быть написаны в SQL или Cache ObjectScript. Запросы пишут, используя Cache SQL Query Wizard в Cache Object Architect (закладка SQL).
Запросы обеспечивают логическое сравнение значений данных. Можно выполнять проверку на "больше чем", "равно" или "меньше чем" некоторое значение и включать в набор результатов только те объекты, которые удовлетворяют условиям запроса. Можно также выполнять проверку на начало строки с некоторой последовательности символов и включать в набор результатов объекты, прошедшие такую проверку.
В одном запросе можно выполнять множественные сравнения, основанные на одном или большем количестве атрибутов. Можно выполнять логическую группировку критериев. Например, критерий один И критерий два И критерий три – к набору результатов будут добавлены объекты, прошедшие все испытания; критерий один ИЛИ критерий два ИЛИ критерий три – к набору результатов будут добавлены объекты, прошедшие хотя бы одно испытание; критерий один ИЛИ критерий два И критерий три – к набору результатов будут добавлены объекты прошедшие первое испытание или второе и третье.
Изменять определение запроса можно с помощью одного или большего количества модификаторов запросов. Каждый модификатор необязателен и, если не указан явно, имеет значение по умолчанию.
Разрешено использовать следующие модификаторы запросов:
DESCRIPTION |
Обеспечивает необязательное описание запроса; Cache не использует это описание. По умолчанию, запросы не имеют никакого описания. |
|
FINAL |
Определяет, что подклассы не могут отменять запрос. По умолчанию, запросы не FINAL. |
|
SQLQUERY |
Определяет код выполнения запроса. SQLQUERY следует определять только в том случае, если TYPE=%SQLQUERY. |
|
SQLPROC |
Определяет, что к запросу можно обращаться также как к хранимой процедуре SQL. По умолчанию, запрос не проецируется как хранимая процедура. |
|
TYPE |
Определяет, содержит ли запрос код SQL или код Cache ObjectScript. По умолчанию, запрос будет содержать код SQL. |
Каждый запрос должен содержать спецификацию строки, содержащую до двух параметров, изменяющих тип запроса. Спецификация дает информацию относительно содержания и порядка полей, возвращаемых для каждой строки в результате запроса.
CONTAINID опционально определяет, является ли первое поле строки ID.
Внимание: Cache не проверяет это значение. Если определить CONTAINID=1, и первое поле – не ID, не будет сгенерирована никакая ошибка. Если логические схемы для обработки информации запроса зависят от наличия ID в первом поле, можно проверить правильность параметра CONTAINID.
ROWSPEC дает информацию относительно имен, типов данных, заголовков и размера полей в каждой строке. Имя, тип данных, если он отличен от типа данных, назначенного по умолчанию атрибута, и необязательный заголовок, отделенные двоеточиями, определены для каждого поля в порядке, в котором они возвращены запросом. Метаданные для различных полей разделяются запятыми.
Будет сгенерирована ошибка "Cardinality Mismatch", если каждое поле не имеет метаданных для каждого поля, возвращаемого запросом.
Например, запрос ByName класса IscPerson имеет следующее объявление типа:
TYPE=%SQLQuery(CONTAINID=1,ROWSPEC="ID:%Integer,Name,DOB,SSN");
Код SQL для этого запроса:
SQLQUERY =
{
SELECT ID, Name, DOB, SSN
FROM IscPerson
WHERE (Name %STARTSWITH %ALPHAUP(:name))
}
Параметр CONTAINID определяет, что первое поле – ID, и первое поле, указанное в инструкции SELECT, фактически, ID. ROWSPEC определяет, что поля должны быть ID, как целое число, за которым следует Name, DOB, и SSN. Инструкция SELECT содержит поля ID, Name, DOB, и SSN.
Индексы определяют определенное сортируемое подмножество часто требуемых данных, связанных с классом. Индексы используются для оптимизации (ускорения) выполнения запроса.
Индексы автоматически охватывают весь класс, в котором они определены: если класс Person имеет подкласс Student, то все индексы, определенные в Person содержат и объекты Person, и объекты Student. Индексы, определенные в классе Student, содержат только объекты Student.
Индексы могут сортироваться по одному или большему количеству атрибутов, принадлежащих классу. Кроме того, индексы могут хранить дополнительные данные, которые часто требуются запросом, основанным на сортируемых атрибутах.
Это очень расширяет область действия запроса, например, если оптимизатор запроса находит индекс, сортируемый атрибутами, то запрос, основанный на этом, также содержит другие атрибуты возврата запроса. Если индекс найден, набор результатов может быть создан и возвращен без обращения к диску.
Можно изменять индексное определение с помощью одного или большего количества индексных модификаторов. Каждый модификатор необязателен и, если не указан явно, имеет значение по умолчанию.
Разрешено использовать следующие модификаторы:
ATTRIBUTE |
Определяет атрибуты, включаемые и сортировку по индексу. По умолчанию, атрибуты не индексированы. |
DATA |
Определяет дополнительные атрибуты, хранимые в индексе. По умолчанию, никакие дополнительные данные не хранятся в индексе. |
DESCRIPTION |
Обеспечивает необязательное описание индекса; Cache не использует это описание. По умолчанию, индексы не имеют никакого описания. |
EXTENT |
Определяет, что индекс идентифицирует (вплоть до класса) объекты, которые принадлежат классу. Индексы EXTENT содержат атрибуты; они используются только, чтобы идентифицировать членов EXTENT. По умолчанию, индекс – не индекс EXTENT. |
IDKEY |
Определяет атрибут или набор атрибутов, чтобы использовать ID как часть OID вместо ID по умолчанию. Ключ ID должен иметь уникальные значения для каждого объекта класса. Эти значения не могут изменять состояние объектов. По умолчанию, индекс IDKEY – не ключ ID. |
PRIMARYKEY |
Определяет индексы, которые формируются как PKEY в SQL. Любой индекс, определенный как первичный ключ, должен содержать уникальные значения для каждого объекта. По умолчанию, индекс – не первичный ключ. |
UNIQUE |
Определяет, что каждый объект имеет уникальное значение для атрибута или комбинации атрибутов в индексе. По умолчанию, индекс не ограничен уникальным значением. |
Упорядочение индексов (Index Collation)
Каждый атрибут, указанный в модификаторе индекса ATTRIBUTE, может также иметь необязательный тип упорядочения. Если тип упорядочения определен для атрибута, значение этого атрибута для каждого экземпляра преобразуется указанным способом прежде, чем данные будут отсортированы и сохранены в индексе. Если упорядочение не задано, тогда в качестве значения упорядочения используется свойство. Это значение унаследовано от атрибута класса типа данных. Если модификатор UNIQUE, PRIMARYKEY или IDKEY определен, упорядочение не выполняется.
Для определения типа упорядочения для атрибута используют следующий синтаксис:
INDEX IndexName {
ATTRIBUTE = AttributeName:CollationType;
}
Различные атрибуты могут иметь различные типы упорядочения. Например, атрибут Name использует упорядочение ALPHAUP, в то время как SSN использует упорядочение EXACT:
INDEX NameSSNIndex {
ATTRIBUTE = Name:ALPHAUP,SSN:EXACT;
}
Cache поддерживает следующие типы упорядочения:
ALPHAUP |
Удаляет все символы пунктуации, кроме вопросительных знаков ("?") и запятых (",") и затем переводит все символы нижнего регистра в верхний. |
EXACT |
Трансляция не выполняется. |
MINUS |
Делает значение числовым и изменяет его знак. |
PLUS |
Делает значение числовым. |
SPACE |
Переводит значение в строку. |
UPPER |
Переводит все символы нижнего регистра в символы верхнего регистра. |
Обработка событий: триггеры (Triggers) и методы обратной связи (Callback Methods)
В Cache в настоящее время поддерживаются два типа обработки событий: триггеры и методы обратной связи. Триггеры – это части программы Cache ObjectScript, выполняемые когда происходят определенные события SQL. Методы jбратной cвязи выполняются, когда выполняются системные методы Cache.
Обработка события SQL: триггеры (Triggers)
Триггеры – сегменты программы, выполняемые, когда в Cache SQL происходят определенные события. Cache поддерживает триггеры, основанные на выполнении команд INSERT, UPDATE и DELETE. В зависимости от триггерного определения указанная программа будет немедленно выполнена или до, или после выполнения соответствующей команды. Каждое событие может иметь множественные триггеры, столько, сколько их будет при выполнении.
Управляемые Cache SQL триггеры будут выполнены всякий раз, когда происходят эти события, даже если они вызваны с использованием объектного синтаксиса. Например, если используется %CacheSQLStorage, то методы %Save() и %Delete() могут вызывать триггеры.
Определение класса может включать список триггерных модификаторов. Триггерным модификатором может быть:
CODE |
Программа Cache ObjectScript будет выполнена, когда происходит событие, при котором срабатывает триггер. Триггеры имеют полную поддержку функциональных возможностей Cache ObjectScript, включая встроенный SQL и объектный синтаксис. |
EVENT |
Событие, с которым этот триггер связан. Возможные события включают INSERT, UPDATE, DELETE. Вместе со значением TIME определяет время вызова триггера. |
NAME |
Имя триггера. Оно должно быть уникальным в пределах области триггеров. |
ORDER |
Номер, указывающий порядок, в котором должен быть выполнен триггер, когда для определенного события имеется больше чем один триггер. ORDER может быть неопределен, если только один триггер определен для события. Если больше чем один триггер связан с определенным событием, каждый должен иметь уникальное порядковое значение. |
TIME |
Вместе с модификатором EVENT, TIME определяет, когда должен быть вызван триггер. Возможные значения: BEFORE и AFTER. |
Обработка объектных событий: методы обратной связи (Callback Methods)
Методы обратной связи называются системными методами и позволяют выполнять дополнительную, написанную пользователем обработку специфического события. Чтобы отличать эти типы методов, им дают имена %OnEvent, где "Event" описывает событие, которое запускает обратную связь.
Если событие поддерживает метод обратной связи, метод, управляющий событием будет автоматически искать метод обратной связи и выполнять его, если он существует. Явно никогда нельзя выполнять методы обратной связи.
Поддерживаемые методы обратной связи (Callback Methods)
Так как различные типы классов поддерживают различные события, не все методы обратной связи доступны всем классам. Например, к методам обратной связи, запущенным для сохранения или удаления объекта, нельзя обращаться хранимым объектам, так как эти объекты не могут быть сохранены или удалены.
В Cache поддерживаются следующие методы обратной связи:
%OnNew |
Вызывается %New() всякий раз, когда создается новый объект. |
%OnClose |
Вызывается %Close() всякий раз, когда закрывается объект. |
%OnValidateObject |
Вызывается %ValidateObject() всякий раз, когда требуется проверить существование объекта. |
%OnDetermineClass() |
Вызывается %Open() или %Delete() всякий раз, когда объект, идентифицированный частичным OID, открывается или удаляется. |
%OnOpen |
Вызывается %Open() всякий раз, когда открывается объект. |
%OnDelete() |
Вызывается %Delete() всякий раз, когда удаляется объект. |
За исключением %OnDetermineClass(), эти методы могут использоваться, чтобы выполнить любую обработку в требуемом событии.
%OnDetermineClass() – особый случай. Когда %Open() или %Delete() дается частично-сформированный OID, то вызывается метод %OnDetermineClass(), если пользователь имеет хотя бы одно фактическое имя класса. Если %OnDetermineClass() указывает, что объект принадлежит различным классам, то будет выполнен Open() нового класса или метод %Delete(). Если метод не %OnDetermineClass(), просто предполагается, что текущий класс – правильный класс.
===========================================
[
Содержание_документа] [Конец_документа][
Выше] [Начало_этой_части] [Конец_этой_части] [Далее]===========================================
По вопросам поддержки любых продуктов InterSystems Corporation обращайтесь:
Россия 121019, Москва, Волхонка, 6, #14
Тел
.: +7 095 203-4649Факс
: +7 095 956-8268 info@intsys.dol.ru http://www.intersystems.ru
Copyright © 1999, InterSystems Corporation. Все права защищены.