Сидоров Станислав

О проблемах разработки приложений, функционирующих в различных операционных средах


Где-то мне попалась фраза, что Oracle работает на любой платформе, включая пустую коробку из-под кукурузных хлопьев. На первый взгляд может и в самом деле показаться, что никаких проблем не существует в принципе. Изначально клиент-серверная среда функционирования Oracle-приложений распределена на различных ЭВМ, в различных операционных средах и не очень понятно, откуда могут взяться какие-то сложности. Их и в самом деле нет до тех пор, пока для создания приложения можно ограничиться каким-то одним средством разработки или пока клиентская часть приложения разрабатывается (эксплуатируется) на одинаковых аппаратных и программных средствах.

Не могу взять на себя смелость давать глобальные рекомендации по этому вопросу, поскольку предлагаемый материал подготовлен на основе проведенной автором в фирме ФОРС работы по переводу системы ПРО-ФИЛИАЛ из среды MS DOS в UNIX. Система создана с использованием таких средств разработки как SQL*Forms 3.0, SQL*Menu 5.0, SQL*ReportWriter 1.1, Oracle*Terminal, SQL*Plus 3.1, SQL*Loader 7.0.

Предлагаемые Вашему вниманию рекомендации не являются KNOW-HOW автора. Это обобщение коллективного опыта, как накопленного в фирме ФОРС С.Мосиным и Д.Безруковым и донесенного автору, так и почерпнутое из такого источника как журнал МИР Oracle, в частности из большой статьи В.Юринского и его устных рекомендаций по этому вопросу.

Все это попало на очень благодатную почву, т.к. у автора возникла необходимость выполнения переноса готовой системы, разработанной для эксплуатации в среде MS DOS, авторы которой совсем не предполагали, что встанет задача переноса ее в UNIX или, по крайней мере, каких-либо намеков на такое предположение обнаружить не удалось.

Основные проблемы, которые приходилось решать в процессе этой работы, были обобщены и сгруппированы в набор правил (ограничений), которые необходимо применять при разработке, если мы хотим создавать приложения, процесс переноса которых в различные операционные среды не будет вызывать значительных трудностей.

Проблемы переносимости можно разделить на следующие категории:

Вызов форм.

1. Имя формы - определяет имя FRM файла и полезны будут следующие рекомендации:

2. Способы вызова формы - зависят от вида активного приложения:

В обоих случаях в качестве параметра задается имя формы со всеми перечисленными выше рекомендациями. Второй способ используется, если запускается приложение, имеющее меню в качестве "корневого" модуля.

На мой взгляд в большинстве приложений можно ограничиться только первым способом вызова формы. В этом случае в качестве "корневого" модуля будет тоже форма, которая имеет связанное с ней меню. В этом случае "корневая" форма может быть использована для: первоначальных проверок и установок приложения - идентификация пользователя и проверка прав доступа, установка значений по-умолчанию для глобальных переменных; завершающих действий для предсказуемого окончания приложения и т.д. Эти возможности возникают в связи с наличием в SQL*Forms триггера KEY-STARTUP и отсутствием аналогичной возможности в SQL*Menu.

Маленькую радость может доставить реализация возможности выхода из приложения только при выборе соответствующего пункта меню. Для "корневого" модуля меню такую возможность реализовать невозможно, более того возможен "неумышленный" выход из приложения по клавише , нажатой несколько раз (хоть отрывай) и, как следствие новый запуск приложения, новый connect и т.д. - целое дело.

Обращение к внешним программам.

Трудно себе представить сложное приложение, разработанное только с использованием меню и форм. SQL*Plus, SQL*Loader, программы пользователя, в том числе использующие PRO*Language, команды операционной системы - все это завязано в единое приложение. При этом команды операционной системы или ее оболочки могут быть совершенно различны для выполнения одних и тех же функций приложения в различных операционных средах.

Для определения среды, в которой функционирует приложение, может оказаться полезным использование функции USERENV('TERMINAL'), возвращаемое значение которой может быть использовано для идентификации среды. Однако наиболее простым будет решение использовать командные файлы для вызова любых внешних программ. Для обращения к командному файлу используется процедура HOST в SQL*Forms или OS_COMMAND, OS_COMMAND1 в SQL*Menu. При этом следует придерживаться следующих правил:

Несколько замечаний необходимо сделать отдельно по использованию SQL- скриптов:

@echo off

rem File: REP_PLUS.BAT

rem

rem Batch file для запуска отчетов на SQLPLUS

rem ДОЛЖЕН БЫТЬ PATH на директорию, содержащую этот файл!

rem

rem

rem

rem Параметры

rem 1 - username/password

rem 2 - имя .sql файла для формирования отчета

rem 3 - имя файла для настройки отчета (.sqp)

rem 4 - имя файла отчета (.prn)

rem 5-9 - остальные параметры

rem

sqlplus -s %1 @%2 %BANK_WD%\%3.sqp %BANK_WD%\%4.prn %5 %6 %7 %8 %9

exit

Рис. 1.

Командный файл MS DOS :

#!/bin/sh

# File: REP_PLUS

#

# Batch file для запуска отчетов на SQLPLUS

# ДОЛЖЕН БЫТЬ PATH на директорию, содержащую этот файл!

#

# Параметры

# 1 - username/password

# 2 - имя .sql файла для формирования отчета

# 3 - имя файла для настройки отчета (.sqp каталог $BANK_WD)

# 4 - имя файла отчета (.prn каталог $BANK_WD)

# 5-9 - остальные параметры

#

sqlplus -s $1 @$2 $BANK_WD/$3.sqp $BANK_WD/$4.prn $5 $6 $7 $8 $9

Рис. 2. Командный файл UNIX

host('REP_PLUS '||:GLOBAL.UNPW||' '||SQL_FILE||' REPORT '||TEXT_File,NO_SCREEN);

Рис. 3. Пример обращения к командному файлу REP_PLUS

set term off echo off show off feed off ver off head off auto off pau off

define my=reptbl

define ind_name=reptbl_ind

START &1

  drop table dept;

  create table dept as

       ...

COL CGR01 NEW_VALUE TODAY

SELECT to_char(SYSDATE,'DD/MM/YYYY HH24:MI') CGR01

FROM SYS.DUAL;

define lin="----------------------------------------------------------------------

----------------------------------------------------------------------------------

----------------------------------------------"

spool &2

SET PAGES 66 NEWPAGE 0

set linesize 212

set space 2

clear breaks

       ...

spool off

whenever sqlerror continue;

       ... exit;

Рис. 4. Фрагмент SQL-скрипта. Параметры - имена файлов.

Названия клавиш.

Использование названия клавиш в текстах сообщений, текстах подсказок и на страницах формы является удобным средством ориентации пользователя в возможностях приложения и последовательности выполнения различных его функций. Однако правильно будет информировать пользователя только о нестандартных возможностях приложения, т.е. о возможности использовать стандартные клавишные последовательности для нестантартных действий или о наличии действий, закрепленных за клавишами "Key-Fn".

В этих случаях Вам потребуется переопределять стандартные действия с использованием соответствующих триггеров. В момент переопределения триггера Вы получаете возможность определить его атрибуты Show Keys и Description. При задании атрибута Description определяйте название нового действия, которое будет закреплено за этой клавишей. Именно этот текст и должен использоваться в сообщениях и на страницах формы (см. Рис. 5). Явное использование здесь клавишной последовательности неприемлимо, т.к. она может быть различна для различного типа терминала. Присоединяясь к рекомендации В.Юринского советую использовать для таких названий текст, начинающийся с ".." (двух точек), это не навязчиво отличает такие действия от стандартных при использовании Show Keys. (см. Рис. 6)

По-видимому даже этого правила достаточно для решения большинства проблем, однако следует отметить еще несколько моментов:

Пользователь        BAL________                         План счетов Стp. 1 из 2 
                                                                Дата 20/06/96__ 
  +--ТИПЫ ПЛАHОВ СЧЕТОВ------------------------------------------------------+ 
  |+------------------------------------------------------------------------+| 
  ||Тип плана РУБЛЕВ Наименование   Рублевый_план_счетов____________________||
  |+------------------------------------------------------------------------+| 
+-+-ПЛАН СЧЕТОB -------------------------------------------------------------+-+
| Счет     П А/П С Раз Б/В Уp ДатаНач  ДатаОтм  Наименование          Счет     |
|0________ _ А-П S 00_ Бал 0_ 01/01/94 ________ Баланс_______________ _________| 
|01_______ _ А-П S 00_ Бал 1_ 01/01/94 ________ _____________________ 0________| 
|010______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Уставный_фонд________ 01_______| 
|011______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Резервный_фонд_______ 01_______| 
|012______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Специальные_фонды____ 01_______| 
|013______ _ А__ S 01_ Бал 2_ 01/01/94 ________ Фонды_основных_средст 01_______| 
|014______ _ А__ S 01_ Бал 2_ 01/01/94 ________ Фонд_амортизации_____ 01_______|
|015______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Износ_основных_средст 01_______|
|016______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Фонды_экономического_ 01_______| 
|017______ _ П__ S 01_ Бал 2_ 01/01/94 ________ Фонд_заработной_платы 01_______| 
|018______ _ П__ S 01_ Бал 2_ 01/01/94 ________ фонды_экономического_ 01_______| 
+------------------------------------------------------------------------------+ 
<План субсчетов> - преход на план субсчетов <Отчет> - создать отчет 
_Балансовый_номеp_счета_________________________________________________________ 
Count: 11        v                                         

Рис. 5. Использование названия клавиш на странице формы

Сохранить изменения F10

       ...

Меню Alt-F1

Следующая запись Ctrl-PgDn

Следующее поле Tab

След. первичн. ключ Shift-F3

..План субсчетов. PgDn

Следующая группа записей Alt-R

Вставить из буфера Alt-V

Предыдущая запись Ctrl-PgUp

Предыдущее поле Shift-Tab

Предыдущее меню Ctrl-End

..Типы планов счетов PgUp

Печатать Shift-F8

       ...

..Типы планов счетов Ctrl-F10

Key 1 Alt-F6

Key 2 Ctrl-F2

..Связать. Ctrl-F3

               Ctrl-Enter

Key 4 Shift-F9

Key 5 Alt-F2

Key 6 ^L

..Отчет. Ctrl-F7

Key 8 Ctrl-F8

Key 9 Ctrl-F9

Рис. 6. Фрагмент списка клавиш

Техническая реализация поддержки многоязыковых приложений в части названия клавиш довольно сложна и поэтому приведу только ее основные положения.

Основа реализации - неизменность для приложения функционального кода (Function Code) любого действия, возможного в форме или меню. С помощью Oracle*Terminal функциональному коду ставится в соответствие Product Key Name (имя клавиши для выбранного продукта, RUNFORM-RUNMENU в нашем случае), например коду 29 ставится в соответствие "Список" или "Список значений поля", или "List", или что- то еще в зависимости от языка общения с пользователем.

В свою очередь Product Key Name ставится в соответствие клавиатурная последовательность (Device Key Name), зависящая от типа терминала. Для нашего примера это F9 для MS DOS или Home для UNIX.

С помощью Oracle*Terminal можно получить отчет в виде текстового файла, из которого для нас важны две таблицы, отражающие описанные выше соответствия:

Полученный отчет пригоден для загрузки с использованием SQL*Loader в таблицы приложения. Настройка приложения собственно и заключается в обновлении этих таблиц всякий раз при изменении ресурс-файла (к сожалению это чисто организационный момент). При формировании сообщений следует извлекать из БД названия или клавиатурную последовательность, используя в качестве первичного ключа уникальный и неизменяемый Function Code. Названия клавиш на страницах формы следует помещать в невводимые видимые поля формы, установив для них атрибуты отображения, соответествующие текстовым константам.