Добавил:
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.5. ФУНКЦИИ 81
речисляет по возрастанию, а если равно -1, то по убыванию индексов в
порядке их сортировки.
USER>s a(1)=1,a(2,2)=22,a(3,3,3)=333,a(4)=4
USER>s name=$na(a(1000000))
USER>f s name=$q(@name,-1) q:name="" w name,!
a(4)
a(3,3,3)
a(2,2)
a(1)
Здесь в примере использовалось то, что в данных применялись числовые индексы. В реальности, при использовании строковых значений,
необходимо в качестве начального значения итератора применить некое
значение заведомо большее чем любое существующее, например
USER>s name=$na(a($c(255,255,255,255,255,255)))
Либо использовать начальное значение в виде имени с одним индексом пустая строка:
USER>s a(1)=1,a(2,2)=22,a(3,3,3)=333,a(4)=4
USER>s name=$na(a(""))
USER>f s name=$q(@name,-1) q:name="" w name,!
a(4)
a(3,3,3)
a(2,2)
a(1)
Обе функции, и $ORDER, и $QUERY, воспринимают пустую строку
в качестве индекса при перечислении назад как индикатор необходимости найти самое старшее значение и вернуть его.
Функция $QUERY традиционно используется совместно с функциями $NAME, $QLENGTH и $QSUBSCRIPT и с применением операции косвенности имени. В случае если необходимо остановить итерацию ранее чем закончится переменная, или не использовать переменные
с ненужным числом аргументов, применяется определение значений отдельных частей имени переменной, в частности:
USER>s a(1)=1,a(2,2)=22,a(3,3,3)=333,a(4)=4
USER>s name=$na(a)

82 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
USER>f s name=$q(@name) q:name="" w name," : ",$ql(name),!
a(1) : 1
a(2,2) : 2
a(3,3,3) : 3
a(4) : 1
Функция $QUERY, также как и функция $ORDER, может применяться как к локальным, так и к глобальным переменным. Причем функция $QUERY поддерживает в отношении глобальных переменных соглашение об имени базы данных:
1. Если аргумент не использует явное задание имени базы данных,
то результат возвращается также без имени базы данных.
2. Если аргумент явно содержит имя базы данных, то возвращаемый
результат также содержит имя базы данных, даже если эта база
данных является текущей.
К дополнительным расширениям, которые могут поддерживаться отдельными реализациями MUMPS систем, относится возможность использовать функцию $QUERY для структурных системных переменных.
В настоящее время этот функционал относится к нестандартному. Существуют MUMPS системы, которые не позволяют использовать $QUERY
в отношении структурных системных переменных, есть которые позволяют в отношении некоторых из них. В любом случае разработчик, применяя функцию $QUERY к структурной системной переменной, должен
проверить в документации на используемую MUMPS систему, как она
поддерживает такую операцию.
Если используемая MUMPS система поддерживает применение функции $QUERY к структурной системной переменной, то такими переменными можно оперировать как обычными:
USER>s name=$na(^$J(""))
USER>f s name=$q(@name) q:name="" w name," : ",$ql(name),!
^$JOB("5960") : 1
^$JOB("7076") : 1
Функция $QUERY появилась в языке в стандарте 1990-го года, и,
формально говоря, в стандарт входит лишь одноаргументная форма этой
функции. Двухаргументная форма функции $QUERY входит в рекомендации комитета по стандартизации языка (MDC), но, в действительности, поддерживается всеми современными реализациями MUMPS систем. Функции $NAME, $QLENGTH и $QSUBSCRIPT входят в стандарт с 1995-го года.

1.5. ФУНКЦИИ 83
Функции имен оперируют именами переменных и выполняют операцию обратную к операции косвенности имени. Частично их применение
было показано при использовании функции $QUERY. К таким относятся
функции:
1. $NAME - возвращает строку с именем переменной для указанной
переменной.
2. $QLENGTH - возвращает число индексов у переменной заданной
именем.
3. $QSUBSCRIPT - возвращает часть имени переменной заданной
именем.
Функции имен оперируют так называемым каноническим представлением имен переменных. При преобразовании имя - строка или наоборот, строка - имя MUMPS система пользуется едиными соглашениями о
представлении имен и значений индексов. Если в системе принято кодировать числовой индекс как число а не как строку, то при канонизации
имени такое значение будет представляться именно как число, например:
USER>w $na(a(123))
a(123)
USER>w $na(a("123"))
a(123)
1.5.6 $NAME
Функция $NAME ($NA) конструирует строковое значение имени для
заданной переменной. Что интересно, имя функции сокращается не до
$N а до $NA, поскольку изначально до буквы $N сокращалась функция
$NEXT. Хотя функция $NEXT в настоящее время не применяется и
рекомендована к замене на функцию $ORDER, в целях совместимости
сокращение имени $NAME до имени $NA осталось.
Функция $NAME принимает в качестве аргумента собственно имя
переменной, локальной или глобальной, и возвращает строку с этим
именем, представленное в канонической форме.
Что интересно, для функции $NAME не требуется существование
самой этой переменной, она оперирует только ее именем. Причем само
имя может быть использовано как явно, так и косвенно, например:
USER>w $na(abc)
abc

84 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
USER>w $na(abc(123,456))
abc(123,456)
USER>w $na(abc("ss","day"))
abc("ss","day")
USER>s name=$na(abc(1,2))
USER>w $na(@name)
abc(1,2)
USER>w $na(@name@(3))
abc(1,2,3)
В случае использования глобального имени функция $NAME, также
как и функция $QUERY, возвращает результат с именем базы данных
если имя базы было указано в аргументе и наоборот, если имя базы
данных не было указано, то результат также его не содержит.
USER>w $na(^GBL(3,3,3))
^GBL(3,3,3)
USER>w $na(^|"any"|GBL(3,3,3))
^|"any"|GBL(3,3,3)
Точно также, как и сама переменная, база данных не обязана существовать, функция $NAME оперирует лишь именем переменной, не
обращаясь к реальным данным.
У функции $NAME определены две формы - одноарументная и двухаргументная. Для двухаргументной формы второй аргумент вычисляется
как целое число и функция возвращает только часть имени из первого
аргумента так, что число индексов в возвращаемом результате ограничено значением второго аргумента. В случае если в исходном имени
недостаточно индексов, то возвращается столько, сколько их имеется:
USER>w $na(a(1,2,3,4,5),2)
a(1,2)
USER>w $na(a(1,2,3,4,5),8)
a(1,2,3,4,5)
Двухаргументная форма $NAME, судя по статистике применения,
используется чрезвычайно редко. Но в тех задачах, когда надо получить
только часть имени переменной, она подходит наилучшим образом.
Традиционным применением функции $NAME является ее парное
применение к операциям косвенности имени, когда программный код
оперирует обобщенными именами, при использовании функции $QUERY,
и при конструировании более длинного имени путем добавления индексов или более короткого путем отсечения части имени.

1.5. ФУНКЦИИ 85
Отдельные реализации MUMPS систем могут использовать имена
структурных системных переменных в качестве аргумента функции $NAME. Этот функционал относится к нестандартному и при необходимости его использования следует обратиться к документации на применяемую MUMPS систему. В частности, если функция $NAME поддерживает такой функционал, то может конструировать имена:
USER>w $na(^$J(12,34,56))
^$J(12,34,56)
В этом случае необходимо понимать, что к реальной структурной системной переменной функция $NAME не обращается и имя, сконструированное в результате, может не соответствовать реально существующему значению либо каким-либо соглашениям и правилам для значений
в этой структурной системной переменной.
При первоначальном знакомстве с системами программирования основанными на языке MUMPS новички могут путаться, где используется
само имя, а где используется строка с именем переменной. Хорошим вариантом решения проблемы может быть обучение или дополнительное
комментирование кода.
1.5.7 $QLENGTH
Функция $QLENGTH ($QL) возвращает число индексов у переменной
заданной строкой с именем.
USER>s name=$na(a(1,2,3,4))
USER>w $ql(name)
4
USER>s name=$na(a(1,2,3,4,5,6))
USER>w $ql(name)
6
USER>s name=$na(a)
USER>w $ql(name)
0
Функция $QLENGTH не включает в результат само имя переменной
и имя базы данных, если оно указывается.
Функция может быть применена к именам локальных, глобальных
и в зависимости от версии MUMPS системы, к именам структурных
системных переменных.

86 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
1.5.8 $QSUBSCRIPT
Функция $QSUBSCRIPT ($QS) возвращает часть имени. Первый аргумент функции это строка с именем переменной, второй аргумент - номер
индекса. Если значение второго аргумента равно 1, то возвращается первый индекс, если 2 - второй, и так далее. Для несуществующих в имени
индексов возвращается пустая строка.
USER>s name=$na(^|"any"|GBL(1,2,3,4))
USER>w $qs(name,1)
1
USER>w $qs(name,2)
2
USER>w $qs(name,3)
3
USER>w $qs(name,4)
4
USER>w $qs(name,5)
USER>
Функция $QSUBSCRIPT поддерживает дополнительно два специально зарезервированных значения для второго аргумента - если оно
равно 0, то возвращается строка с корневым именем, а если -1 - то
строка с именем базы данных, если оно было указано:
USER>s name=$na(^|"any"|GBL(1,2,3,4))
USER>w $qs(name,0)
^GBL
USER>w $qs(name,-1)
any
Все остальные отрицательные значения зарезервированы и при их
использовании в настоящее время должна генерироваться ошибка.
Функции $NAME, $QLENGTH и $QSUBSCRIPT в описанном виде входят в текущий стандарт языка MUMPS и могут быть свободно
использованы в целях переносимости программ.
В рекомендации комитета MDC дополнительно входит поддержка
левостороннего присваивания для функции $QSUBSCRIPT, но такой
функционал поддерживается не всеми реализациями. В частности, MiniM
Database Server поддерживает такой функционал:
USER>s name=$na(a("aa","bb","cc"))

1.5. ФУНКЦИИ 87
USER>w name
a("aa","bb","cc")
USER>s $qs(name,2)="dd"
USER>w name
a("aa","dd","cc")
USER>s $qs(name,0)="newname"
USER>w name
newname("aa","dd","cc")
Функция $QSUBSCRIPT с левым присваиванием использует в качестве первого аргумента переменную, в которой должно быть имя переменной. При присваивании это значение изменяется таким образом, что
в содержащемся имени замещается соответствующий фрагмент. В случае если в исходном имени недостаточно индексов, функция дополняет
имя индексами с пустыми строками:
USER>s $qs(name,6)="ff"
USER>w name
a("aa","dd","cc","","","ff")
Аналогичный к левосторонней функции $QSUBSCRIPT функционал
можно получить, комбинируя косвенность имени и функцию $NAME, и
выполняя в цикле итерации для каждого из значений индексов.
Строковые функции манипулируют строковыми значениями безотносительно того, хранятся они в базе данных или нет. Функции рассматривают строки как последовательность байт. В строке, согласно стандарту
языка MUMPS, могут содержаться произвольные символы, включая нулевой байт.
К строковым функциям относятся функции:
1. $ASCII - возвращает код символа в указанной позиции.
2. $CHAR - конструирует строку на основе заданных кодов символов.
3. $EXTRACT - возвращает подстроку.
4. $PIECE - возвращает фрагмент строки рассматривая ее как строку
с разделителями.
5. $LENGTH - возвращает число символов в строке.
6. $REVERSE - возвращает строку с обратным порядком символов.

88 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
7. $FIND - возвращает позицию подстроки в строке.
8. $TRANSLATE - выполняет замену символов.
9. $JUSTIFY - выполняет дополнение строки.
10. $FNUMBER - форматирует число по заданному формату.
Некоторые из аргументов строковые функции воспринимают как строки, некоторые строго как числа. В отличие от других языков, в MUMPS
любое значение может быть использовано в обоих контекстах. В частности, строковые функции могут вычислить длину числа
USER>w $length(456)
3
или переставить в числе знаки
USER>w $reverse(456)
654
При этом любой из параметров строковыми функциями используется
как выражение, которое предварительно вычисляется перед использованием. Использование в примерах констант - это частный случай использования выражений. Например
USER>w $length(4_5_6)
3
USER>w $length(4+5+6)
2
1.5.9 $ASCII
Функция $ASCII ($A) возвращает код символа из строки в указанной
позиции. Строка рассматривается как последовательность байт, и один
байт рассматривается в зависимости от реализации как 7-ми битный
или 8-ми битный. Современные реализации MUMPS систем оперируют
8-ми битными байтами и рассматривают коды символов старше 127 как
беззнаковое число от 0 до 255 включительно.
Это отношение к строке по умолчанию, поддерживаемое большинством систем. При этом в связи с расширением поддержки кодирований
UTF и юникода отдельные MUMPS системы могут возвращать код не до
255 включительно, а все старшие и позиция в строке отсчитывается не в

1.5. ФУНКЦИИ 89
байтах во внутреннем представлении, а в виде позиции символа в зависимости от использованного кодирования (UTF отводит под различные
символы различное число байт для их представления). В любом случае,
если система применяет юникод, его поддержка внешне, для разработчиков, приводится к таким же стандартным соглашениям.
Кроме того, современные реализации MUMPS придерживаются соглашений об ASCII кодировании символов, когда часть кодовой таблицы
от 0 до 127 отводится под стандартную (латиница), а дополнительная
часть (от 128 до 255) отводится под национальные символы. В стандарте
для них используется также отдельное название - графические символы. Для них уже нет четко определенного представления и для представления символов каждая из реализаций использует дополнительное
соглашение о кодировании и кодировках символов.
Для функции $ASCII определены две формы - одноаргументная и
двухаргументная. Основной формой является двухаргументная. При этом
первый аргумент - строка в которой надо определить код символа, второй - позиция символа в строке. Отсчет символов ведется от единицы.
Например:
USER>w $a("123",1)
49
USER>w $a("123",2)
50
USER>w $a("123",3)
51
В случае если для указанной позиции в строке нет символа, функция
$ASCII возвращает значение -1. Это значение определено стандартом и
может быть использовано в арифметических операциях.
Если второй параметр функции опущен, то функция возвращает код
первого символа, или, другими словами, использует значение параметра
по умолчанию равное 1:
USER>w $a("123",1)
49
USER>w $a("123")
49
Функция $ASCII не использует никаких соглашений о строении строки, ее формате, кодировке, и рассматривает строку исключительно как
просто последовательность байт, вне зависимости от того, каким образом строка была сформирована. Для систем поддерживающих юникод,
строка рассматривается как последовательность символов.

90 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
Большинство современных реализация MUMPS систем поддерживают расширенные варианты функции $ASCII - в зависимости от версии это обычно $ZWASCII ($ZWA), $ZLASCII ($ZLA) и $ZQASCII
($ZQA). Они оперируют не одним байтом, а соответствено словом (2
байта), двойным словом (4 байта) и четверным словом (8 байт). Вся последовательность байт для них разбивается на последовательность слов
соответствующей длины. Так, если есть строка "abcdefghijk", то такие
функции дают результат:
USER>s str="abcdefghijk"
USER>w $a(str,1)
97
USER>w $a(str,2)
98
USER>w $zwa(str,1)
25185
USER>w $zwa(str,2)
25442
USER>w $zla(str,1)
1684234849
USER>w $zla(str,2)
1701077858
USER>w $zqa(str,1)
7523094288207667809
USER>w $zqa(str,2)
7595434461045744482
В случае если в строке недостаточно байт для указанной группы, то
функции возвращают значение -1:
USER>w $zwa("1",1)
-1
USER>w $zqa(str,8)
-1
Расширенные варианты функций $ZWA, $ZLA и $ZQA очень практичны в задачах кодирования последовательностей чисел в строку и обратно для различных протоколов передачи данных, но нужно понимать,
что они не входят в стандарт и могут не поддерживаться на выбранной реализации MUMPS системы, либо могут иметь иной результат для
неопределенного значения (возвращать вместо -1 иное значение). Также
нужно отметить, что позиция в строке для отсчета слова указывается не
в словах, а в байтах.
При необходимости можно заменить эти функции при портировании
программ на комбинацию стандартной функции $ASCII и арифметических операций:
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
