Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:MUMPS СУБД. Практика применения и опыт программирования.pdf
X
- •Предисловие
- •Введение
- •Среда исполнения
- •Команды
- •Команды присваивания
- •Условные команды
- •Команды передачи управления
- •Команды ввода-вывода
- •Служебные команды
- •Постусловия
- •Операторы
- •Переменные
- •Числа и строки
- •Функции
- •$DATA
- •$GET
- •$ORDER
- •$NEXT
- •$QUERY
- •$NAME
- •$QLENGTH
- •$QSUBSCRIPT
- •$ASCII
- •$CHAR
- •$EXTRACT
- •$PIECE
- •$LENGTH
- •$REVERSE
- •$FIND
- •$TRANSLATE
- •$JUSTIFY
- •$FNUMBER
- •$TEXT
- •$RANDOM
- •$VIEW
- •$SELECT
- •$STACK
- •Списковые функции
- •Битовые функции
- •Модули
- •Рутины
- •Передача параметров
- •Неопределенные значения
- •Шаблоны
- •Косвенность
- •Косвенность имени
- •Косвенность индексов
- •Косвенность метки
- •Косвенность аргумента
- •Косвенность шаблона
- •Интерпретатор
- •Голая ссылка
- •Очередность выполнения
- •Очередность вычисления выражений
- •Очередность вычисления имен
- •Стекование $test
- •Комментарий
- •Стандарт и расширения
- •Глобалы
- •B-дерево
- •Кодирование индексов
- •Размер блока
- •Кеширование блоков
- •Структуры
- •Индексация
- •Группировка
- •Каноничность индексов
- •Маппинг
- •Индексация данных
- •Общие принципы
- •Механизм поддержки индекса
- •Простой индекс
- •Составной индекс
- •Покрывающий индекс
- •Кластерный индекс
- •Хеш-индекс
- •Битмап индекс (bitmap)
- •Битслайс индекс (bitslice)
- •Нормирование значений
- •Выборки по индексу
- •Многоиндексная выборка (zig-zag)
- •Дифференциальное индексирование
- •Индексация длинных атрибутов
- •Межтабличный индекс
- •Индекс с условием на вставку
- •Индекс на вычисляемый атрибут
- •Индекс поиска по фрагменту
- •Индексация для шаблона (like)
- •Индексация уникального атрибута
- •Массовое перестроение индексов
- •Операции с древовидными индексами
- •Операции с битовыми индексами
- •Сортировка по индексу
- •Статистики и кардинальность
- •Конкурентный доступ
- •Параллельность выполнения
- •Блокировки
- •Функция $INCREMENT
- •Транзакции
- •Блокировки в транзакциях
- •Функция $BIT
- •Дедлоки
- •Обработка ошибок
- •Состояние ошибки
- •ZTRAP
- •GT.M
- •MiniM
- •ETRAP
- •Определение
- •$ETRAP
- •$ECODE
- •$ESTACK
- •Ошибки в обработчике ошибок
- •$STACK()
- •Трассировка
- •BREAK
- •MiniM Debugger
- •Serenji Debugger
- •Внешний мир
- •Общие принципы
- •Терминальный интерфейс
- •Сокеты
- •HTTP клиент
- •Вебсервер на MUMPS
- •WebLink
- •Проблемы HTTP
- •Поверх HTTP
- •Подключаемые DLL (SO)
- •Файлы
- •Внешние процессы
- •Порты
- •Практика применения
- •Терминальный режим
- •Редакторы рутин
- •Экспорт и импорт
- •Препроцессор
- •Формат $HOROLOG
- •Опции устройств
- •$X и $Y
- •Возврат результатов
- •Возврат по значению ($$)
- •Возврат по ссылке
- •Запись в предопределенную переменную
- •Возврат значений косвенно
- •Итеративный возврат
- •Потоковый возврат
- •%Z - рутины
- •Планирование файлов
- •Память и сборка мусора

1.10. ПЕРЕДАЧА ПАРАМЕТРОВ 131
Общие правила и возможности MUMPS систем по работе с огромными данными на ограниченных ресурсах позволяют строить прикладные
системы большого или, можно сказать, сверхбольшого объема.
Исполняемый байткод кешируется и используется по необходимости,
и MUMPS системе обычно не требуется хранить в оперативной памяти весь объем кода приложения. Именно то обстоятельство, что сами
рутины используются системой выполнения только по необходимости, и
позволяет строить большие прикладные системы, объем программного
кода которых может превосходить как объем оперативной памяти, так и
размер адресуемого пространства памяти.
Для редактирования исходного текста рутин большинство современных MUMPS систем имеют либо собственные средства редактирования, либо могут быть использованы сторонние редакторы. Это могут
быть графические оконные программы с MDI интерфейсом, консольные
с псевдографикой включая доступ по telnet, или редакторы с WEB интерфейсом.
В случае если MUMPS система хранит исходный текст во внешних
файлах, также могут быть использованы текстовые редакторы общего
назначения, сохраняющие файлы в каталогах файловой системы или в
каталогах FTP.
Поскольку исполняющие среды MUMPS систем являются системами позднего связывания, для компиляции рутин нет необходимости в
каких-либо объявлениях, что другая рутина и тем более какая-то из меток в ней существует. В отличие от языков компилирующего типа, где
необходимо связывание имен подпрограмм с предварительным описанием их прототипа, в MUMPS это не требуется. В техническом отношении
можно компилировать и импортировать рутины в любом порядке. Более
того, можно выполнять рутину, если она обращается к еще несуществующей рутине или метке, в этом случае исполняющая система просто
сгенерирует соответствующую ошибку и управление будет передано на
обработчик ошибок.
1.10 Передача параметров
При вызове метки как подпрограммы ей могут быть переданы параметры. Для языка MUMPS можно передать параметры любой метке, код
вызова транслируется совершенно независимо от вызываемого кода. Будет ли на самом деле метка принимать параметры, это определяется
разработчиком, описывающим метку.
Для вызывающей стороны параметры являются фактическими, для

132 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
вызываемой - формальными. Синтаксически формальные параметры следуют в круглых скобках сразу после имени метки один за другим и
описаны также как локальные переменные. При вызове подпрограммы
формальные параметры сопоставляются фактическим. В контексте выполнения команды, следующей после метки, эти формальные параметры
для этого контекста уже являются именами локальных переменных.
При этом, что интересно, ничто не мешает передать управление на
строку, непосредственно следующую после строки с меткой, но в этом
случае в контексте процесса не будет производиться сопоставление с
формальными аргументами, и локальные переменные с теми же именами
будут иметь иное значение и область видимости, то есть будет иной
контекст этих переменных.
Стандарт языка определяет следующие варианты передачи фактических параметров:
1. По значению
2. По ссылке на локальную переменную
3. Опускание параметра
При этом формальные параметры могут быть либо именами локальных переменных, либо опущены. В случае если параметр опущен, с ним
ничего не сопоставляется, даже если было что-то передано. При указании имени локальной переменой с ней сопоставляется соответственно
способу передачи:
1. Локальная переменная принимает переданное значение.
2. Локальная переменная становится синонимом переменной, переданной по ссылке, и указывает на нее на ее уровне стека. Все
операции с такой локальной переменной автоматически заменяются на операции с переданной по ссылке переменной.
3. Локальная переменная принимает неопределенное значение.
При покидании уровня стека локальные переменные формальных параметров автоматически уничтожаются, а при передаче по ссылке все
выполненные изменения с переданной переменной остаются.
Положим для примера, что имеется метка с параметрами:
label(a,b,c)

1.10. ПЕРЕДАЧА ПАРАМЕТРОВ 133
Для передачи параметра по значению нужно указать значение. Это
может быть произвольное вычисляемое выражение. Перед вызовом выражение вычисляется и значение передается.
do label(1+2,3+4,5+6)
do label($h,$$func(789),^DATA)
Для передачи параметра по ссылке нужно указать точку с последующим корневым именем передаваемой локальной переменной. Передача
имени с индексом не допускается.
new local1 s local1(1)=$h
new local2 s local1(2)=$h
new local3 s local1(3)=$h
do label(.local1,.local2,.local3)
Для вызова с опусканием параметра в его позици ничего не пишется:
do label(,,)
do label(,)
do label()
Если указано фактических параметров меньше чем метка принимает формальных, остальные формальные параметры также принимают
неопределенное значение, как если бы было указано правильное число
формальных параметров, но они были бы опущены.
Язык MUMPS отличает в фактическом параметре точку как спецификатор передачи по ссылке и точку как начало спецификации числа.
Во втором случае передается параметр по значению.
Эти три способа передачи параметров являются стандартными и поддерживаются всеми современными реализациями MUMPS систем. При
этом производители могут дополнительно поддерживать другие способы
передачи параметров. В частности, системы MiniM и Cach´e поддерживают дополнительно 2 способа передачи параметров:
1. Автоматическое присваивание
2. Неопределенное количество параметров
Если используется передача параметра с автоматическим присваиванием, то можно указать, какое значение в этом случае ему необходимо
автоматически присвоить. Синтаксически указывается имя формального
параметра, символ присваивания = и следующая за ним константа.
Пусть есть такая подпрограмма:

134 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
LABEL(v=123)
q v
Её можно вызвать как
$$LABEL() ; 1
$$LABEL(2) ; 2
$$LABEL(3,8) ; 3
Здесь в первом случае не передаётся фактический параметр и переменная v принимает неопределённое значение, которой автоматически
присваивается значение 123.
Во втором случае переменной v присваивается значение 2 и значение,
указанное как значение по умолчанию, игнорируется. В третьем случае
переменной v значение сопоставляется, но для второго параметра метка
ничего не принимает, поэтому MUMPS система в этом случае генерирует ошибку.
Для того, чтобы метка могла принять неопределённое количество
параметров, её последний формальный параметр специфицируется тремя
точками:
LABEL(p1,params...)
В этом случае, при сопоставлении фактических параметров формальным, игнорируется передача локальных переменных по ссылке и принимаются только значения. Значение переменной, указанной тремя точками (в примере params), принимает значение количества принятых фактических параметров, начиная с этой позиции. Принимаемые значения
записываются в индексы переменной (в примере это params), начиная
с индекса 1 и так далее в порядке следования. Если, начиная с этой
позиции, не было фактических параметров, то формальная переменная
принимает неопределённое значение. Если были пропуски фактических
параметров, то соответствующие узлы формальной переменной не создаются и имеют неопределённое значение.
Например, пусть есть подпрограмма:
LABEL(params...)
zw params
q params
Тогда при её вызове получаем:

1.11. НЕОПРЕДЕЛЕННЫЕ ЗНАЧЕНИЯ 135
USER>w $$LABEL^test(1)
params=1
params(1)=1
1
USER>w $$LABEL^test(1,2)
params=2
params(1)=1
params(2)=2
2
USER>w $$LABEL^test("we",2)
params=2
params(1)="we"
params(2)=2
2
USER>w $$LABEL^test(,2)
params=2
params(2)=2
2
Разработчикам, конечно, следует учитывать, что автоматическое присваивание значений и приём неопределённого количества параметров не
входят с стандарт языка MUMPS, что их использование может создать
препятствие при переносе программ на другую MUMPS систему.
Для всех методов передачи параметров их правила применимы к передаче параметров подпрограмме, когда вызываемый код создает контекст,
принадлежащий тому же самому процессу. В случае если параметры передаются новому процессу, вызовом команды JOB, то передать можно
лишь параметры по значению. При попытке передать параметр по ссылке
команда JOB генерирует ошибку. Передаваемые значения MUMPS системой передаются специальным внутренним образом новому процессу.
1.11 Неопределенные значения
В языке MUMPS локальная или глобальная переменная может иметь
или не иметь присвоенное значение. Если значение не было присвоено,
то такая переменная не хранится и имеет неопределенное значение. При
попытке чтения ее значения процесс генерирует ошибку о неопределенном значении.
В других языках для использования переменной требуется ее объявить. В этом случае под переменную отводится определенная память.
До явного ей присваивания или выполнения кода инициализации объекта значение переменной по умолчанию может быть либо произвольным
(мусор в памяти), либо проинициализировано заранее нулевыми значе-

136 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
ниями или указанной константой. В этом случае поведение определяется настройками соответствующего транслятора и среды исполнения или
соглашениями используемого языка. В частности, отдельные компиляторы при трансляции отладочных версий инициализируют переменные,
не инициализированные явно, нулевыми байтами, но при трансляции
релизных версий уже этот код не вставляется и переменная содержит
мусор.
В языке MUMPS в переменной не может быть произвольного значения, поскольку до использования переменная не существует и не хранится. Обращение к переменным производится по именам и по этому имени
исполняющая система определяет есть ли такая переменная и какое у
нее значение. При этом до присваивания переменной не существует, и
переменные создаются при первом им присваивании.
Во многих случаях разработчикам необходимо определять, существует ли переменная или нет и зачастую считать, что переменная имеет
значение по умолчанию. Для этого в языке есть несколько функций,
которые оперируют как определенными, так и неопределенными переменными. К ним относятся:
1. $DATA - возвращает индикатор, имеет ли переменная и ее дочерние переменные значения.
2. $GET - возвращает для переменной ее значение, или если она имеет неопределенное значение то возвращает значение по умолчанию.
3. $INCREMENT - может увеличить на указанную величину неопределенную переменную, автоматически создав ее.
4. $LISTBUILD - может использовать неопределенную переменную
для конструирования элемента списка, создав элемент имеющий
неопределенное значение.
5. $BITLOGIC - расширенная функция, может использовать неопределенные переменные, считая их эквивалентом последовательности
битовых нулей.
Функция $DATA возвращает индикатор существует ли указанная переменная и существуют ли ее дочерние переменные, хотя бы одна. Функция является основной для проверки переменной на неопределенность.
Функция возвращает одновременно два индикатора в виде двух десятичных знаков, старший для дочерних и младший для самой переменной.
Их можно выделить арифметическими операциями явно.

1.11. НЕОПРЕДЕЛЕННЫЕ ЗНАЧЕНИЯ 137
Проверка на то, что имя существует, независимо от существования
дочерних:
$DATA(varname)#2
и проверка существования дочерних, независимо от существования самой переменной:
$DATA(varname)\10
Функция $GET принимает имя переменной и возвращает ее значение, если переменная была определена. Если переменная не была определена, то функция возвращает пустую строку или указанное значение
по умолчанию. Это поведение функции $GET определено стандартом
и им пользуются разработчики, если необходимо использовать значение по умолчанию для переменной, если ее значение может оказаться
неопределенным и это не является ошибкой.
Что интересно, существовала такая реализация MUMPS системы
(StarMUMPS), в которой любая неопределенная локальная переменная
имела значение пустая строка и к любой из них можно было обратиться на чтение, не получив ошибку о неопределенном значении. Можно
сказать, что создание такой отдельной реализации MUMPS системы
действительно могло быть оправдано если необходимо было выполнять
приложения, трактующие неопределенное значение именно как пустую
строку. Хотя, со стороны интерпретатора, значение пустая строка ничем
особым не отличается от любого другого значения.
Аналогичное реликтовое поведение в угоду прикладным системам до
сих пор встречается и в СУБД отличных от MUMPS, в частности в SQL
системе Oracle не выполняется различение между данными равными
пустой строке и зарезервированным значением языка NULL. Вероятно,
когда-то давно это решение съэкономило время при разработке какойто из прикладных систем, и в настоящее время этот рудимент в целях
совместимости до сих пор поддерживается, хотя большинство других
SQL систем не содержат такой ошибки.
В современных MUMPS системах отношение к неопределенным значениям строгое и четко регламентируется стандартом, либо строго описано для расширенных функций. В тех случаях когда MUMPS система
поддерживает опциональную настройку на нестандартное поведение в
отношении неопределенных значений и пустых строк, тем не менее настройки по умолчанию всегда соответствуют стандартному поведению.
Функция $INCREMENT может увеличить на указанное значение
(по умолчанию на 1) в том числе и неопределенную переменную. В этом

138 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
случае функция считает, что переменная имела значение, эквивалентное
0.
Функция $LISTBUILD (расширенная, не входящая в стандарт) мо-
жет принимать в качестве параметра имя неопределенной переменной, в
этом случае функция конструирует элемент списка в соответствующей
позиции, имеющий неопределенное значение в смысле элемента списка.
В какой-то степени эта функция также может быть использована, таким
образом, как альтернатива функции $DATA.
Функция $BITLOGIC может оперировать именами неопределенных
переменных, в этом случае она считает что переменная эквивалентна
битовой строке нулевой длины и при логических операциях условно дополняет ее нулями до длины, необходимой для операции с другой переменной. В частности, битовая операция ИЛИ с неопределенной переменной возвращает исходное значение.
Такое определение функции $BITLOGIC очень практично для выпол-
нения массовых битовых операций над строками битовых индексов, поскольку отпадает необходимость использовать дополнительный код проверки определено ли значение битовой строки в индексе.
Что интересно, в языке MUMPS неопределенные значения можно не
только проверять и использовать, но также передавать как параметры
пользовательским функциям. Причем, таких способов даже два:
1. Передать по ссылке неопределенную локальную переменную.
2. Опустить фактический параметр чтобы формальный параметр принял неопределенное значение.
Если мы передает по ссылке локальную переменную, имеющую неопре-
деленное значение, например:
kill accum
set result=$$calc(.accum)
...
calc(acc)
...
q ret
то при сопоставлении фактического параметра формальному производится конструирование локальной переменной (в данном случае acc) в
виде синонима другой переменной, на другом уровне (в данном случае
accum). Если исходная переменная имела неопределенное значение, то
и формальный параметр будет иметь также неопределенное значение.

1.12. ШАБЛОНЫ 139
Второй способ - это опускание соответствующего фактического параметра вместо указания ссылки на переменную или вычисляемого значения:
set result=$$calc()
...
calc(acc)
...
q ret
В этом случае фактическому параметру также будет сопоставлено
неопределенное значение.
При этом, в языке MUMPS нельзя вычислить значение, имеющее
неопределенное значение, поскольку неопределенные значения могут иметь
только переменные, если они не были присвоены. Но можно сделать так,
чтобы переменная получила неопределенное значение, для этого ее необходимо удалить:
s var="string"
; переменная var имеет значение
kill var
; переменная var не имеет значения
либо применить команду new, побочно присваивающую переменной неопределенное значение, но только начиная с текущего уровня стека:
s var="string"
; переменная var имеет значение
new var
; переменная var не имеет значения
1.12 Шаблоны
Шаблонами (pattern) в языке MUMPS называются правила, описывающие символы, входящие в строку, для проверки соответствует или нет
строка такой последовательности.
Синтаксически оператор проверки по шаблону записывается так:
expr?pattern
Оператор возвращает значение 1 если строка соответствует шаблону
и 0 если нет, причем к оператору можно применить отрицание оператора:
expr’?pattern

140 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
что эквивалентно отрицанию логического значения результата
’(expr?pattern)
С точки зрения синтаксиса, последовательность, описывающая шаблон оценивается транслятором MUMPS на этапе трансляции. При этом
те же самые действия могут быть выполнены косвенно, если шаблон
задать в виде значения вычисляемого выражения и использовать косвенность шаблонов:
s pattern=...
expr?@pattern
В этом случае оценивать шаблон MUMPS система будет на этапе
выполнения кода.
Структурно шаблон представляет собой последовательность из одного
или нескольких следующих подряд правил. Каждое из правил называется атомарным шаблоном. Каждый из атомарных шаблонов состоит из
указания числа повторов и одной из конструкций, что именно должно
повторяться:
1. Код обозначающий принадлежность символа к группе символов.
2. Строка задающая последовательность символов явно.
3. Альтернатива, задающая перечисление атомарных шаблонов и означающая операцию ИЛИ.
Рассмотрим каждое из этих определений более подробно.
Для указания числа повторов можно указывать один из следующих
вариантов в виде комбинации из чисел:
count Точно указанное воличество.
. Любое количество, включая ноль по-
второв.
min . Минимум min раз, максимум не
ограничен.
. max Максимум max раз, начиная с нуля.
min . max От min до max раз включительно.
Задание кода или класса символов производится указанием символа,
соответствующего классу символов:
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
