nsutextbook (1037554), страница 14
Текст из файла (страница 14)
Обычно индекс строится длявсех экземпляров класса, включая все его подклассы. Например, индекс класса Person сподклассом Student включит в себя не только всех «просто» лиц, но также всех студентов.Индекс подкласса студент Student, напротив, будет содержать только студентов.Каждый индекс создается на основе одного или нескольких свойств класса.
При этомможно задать способ сортировки. Возможны следующие способы сортировки:EXACT – без преобразований как есть;UPPER – с преобразованием в прописные;ALPHAUP – с преобразованием в прописные и удалением всех знаков препинания;SPACE – принудительно устанавливается алфавитная сортировка также и для чисел;PLUS – устанавливается числовая сортировка даже для строк символов;MINUS – обратная числовая сортировка.В дополнение к свойствам, по которым производится сортировка, в индексах могутсодержаться другие свойства в виде полей данных. Благодаря этому их значения уже известны из индекса, что при определенных обстоятельствах позволяет избежать операций,связанных с доступом к данным.5.10.
ПакетыПакет это простой способ группирования взаимосвязанных классов под общим именем. Например, приложение может иметь систему счетов: “Accounting” и систему вложений: “Inventory”. Классы, реализованные в этом приложении, могут быть организованы впакеты “Accounting” и “Inventory”.61На каждый из этих классов можно ссылаться, используя полное его полное имя, которое состоит из имени пакета и имени класса:Do ##class(Accounting.Invoice).Method()Do ##class(Inventory.Item).Method()Если имя пакета может быть определено из контекста, то имя пакета может бытьопущено:Do ##class(Invoice).Method()Пакет это просто соглашение об именах: он не обеспечивает никакой другой функциональности, кроме именования класса.Так же как и класс, определение пакета существует внутри рабочей области Caché.Рабочая область Caché это логическое представление данных, как правило, одной базыданных.5.10.1.
Имя пакетаИмя пакета это просто строка. Оно может содержать точку “.”, но больше никакойдругой пунктуации. Например, полное имя класса “Test.Subtest.TestClass” означает, что«TestClass» это имя класса, а “Test.Subtest” это имя пакета. В схеме базы данных в SQLимя будет преобразовано к виду: “Test_TestClass”.Существует несколько ограничений на длину и использование имен пакетов:• Имя не более 31 символа, включая точку, но различаются только первые 25символов.• Внутри области, имя каждого пакета должно быть уникально.5.10.2. Определение пакетовПакеты подразумеваются при именовании классов. Самый простой способ созданияпакета – задать его имя при создании нового класса в Caché Studio с использованием мастера, в котором также можно просмотреть список всех пакетов. При удалении последнегокласса пакета, сам пакет автоматически удаляется.
Пакет можно указать при программномсоздании класса. Например:Class Accounting.Invoice {}Класс Invoice внутри пакета “Accounting”.Используя Caché Studio, можно просматривать и редактировать дополнительные характеристики пакетов, такие как его описание, щелкнув правой кнопкой мыши на именипакета в окне проекта и выбрав меню «Информация о пакете».5.10.3. Использование пакетовСуществует два пути использования имени класса:• Использование полного имени класса вместе с именем пакета.
Например: пакет.класс• Использование короткого имени класса, позволив компилятору классов самому решать какому пакету будет принадлежать класс.Пример использования полного имени:// создать экземпляр Lab.PatientSet patient = ##class(Lab.Patient).%New()Для того, чтобы компилятор сам мог решать к какому имени будет принадлежатькласс, необходима директива #IMPORT в коде .MAC или внутри определения класса.
Если такой директивы нет, то имя класса будет ассоциировано с пакетом “User” или“%Library”. Например:// создание экземпляра класса PersonSet person = ##class(Person).%New()62// это тоже самое, что иSet person = ##class(User.Person).%New()5.10.4. Директива #IMPORTДиректива #IMPORT позволяет задавать пакет, где следует искать класс. Например:#import Lab// Класс "Patient" внутри пакета LabSet patient = ##class(Patient).%New()Можно использовать несколько директив #IMPORT внутри программы MAC:#import Lab#import Accounting// Поиск класса "Patient" внутри пакетов Lab & АccountingSet pat = ##class(Patient).%OpenId(1)// Поиск класса "Invoice" внутри пакетов Lab & AccountingSet inv = ##class(Invoice).%OpenId(1)Порядок следования директив #IMPORT не имеет значения и может привести кошибке в случае двусмысленного использования.
Например, если имеется одно и то жеимя класса в двух разных пакетах, заданных директивой #IMPORT. Чтобы избежать этогоиспользуйте полное имя класса.Директива IMPORT определяет, какой пакет используется для разрешения ссылкивнутри определения класса. Если директива не размещена, то предполагается использование следующего кода:#import UserЕсли одна директива уже определена, то директива с User автоматически не подставляется, нужно написать:#import MyPackage#import User5.10.5.
Пакеты и SQLКаждый пакет соответствует SQL схеме. Например, если класс называетсяTeam.Player (класс Player в пакете “Team”), соответствующая таблица называется“Team.Player” ( таблица Player в схеме “Team”).Пакет по умолчанию “User” соответствует схеме “SQLUser”. Следовательно, класс сименем User.Person соответствует таблице с именем SQLUser.Person.Если имя пакета содержит точку, то она заменяется подчерком.
Например: классMyTest.Test.MyClass (класс MyClass, пакет “MyTest.Test”) становится таблицейMyTest_Test.MyClass (MyClass – таблица, “MyTest_Test” – схема).Схема по умолчанию SQLUser. Например:Select ID, Name from Person// То же самое что и:Select ID, Name from SQLUser.Person5.10.6. Встроенные пакетыДля совместимости с ранними версиями используются «встроенные» пакеты:• “%Library” – любой %class без имени пакета это просто часть пакета“%Library”• “User” – любой не-% class без имени пакета принадлежит пакету “User”63Глава 6. Работа с объектами6.1. Создание новых объектовОсновной синтаксис для создания новых экземпляров объектов это использованиеметода класса %New:Set oref = ##class(Classname).%New()где oref ссылка OREF на новый объект и Classname это имя класса, чувствительно крегистру букв и может содержать имя пакета.##class() – это макровызов, который используется для вызова методов класса.Например, для создания нового объекта Person используется следующий синтаксис:Set person = ##class(MyApp.Person).%New()Методу %New можно передать необязательный параметр.
Если он присутствует,этот аргумент передается методу-триггеру %OnNew объекта. Использование этого аргумента зависит от реализации конкретного класса.6.2. Ссылки на экземпляр объектаДля доступа к экземпляру объекта можно использовать следующие ссылки:1. OID – идентификатор экземпляра объекта в базе данных2. ID – идентификатор экземпляра внутри класса в базе данных3. OREF – ссылка на экземпляр объекта в оперативной памяти.Связь между OID и ID задается следующим образом:Set OID = $LB( ID, “пакет.класс”)Например:Set OID=$LB(ID,”User.Books”)6.3.
Открытие объектовМожно открыть существующий хранимый объект с помощью его идентификатораID, используя следующий синтаксис:Set oref = ##class(Classname).%OpenId(ID)где oref – это переменная, содержащая OREF открываемого объекта, Classname этоимя класса, ID это идентификатор открываемого объекта. Classname чувствителен к регистру букв.Например, чтобы открыть объект Sample.Person с ID 22:Set person = ##class(Sample.Person).%OpenId(22)Write person.Name,!где person это новая объектная ссылка OREF на объект Person.Можно также открыть объект, используя его полный OID:Set oref = ##class(Classname).%Open(oid)где oref содержит ссылку OREF, Classname имя класса, oid это полный OIDобъекта.Обычно приложения используют метод %OpenId.Имея открытый объект можно просматривать или изменять его свойства, используяметоды описанные ниже.6.4.
Изменение свойств объектаНаряду с методами объект имеет свойства, которые определяют его состояние.Большинство свойств имеют значения, например, такие как имя человека, его дата рождения, так же есть свойства-связи, которые задают связи между объектами.Синтаксис для изменения свойства объекта:Set oref.PropertyName = value64где oref содержит OREF на определенный объект, PropertyName имя свойства, value– значение. Например, назначить свойству Name объекта Person новое значение:Set person.Name = "Александр"где person ссылка OREF на объект Person и “Александр ” новое значение свойстваName.
Этот синтаксис работает для любого типа свойств.Внутри методов экземпляра доступ к свойствам выполняется с помощью синтаксиса:set ..<свойство>=<значение>. Например:set ..Adress=”Русская 35”.Также для доступа к свойствам экземпляра можно использовать переменную ##this,которая содержит OREF- ссылку на экземпляр объекта:Set ##this.Name=”Иванов”Ниже описан синтаксис для работы с разными типами свойств:• свойства ссылки на хранимые объекты• свойства ссылки на встраиваемые объекты• свойства коллекции: свойства-списки и свойства-массивы• свойства потоки.6.5.