Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MUMPS СУБД. Практика применения и опыт программирования.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
7.3. ЭКСПОРТ И ИМПОРТ 461
рутин в виде файлов и согласуют файлы через систему контроля версий самостоятельно.
3. Разработчики работают в различных базах данных и используют специальные средства сопряжения рутин и файлов с системами контроля версий.
Одним из очень практичных свойств MUMPS систем является то, что рутины могут быть изменены и компилированы независимо друг от друга, в том числе в эксплуатирующейся базе данных. При этом при­ложение, их не использующее во время редактирования и компиляции, продолжает корректно работать. Из-за того, что рутины используются только по необходимости, возможна работа с огромными объемами про­граммного кода, и, одновременно с тем, отсутствуют сложные процедуры сборки приложения в один исполняемый файл.
MUMPS системы, хотя это и не определено стандартом явно, поддер­живают выполнение рутин в режиме позднего связывания. В этом ре­жиме выполнения кода переход к нужной строке выполняется как есть, и проверка существования вызываемой строки проверяется только при исполнении. При трансляции программ и исполняемых строк существо­вание вызываемых строк или их корректность не требуются. Их можно написать, импортировать или отредактировать позже, чем редактирова­ние и компиляцию вызывающего кода. В системах исполнения позднего связывания не используется линкер или построитель связей.
При разработке большой системы группа разработки выбирает од­ну из моделей разработки и далее ей следует. В большинстве случаев используется редактирование рутин в отладочных базах данных (в об­щей или индивидуальной), перенос рутин в тестовую базу для проверки (также может быть общей или индивидуальной) и передача готового комплекта рутин в рабочую базу. При необходимости вместе с исход­ными текстами рутин могут передаваться файлы экспорта глобалов и инструкции по выполнению кода настройки после импорта рутин.
В качестве средств контроля версий обычно используются традици­онные файловые средства и разработчики выполняют синхронизацию системы контроля версий с нужным каталогом и выполняют импорт и экспорт рутин в этот каталог.

7.3 Экспорт и импорт

Экспорт и импорт рутин и данных для MUMPS систем являются основ­ным средством переноса рутин и данных между различными серверами.
462 ГЛАВА 7. ПРАКТИКА ПРИМЕНЕНИЯ
Одним из ключевых отличий MUMPS систем от других систем баз данных является то, что стандарты применения MUMPS систем преду­сматривают стандартные форматы переноса рутин и данных, и они под­держиваются практически всеми реализациями MUMPS систем. Кро­ме стандартных форматов MUMPS реализации зачастую поддерживают дополнительные собственные расширенные форматы файлов экспорта и импорта.
Для рутин есть, по сути, один стандартный формат экспорта, с ва­риациями на усмотрение реализаций. Файл экспорта рутин состоит из последовательности следующих элементов:
1. Заголовок экспорта.
2. Последовательность рутин.
3. Пустая строка как индикатор окончания экспорта.
Последовательность рутин хранится как простая последовательность следующих строк:
1. Строка с именем рутины.
2. Последовательность строк рутины как есть.
3. Пустая строка как индикатор окончания рутины.
Для того, чтобы отличить пустую строку рутины и индикатор окон­чания, при экспорте пустой строки рутины экспортируется строка из од­ного пробела или одной табуляции. Поэтому, если в рутине разработчик поставил пустую строку, экспортировал рутину, потом импортировал, то эта пустая строка будет заменена на строку из пробельной последова­тельности.
Вторым нюансом, в котором различные реализации MUMPS систем могут проявить особенности, является заголовок экспорта. Это две тек­стовые строки, в которых программа экспорта пишет служебную инфор­мацию о проведенном экспорте. Очередность и формат этого заголовка не фиксированы, и различные MUMPS системы могут писать заголов­ки с различном порядке. В любом случае, для импорта рутин эти обе строки заголовка используются лишь в информационных целях.
Третьим нюансом является возможность размещения в первых двух строках заголовка автоимпорта. Это последовательность команд MUMPS,
7.3. ЭКСПОРТ И ИМПОРТ 463
выполняющих импорт оставшейся части файла импорта. Заголовок ав­тоимпорта является специфическим для каждой из MUMPS систем, по­скольку используется информация о деталях хранения рутин, а в каж­дой из MUMPS систем они могут отличаться, кроме того в каждой из MUMPS систем используются различные способы компиляции рутин. Заголовок автоимпорта используется для передачи файла с экспорти­рованными рутинами MUMPS системе как последовательности команд для исполнения, например:
mumps.exe < routines.rtn
При этом процесс считывает команды для выполнения из переданно­го файла. Эти команды уже самостоятельно продолжают последующее чтение и выполняют импорт. Реальное имя исполняемого файла и необ­ходимые дополнительные опции командной строки нужно определить по документации на используемую MUMPS систему или обратиться в ее техническую поддержку.
Вариант заголовка автоимпорта, используемый системой Cach´e:
N IO,D,P,I,A,X,L S IO=$I R D U 0 W !,D,! S P="^" >>
F U IO R A Q:A="" I $P(A,P,3) S L=$P(A,P,5) >> S:L X=$ZU(55,L) ZL ZS @$P(A,P) S:L X=$ZU(55,0) >>
U 0 W !,$P(A,P,1,2),?20," loaded" ;(Self-loading) %RO on 05 Oct 2012 2:27 PM ETRAP^INT^1^62735,51942^0^1 ETRAP ; etrap examples
q ...
Здесь символами » обозначено продолжение одной строки. При вы­полнении такого файла экспорта система Cach´e выполняет команды им­порта рутин из того же самого файла.
Вариант заголовка автоимпорта, используемый системой MiniM:
n h,r,l r h f r r q:r="" s h=$p(r,"^",4) >>
s h=$s(h:h,1:$h) s r=$p(r,"^") f r l >> i l="" q:l="" >>
s ^ROUTINE(r,$i(^ROUTINE(r)))=l s ^ROUTINE(r,0)=h 14:31 5-окт-2012 MiniM Routine Editor export ETRAP ETRAP ; etrap examples
q ...
464 ГЛАВА 7. ПРАКТИКА ПРИМЕНЕНИЯ
Здесь символами » также обозначено продолжение одной строки. При выполнении такого файла экспорта система MiniM выполняет команды импорта рутин из того же самого файла.
Вариант заголовка автоимпорта, используемый системой MUMPSV1:
S %I=$I R B X B U 0 C %I D ^%C K ^$R("%C") >>
W !,"Done",! Q
F R R Q:R="" U 0 W R,! U %I K A F I=1:1 >>
R A(I) I A(I)="" M ^$R(R)=A Q ETRAP ETRAP ; etrap examples
q ...
Здесь символами » также обозначено продолжение одной строки. При выполнении такого файла экспорта система MUMPSV1 выполняет ко­манды импорта рутин из того же самого файла.
В принципе, эта же методика может быть использована для размеще­ния в этом же файле не только рутин, но и глобалов, и иных выполняе­мых действий. В частности, после того, как процесс MUMPS выполнит команды, он продолжит считывание входных команд. Если далее снова встретит команды для выполнения, то снова их будет выполнять. Таким образом, можно в одном файле переносить множество различных фраг­ментов. При размещении в одном файле экспорта лишь одной последо­вательности рутин с одним заголовком автоимпорта после выполнения команд процесс MUMPS считает в качестве дальнейших команд пустую строку, поэтому закончит работу.
Заголовок автоимпорта традиционно составляется так, чтобы зани­мать только первые две строки для того, чтобы рутины могли быть импортированы традиционными средствами. В этом случае в качестве служебных данных экспорта системы считают и покажут последователь­ности команд, но на содержание импортируемых рутин это не оказывает никакого влияния. В том случае, если разработчики используют ме­ханизм автоимпорта для собственных целей, не предназначенных для стандартных средств импорта рутин или глобалов, то могут быть ис­пользованы произвольное число строк в начале файла и произвольные операции.
У механизма автоимпорта есть еще один нюанс, касающийся ошибок импорта. При передаче команд исполнения через стандартный вход ко­манды выполняются в контексте текущего устройства с разделенными каналами входа и выхода (stdin + stdout), поэтому, если при импорте или компиляции импортированной рутины произойдет ошибка и будет производиться вывод диагностики в текущее устройство, то вывод будет
7.3. ЭКСПОРТ И ИМПОРТ 465
направлен в канал вывода, а не в канал ввода, и файл экспорта не будет поврежден операциями записи. Ошибки при импорте могут произойти даже при записи очередной строки рутины, например, при недостатке места в базе данных. Большинство современных MUMPS систем при­нимают меры к тому, чтобы при импорте не допускать порчи исходного файла диагностическими сообщениями об ошибках в случае их происхо­ждения, не утрачивать диагностические сообщения и продолжать импорт до его полного окончания с получением полного отчета.
Имена файлов с экспортированными рутинами могут иметь любое расширение файла, зачастую разработчики используют один из несколь­ких: R, ROU, RTN, M, RSA (Routine Save Archive) или другие, читаемые как "это файл, содержащий рутины".
Распространенной ошибкой является использование форматов экс­порта рутин для хранения в репозиториях систем контроля версий. При­чин две:
1. Формат экспорта содержит не одну целостную сущность редакти­рования, а несколько.
2. Формат экспорта содержит дополнительную информацию, не вхо­дящую в сущность, редактируемую разработчиками.
Первая причина приводит к тому, что в файле могут оказаться не одна сущность редактирования, а несколько, и их состав, вообще говоря, может быть произвольным и определяется каждый раз при экспорте. Кроме того, порядок экспорта рутин, а значит и построчное содержание такого файла экспорта, в общем случае, не детерминированы, поскольку средства экспорта не гарантируют порядок следования экспортируемых сущностей. В большинстве случаев они следуют в лексикографической сортировке имен сущностей, но это не гарантируется.
Вторая причина приводит к тому, что утилита экспорта автоматиче­ски формирует первые две строки с добавлением служебной информа­ции, и в нее могут входить дата, время, версия, название программы экспорта, и другие данные, отличающиеся как на разных серверах, так и в разное время экспорта.
Обе проблемы приводят к тому, что для систем контроля версий такие файлы вызывают проблемы коллизий изменений строк, не относящиеся к разработке.
Для задачи сопряжения с системами контроля версия наиболее под­ходит формат хранения рутин в файлах, используемый в системе GT.M. Он решает обе проблемы. Система хранит рутины в виде файлов файло­вой системы как есть. В одном файле хранится одна рутина, и в файле
466 ГЛАВА 7. ПРАКТИКА ПРИМЕНЕНИЯ
не хранится никакая другая автоматически добавляемая информация, которую не редактирует разработчик.
У этого формата имеется лишь один недостаток - имя рутины сов­падает с именем файла. При использовании файловых систем, не раз­личающих регистр символов в именах файлов (например, в Windows), это приводит к невозможности хранить две рутины, отличающиеся в имени регистром символов, и к неопределенности регистра символа для импорта. При преодолении проблемы регистра, например, при соглаше­нии использовать лишь верхний, или при специальном декорировании имен, такой формат, тем не менее, наиболее удобен для систем контроля версий по содержанию файлов.
MUMPS системы, поддерживающие препроцессор, также дополни­тельно различают типы рутин - непосредственный код MUMPS языка, получаемый после препроцессирования, макрокод рутин с директивами препроцессора, и включаемые рутины с макрокодом. При необходимо­сти экспортировать рутины с разным типом применяется формат RSA, в котором в качестве имени рутины хранится не только имя, но так­же дополнительно расширение, указывающее на тип рутины, и другая дополнительная информация, например время последней модификации этой рутины. Таким образом, макрорутины не могут быть перенесены в MUMPS систему, не поддерживающую препроцессор и такой специаль­ный формат экспорта с сохранением типа рутины.
Данные глобалов, так же как и рутины, экспортируются и импорти­руются через стандартные форматы файлов. Данные могут быть перене­сены между различными MUMPS системами, разных версий, работаю­щими на разных операционных системах и от разных производителей.
Принцип организации форматов экспорта глобалов тот же, что и для рутин. В файле записывается заголовок экспорта, и перечисляются име­на глобалов и их значения.
Так же как для файлов экспорта рутин, для файлов экспорта глобалов могут быть применены заголовки автоимпорта и такие файлы могут быть использованы в пакетных операциях.
В отличие от рутин, глобалы могут содержать произвольные символы, в том числе символы используемые текстовыми файлами как символы окончания строки. Поэтому для глобалов различают два формата экс­порта - потоковый и переменной длины.
Потоковый формат представляет собой простой текстовый формат, как последовательность пар строк - первая из них содержит полное имя глобала с индексами, вторая полное значение. Поскольку потоко­вый формат рассматривается как текстовый, его нельзя использовать для переноса тех данных, в индексах или в значениях которых могут
7.3. ЭКСПОРТ И ИМПОРТ 467
быть нетекстовые байты.
Формат переменной длины для кодирования пар имя - значение ис­пользует для каждой записи специальный маркер длины. В этом случае и индексы и данные глобалов могут содержать произвольные байты, по­скольку количество байт для использования в качестве имени и данных определяется маркерами.
В отношении глобалов, в отличие от рутин, неприменимо понятие целостности сущности. Если рутина как совокупность строк после вы­полнения импорта целиком принимает новое значение, то в отношении глобалов такое соглашение действует только для каждой из перечислен­ных пар имя - значение. При импорте глобалов действуют правила:
1. Имеющиеся записи в глобалах не удаляются, независимо от совпа­дения значений индексов, в том числе при частичном их совпаде­нии.
2. Если имеется запись с тем же именем (полное совпадение значений индексов), то эта запись принимает указанное значение независи­мо от того, существовала ли она ранее, и от того, какое имела значение.
Таким образом, при импорте данных из файла экспорта глобалов действуют правила, используемые командой merge. Если для операции переноса данных необходимо обеспечить взаимную целостность меж­ду различными записями в глобалах, то перед импортом необходимо самостоятельно удалить имеющиеся в этих глобалах записи, чтобы их совокупность после импорта приняла строго то же значение, и чтобы они не содержали иных записей, бывших ранее и не имеющихся в файле экспорта.
Автоматические средства ни одной из MUMPS систем такого пред­варительного удаления данных не выполняют.
Организация файлов экспорта глобалов технически допускает их ис­пользование в системах контроля версий, но разработчики очень редко прибегают к такому способу. Согласно общему принципу разработки, в системах контроля версий хранится только то, что пишут программи­сты. Поэтому, если необходимо в разрабатываемой системе иметь кроме рутин также и данные, то разработчики помещают эти данные в рутины и программный код получает их через функцию $TEXT.
В среде MUMPS разработчиков многие годы также действовало пра­вило хранить в глобалах, подлежащих переносу через экспорт, только текстовые символы, как в значениях индексов, так и в значениях за­писей. При этом также налагалось ограничение на длины и индексов и
468 ГЛАВА 7. ПРАКТИКА ПРИМЕНЕНИЯ
данных. Такой набор соглашений, при их соблюдении, позволял свобод­но переносить глобалы между произвольными MUMPS системами. И все данные, экспортированные в соответствии с требованиями стандар­та переносимости, и сейчас могут быть импортированы любой MUMPS системой.
Что интересно в применении файлов экспорта глобалов, это то, что в такой формат могут быть экспортированы данные из самых различных источников данных и впоследствии импортированы в MUMPS систе­му. Разработчик, описывающий такой экспорт из не-MUMPS системы, должен лишь определить соответствие пар ключ-значение и соблюсти синтаксис языка MUMPS для кодирования индексов и значений.
Для разработки прикладных программных систем зачастую исполь­зуются также сущности, не являющиеся рутинами и данными глобалов, но рассматриваемые как целостный элемент. К таким относятся, напри­мер, определения экранных форм, отчетов, классов. Хотя вся информа­ция хранится в виде глобалов, к таким сущностям зачастую применяют­ся специализированые средства редактирования и их экспорт и импорт также должны выполняться соответствующим способом, как целостной сущности.
При импорте рутин и данных важным моментом эксплуатации мо­жет оказаться, в зависимости от предъявляемых требований к системе, режим транзакционности при импорте. При импорте как рутин так и гло­балов MUMPS системы, даже если поддерживают транзакционность, ее не применяют. В случае неудачи импорта, например, при замещении ру­тины или при ошибке ее компиляции, в базе данных останется состояние рутины на момент ошибки. Такой вариант используется по умолчанию всеми MUMPS системами в целях совместимости поведения. В слу­чае если разработчикам необходимо выполнять импорт с возможностью восстановления состояния рутин и данных на момент начала импорта если произошла ошибка, то такие средства импорта необходимо соста­вить самостоятельно и применить стратегию по правилам, применяемым прикладной системой.
Другим нюансом является возможность административно указать, какие глобалы или базы данных не журналируются и при откате тран­закции импорта сделанные изменения не будут возвращены. Некоторые MUMPS системы и, возможно, в зависимости от версии, могут приме­нять такие соглашения, в частности, к глобалам хранения компилиро­ванного байткода. В таких системах, если разработчик выполняет им­порт с компиляцией в транзакции, то при ошибке компиляции и откате транзакции исходный код рутин может быть возвращен в предыдущее состояние, а компилированный байткод нет, или наоборот.
7.3. ЭКСПОРТ И ИМПОРТ 469
Кроме того, часть MUMPS систем применяет хранение рутин не в глобалах, а, например, во внешних файлах или в блоках базы данных специального типа. В этом случае при применении импорта в контексте транзакции надо проверить поведение системы при выполнении команды trollback, и как именно система выполняет откат изменений сделанных при импорте рутин и при компиляции в байткод. Кроме того, возмож­ность выполнить откат сделанных изменений может определяться осо­бенностями поведения и ограничениями журнала для команды kill, вы­полняющей предварительное удаление импортируемых сущностей. Если поведение команды kill несовместимо с предъявляемыми требованиями по откату больших изменений, необходимо заменить одну команду kill на соответствующую серию так, чтобы выполняемые удаления могли быть отменены командой trollback.
Конечно, если необходимо обеспечить целостность импорта на ис­пользуемой MUMPS системе, не имеющей поддержки транзакционно­сти, то необходимо самостоятельно принять меры к сохранению инфор­мации о состоянии до импорта, о выполняемых при импорте изменениях и, при необходимости, программно отменить выполняемые изменения и вернуть состояние импортируемых сущностей (глобалы, рутины, формы, отчеты и т.д.) на начало импорта.
Хотя большинство прикладных разработок для MUMPS систем не столь критичны к целостности импорта, в случае наличия особых требо­ваний к системе по качеству разработчикам необходимо детально прове­рить все нюансы импорта с обеспечением целостности. К отличительным качествам MUMPS систем относится то, что на них возможно выполне­ние прикладных систем удовлетворяющих самым высоким критериям и разработчики имеют возможность определять и контролировать каждое выполняемое системой действие.
Кроме стандартных форматов экспорта глобалов как последователь­ности пар ключ - значение часть MUMPS систем поддерживают блоч­ный экспорт глобалов. В основе такого экспорта лежит факт, что глобалы хранятся в виде блоков диска и большинство MUMPS систем выполняет хранение данных по схеме B*-tree. В такой схеме глобал состоит из де­рева блоков, в котором есть два типа блоков - блоки ссылок и листовые, или конечные блоки.
Блоки ссылок содержат значения индексов, разделяющие области по­иска и указывающие на дочерние блоки - они могут быть как блоками ссылок так и листовыми блоками. В результате изменений базы данных вполне может оказаться, что ключи хранящиеся в блоках ссылок да­же не соответствуют реально существующим данным. Их задача в том, чтобы разделить области поиска. Листовые блоки содержат последова-
470 ГЛАВА 7. ПРАКТИКА ПРИМЕНЕНИЯ
тельности пар ключ - значение.
Если абстрагироваться от реального формата кодирования такого бло­ка, то, по сути, занимаемое им пространство это уже и есть готовая последовательность хранения данных. Поэтому часть MUMPS систем использует прямой экспорт таких блоков. Вместо многократных прохо­дов за каждой парой ключ - значение при таком способе система про­сто рекурсивно проходит дерево глобала не как логическое дерево пар ключ - значение, а как физическое дерево блоков, и экспортирует за­нимаемую листовыми блоками последовательность байтов целиком. В экспорте блоков ссылок нет никакой необходимости, поскольку они не содержат данные, а действительные ключи разделения областей поиска после импорта могут оказаться совершенно другими, и ключи блоков ссылок для экспорта просто не требуются.
Каждый из производителей использует свой собственный формат бло­ков, способы кодирования данных и ключей. В результате, естественно, получаемый файл зависит от используемой MUMPS системы и не мо­жет быть использован на системах других поизводителей, но может быть использован на системах того же производителя.
При импорте система проходит по каждому из записанных в файле образов блоков, разделяет пары ключ - значение и записывает их в базу данных по месту так, как эта пара должна храниться в текущей базе. Стратегия записи соответствует команде merge - данные, уже присут­ствующие в базе, но отсутствующие в файле экспорта, будут сохранены.
У такого блочного экспорта глобалов есть две вытекающие из его принципа особенностей. Первая особенность - это то, что экспорт вы­полняется очень быстро. Системе нет необходимости выполнять проме­жуточные преобразования значений ключей и формировать полное имя для стандартного формата экспорта. Но, при этом, импорт не избавлен от парсинга блоков на пары и выполняется несколько медленнее, чем экспорт, хотя во многих случаях и быстрее, чем импорт из стандартных форматов, поскольку ключи хранятся в образе блока в уже кодированном виде.
Вторая особенность блочного экспорта - это то, что при экспорте система использует блоки целиком, не разделяя на пары ключ - значе­ние, поэтому такому способу экспорта нельзя указать, что необходимо экспортировать только определенные значения, задав индексы, из всего глобала. Таким образом, блочный экспорт применяется всегда целиком к глобалу.
Блочный экспорт глобалов, естественно, не ограничен различением, текстовый это формат или бинарный, поскольку он всегда используется как бинарный и экспортирует всегда все символы, содержащиеся как в