Руководство по стандартам от Christopher Schreiber
Этот стандарт предназначался для разработки традиционных символьных (терминальных) приложений, и определяет только принципы дизайна базы данных и традиционного ABL-кода. Кроме того, с момента его разработки прошло довольно много времени, и некоторые положения потеряли свою актуальность.
Дизайн базы данных
Общие положения
- Поле таблицы, ссылающееся на другую таблицу (Foreign Key, FK), должно иметь то же самое имя, что и в оригинальной таблице.
- Дублирование имен полей недопустимо за исключением ссылочных полей (FK).
- В именах таблиц и полей должны использоваться подчеркивания («_»), а не дефисы («-»), во избежание проблем с SQL приложениями.
- Контекстная справка (Help) должна быть введена для каждого поля.
- Следует вводить описания таблиц и полей.
- Необходимо указывать формат поля по умолчанию
- Для каждой таблицы всегда должен быть единственный уникальный первичный ключ.
- В многокомпонентных индексах поля с часто повторяющимися значениями должны быть в начале списка, для ускорения поиска.
- Не добавляйте и не удаляйте таблицы / поля / индексы без предварительного анализа последствий этого изменения.
Таблицы
- Если требуется совместимость с ДОС, то наименования таблиц должны быть ограничены 8 символами.
- Имена таблиц должны быть осмысленными, а значит достаточно длинными. В то же время эти имена хранятся в скомпилированном r-коде, и длина имен непосредственно влияет на его размер, не следует использовать слишком длинные имена без необходимости. (Это же относится к именам полей и переменных).
- Для валидации удаления в Dictionary используйте инклюд-файлы. Это позволяет изменять условия удаления даже, если база данных используется другими пользователями.
Поля
- Рекомендуется ограничивать наименования полей 12 символами.
- Следует ограничить использование полей типа RECID. Используйте тип ROWID.
- Для DECIMAL полей число хранимых знаков после запятой должно совпадать с числом десятичных знаков, указанных в формате, либо превышать его.
- Если DECIMAL поля используют в формате символ «>», то использование опции SIDE-LABELS вызовет потерю выравнивания, в зависимости от размера и отображаемого числа (даже если формат той же длины). Поэтому для форматирования используйте символ «z».
- Формат LOGICAL полей всегда должен иметь формат истинного значения слева и ложного – справа. Формат, типа «NO/YES» может стать причиной серьезных логических проблем.
- Для CHARACTER полей избегайте использования символов «!» и «9» в формате, кроме случаев, когда без этого невозможно обойтись.
- Размер метки (LABEL) должен быть ограничен 14 символами, чтобы не усекаться при отображении с опциями WITH 1 COLUMN или WITH 2 COLUMN. Если часто используются 3 или 4 колонки, то размер меток не должен превышать 12 символов.
- Метки колонок (COLUMN-LABEL) должны иметь ту же или меньшую ширину, что и размер формата поля (могут использоваться в качестве «короткой метки» для плотных отчетов и экранов). Не разбивайте метки колонок более чем на 2 строки.
- Избегайте использования неопределенного значения (?) в качестве значения по умолчанию, кроме дат.
- Значение по умолчанию для логических полей всегда должно быть либо YES, либо NO (TRUE/FALSE). Не используйте односимвольные сокращения Y, N, T или F.
- Обязательное (Mandatory) значение должно быть установлено в YES для полей, где неопределенное значение недопустимо.
- Progress не проверяет синтаксис валидационных выражений в Dictionary. Как только Вы меняете или вводите новое выражение, тут же его проверяйте, например INSERT Customer.
Индексы
- Первичным индексом должен быть индекс, наиболее часто используемый для чтения записей из таблицы операторами FOR EACH, а не индексы, используемые для произвольного доступа.
- Индексы, включающие в себя символьные поля, должны быть объявлены как Abbreviate (кроме случаев, когда символьное поле не является последним компонентом индекса). Это позволит использовать PROMPT-FOR / FIND USING операторы, не прибегая к функции BEGINS. (Замечание: Abbreviate = Yes относится только к единственному или последнему символьному компоненту индекса).
- Рекомендуется ограничивать имена индексов 12 символами.
- Не создавайте индексы, содержащие одинаковые компоненты.
Пример:
Index-A Index-B
Field-A Field-A
Field-B Field-B
Field-C
Index-B может рассматриваться как лишний, кроме случая, когда Index-A уникален, а Index-B нет.
Замечание: следовало бы сказать «содержащие одинаковые компоненты в той же последовательности». Индекс Field-B, Field-A имеет смысл, хотя он и содержит те же компоненты. - Никогда не создавайте индекс «просто потому, что он может потребоваться в будущем».
Ссылочная целостность
- При заполнении ссылочного поля заполняется должна быть сделана проверка наличия записи в связанной таблице.
- Если запись удаляется, должна быть сделана проверка отсутствия ссылок на эту запись в связанных таблицах, если ссылки имеются, удаление должно быть запрещено. Или, в зависимости от логики приложения, связки тоже должны быть удалены.
- Проверки ссылочной целостности осуществляются в следующих случаях:
- Значение вводится в ссылочное поле пользователем
- Запись записывается в БД
- Запись удаляется
- Контроль ссылочной целостности может производиться в трех местах: в словаре данных (валидационные выражения), триггерах БД (CREATE, FIND, ASSIGN, WRITE и DELETE) и в коде приложения.
- Используйте DELETE триггер для обеспечения ссылочной целостности и аудита при удалении, а WRITE триггер для аудита.
Соглашения по наименованию
Общие соглашения
- Все ключевые слова PROGRESS пишутся заглавными буквами. Все остальные слова, такие как идентификаторы переменных, пишутся либо строчными буквами, либо допускается смешанное написание, ниже приведены соответствующие примеры. Для случаев, которые не рассматриваются ниже, предпочтительно написание строчными буквами.
- Если имя поля или таблицы состоит из одного слова, то название пишется с заглавной буквы. Если имя состоит из нескольких слов, то они отделяются друг от друга символом подчеркивания («_»), и каждое слово начинается с заглавной буквы.
Процедуры
Если необходима совместимость со стандартом Progress по именованию файлов, расширения файлов должны быть следующими:
.p Процедура
.i Include-файл
.w Форма, созданная в Application Builder (UIB)
Переменные
Для того чтобы отличать имена переменных от полей БД, рекомендуется использовать префиксы или суффиксы. Если переменная объявлена как LIKE, то имя поля должно содержаться в имени переменной.
Примеры:
DEFINE VARIABLE vDate AS DATE NO-UNDO. DEFINE VARIABLE vItem_no LIKE Item.Item_no NO-UNDO. DEFINE INPUT PARAMETER ipUpdate AS LOGICAL NO-UNDO. DEFINE SHARED VARIABLE sGLCode AS CHARACTER NO-UNDO. DEFINE GLOBAL SHARED VARIABLE gsCompany AS INTEGER NO-UNDO.
Поскольку Progress позволяет ссылаться на поле с использованием полного имени db.file.field, то рекомендуется, чтобы логические имена БД (алиасы) отличались от наименования таблиц и буферов во избежание путаницы между database.file и file.field.
Виджеты
Принцип именования виджетов такой же, как для полей и таблиц, но с префиксом, указывающим тип объекта. Допустимые префиксы:
br Browse qu Query cb Combo Box ed Editor Box tg Toggle Box rs Radio Set sl Selection List
Например:
DEFINE BROWSE brOffice_Header QUERY quOffice_Header DISPLAY Office_Header.Office_Number Office_Header.Office_Type WITH TITLE “Select a Office” 8 DOWN.
Фреймы
Как и для переменных, имена фреймов должны включать префиксы или суффиксы для их отличия. Кроме того, следует указывать тип фрейма (локальный или разделяемый). В многооконных приложениях, может возникнуть необходимость в нумерации фреймов.
Буферы
Буферы также должны иметь суффикс / префикс и идентифицироваться как локальные или разделяемые. Имя таблицы БД, к которой относится буфер, должно содержаться в ими буфера.
Потоки
Потоки также должны иметь суффикс / префикс, например:
DEFINE STREAM sReport.
Блоки
- Метки блоков должны располагаться на отдельной линии над оператором блока.
MAIN-LOOP: REPEAT: DISPLAY Customer.Name. END. /* MAIN-LOOP: */
- Метки блоков также должны иметь суффикс / префикс и давать некоторую информацию о содержимом блока, который они идентифицируют.
- Конец помеченного блока должен иметь комментарий, содержащий идентификатор метки, включая двоеточие для быстрого / легкого доступа к началу и концу блока.
MAIN-LOOP: DO: /* код блока */ END. /* MAIN-LOOP: */
- Progress позволяет повторно использовать метки в рамках одной процедуры, однако, во избежание путаницы, следует избегать подобной практики.
Временные таблицы
Для отличия временных таблиц от полей БД используйте префиксы. Если временная таблица, объявляется LIKE к таблице БД, то имя временной таблицы должно содержать имя таблицы БД:
DEFINE TEMP-TABLE ttCustomer LIKE Customer. DEFINE WORKFILE wfCustomer LIKE Customer.
Индексы
- Если индекс состоит только из одного поля, то имя индекса должно совпадать с именем поля.
- Когда индекс состоит из нескольких полей, то в его имени нужно попытаться отобразить имена составляющих его полей.
Внешние ссылки (файлы)
- Для совместимости, имя файла не должно превышать 8 символов, а расширение – 3-х.
- Запись должна производиться в пользовательский домашний каталог или специально созданный временный каталог.
- Делайте имя файла уникальным. Обычно результат функции TIME связывается с именем пользователя для предотвращения возможных конфликтов.
- Используйте расширение .d для файлов, содержащих данные, полученные оператором EXPORT.
Структура программы
Общая структура программы
- Заголовок
- Объявление переменных
- Прочие объявления
- Формы
- Тело программы
- Точка выхода
Заголовок программы
- Наименование программы
- Наименование приложения / модуля
- Расположение программы / каталог
- Лицензионная информация / копирайт
- История изменений / Ревизии / Имя пользователя / Дата
- Причины изменений
- Список инклюд-файлов
- Файлы для ввода (Input)
- Файлы для вывода (Output)
- Назначение и общее описание программы
Переменные
- Переменные должны размещаться в следующем порядке:
- Инклюд-файл с общесистемными переменными.
- Инклюд-файл со специальными переменными приложения.
- new global shared
- new shared
- shared
- local
- Переменные должны располагаться в алфавитном порядке для их удобного поиска.
- Все переменные, временные таблицы и параметры должны объявляться как NO-UNDO. Все исключения должны быть прокомментированы во избежание проблем при изменении их в будущем.
- Переменные следует, по возможности, объявлять как LIKE для лучшего самодокументирования и облегчения работы по сопровождению кода.
- Переменным не следует давать те же имена, что и полям БД во избежание путаницы.
- Все объявления NEW SHARED/SHARED переменных должны храниться в инклюд-файлах, в которые можно передавать NEW в качестве параметра в процедуре, где они изначально объявляются. Это упростит поддержку кода, а также предотвратит проблемы с различиями типов данных, опций NO-UNDO, размерности массивов и т.д.
- При объявлении переменных все опции декларации должны быть выровнены для удобства чтения.
- Все переменные должны объявляться только оператором DEFINE. Некоторые операторы языка позволяют объявлять переменные неявно, таких случаев следует избегать.
Прочие объявления
Прочие объявления должны располагаться в следующем порядке:
- new global shared stream
- new shared stream
- shared stream
- stream
- new shared buffer
- shared buffer
- buffer
- new shared temp-table
- shared temp-table
- temp-table
- new shared frame
- shared frame
- input parameter
- output parameter
- input-output parameter
Формы
- Формы объявляются в следующем порядке:
- Инклюд с new shared фреймами
- Инклюд с new shared фреймами
- Инклюд с объявлениями форм
- Локальные формы
- Все опции фрейма (FRAME Phrase) должны указываться только в операторе FORM для удобства поддержки.
- Для всех форм, описанных в программе должно указываться явное имя фрейма. Это особенно важно, когда форма объявляется в начале процедуры, тем самым область ее видимости распространяется на весь процедурный блок.
Тело программы
- Любые инклюд-файлы, выполняющие инициализирующие действия, такие как формирование заголовков форм и проверка безопасности должны располагаться вместе в начале тела программы (в точке запуска).
- Инициализация переменных должна выполняться там же.
Точка выхода
- Все процедуры должны иметь единственную точку выхода. Как правило, это оператор RETURN на последней строке процедуры. Оператор RETURN в любом другом месте процедуры аналогичен оператору GOTO в других языках, за исключением того, что RETURN передает управление вызывающей процедуре.
- Точка выхода должна использоваться для закрытия любых фреймов, которые не должны быть видимы при возврате в вызывающую процедуру, и для инициализации любых разделяемых переменных, которые должны быть инициализированы.
Форматирование, стиль, практики
Отступ
- Рекомендуется делать отступ на 3 пробела.
- Когда уровень вложенности блоков достигает точки, где каждая строка постоянно «разрывается», допускается отступ в 2 пробела, хотя это зачастую свидетельствует о плохой структуре программы.
- Все операторы внутри блока должны писаться с отступом.
- Оператор END всегда должен быть на одной линии под оператором начала блока, который он завершает.
Количество операторов на строке
- Для облегчения чтения на строке допускается использование только одного оператора.
- Нельзя разрывать оператор с использованием символа тильды (~).
Метки блока
- Основные блоки REPEAT и FOR EACH блоков должна иметь метку, которая описывает функцию, выполняемую блоком.
- Метка должна располагаться на отдельной линии над началом блока.
- Для DO блоков метка требуется только в случаях, если они выполняют действия, отличные от простой группировки операторов, или когда их длина превышает 10-12 строк.
- Любой блок, в котором используются операторы NEXT, LEAVE или UNDO должен иметь метку, а в этих операторах должна присутствовать явная ссылка на эту метку.
Пунктуация
Все операторы должны завершаться точкой, кроме меток и операторов блоков (REPEAT/DO/FOR), которые должны завершаться двоеточием.
Комментарии
- Все операторы блоков (FOR EACH/REPEAT) должны предваряться комментарием, особенно если это транзакционные блоки.
- Все операторы END в блоках должны содержать комментарий, совпадающий с меткой в начале блока. Исключение составляют блоки, содержащие небольшое количество операторов.
Словарные форматы и метки
- Предпочтительно использовать метки, форматы, выражения валидации и строки подсказки из словаря данных, а не перекрывать их в процедуре.
- При перекрытии словарной метки, старайтесь использовать операторы FORM или DEFINE FRAME, при условии, если фрейм объявляется с помощью них.
- Для переменных указывайте LABEL и FORMAT в операторах DEFINE или FORM, а не в других операторах манипуляции данными, таких как DISPLAY и UPDATE.
- Используйте LABEL при объявлении боковой метки и COLUMN-LABEL при объявлении меток столбцов. Ширина COLUMN-LABEL должна совпадать с шириной FORMAT.
Инклюд-файлы
- Используйте общесистемные инклюд-файлы везде, где это возможно.
- Общесистемные инклюд-файлы, использующиеся в нескольких приложениях должны размещаться в каталоге «include».
- Специальные инклюд-файлы приложения должны размещаться в подкаталоге приложения (например, ar/).
- Для передачи параметров в иклюд-файл должны использоваться именованные параметры, а не позиционные.
- Рекомендуется, чтобы вложенность инклюд-файлов не превышала 3-х уровней, т.к. большее число уровней затрудняет отладку.
- Инклюд-файлы не должны заканчивать блок, начатый не в них. И наоборот, инклюд-файлы не должны начинать блок, конец которого не находится в них.
- Не вставляйте комментарии внутрь фигурных скобок, чтобы не вводить в заблуждение компилятор.
Операторы If / Then / Else
- Следует избегать условия NOT. Проверяйте истинное условие, где только это возможно.
- Не рекомендуется использовать совместно условия AND и OR, но если они используются, тогда явно ограничивайте условия скобками. Помещайте каждое условие на отдельную строку с выравниванием AND/OR по вертикали.
- Для группы условий, связанных через AND, помещайте сначала условия, истинность которых маловероятна.
- Для группы условий, связанных через OR, помещайте сначала условия, истинность которых более вероятна.
- Каждая ветка IF/THEN/ELSE должна использовать DO блок, даже если он состоит из одного оператора. Недостатком является незначительный рост R-кода. Это избавит от ошибок при дальнейшем добавлении других операторов в ветку.
- Исключение – вложенный IF/THEN/ELSE, когда на каждой ветке выполняется только один оператор, например RUN.
- ELSE оператор должен писаться на отдельной строке и быть выровнен с оператором IF, к которому он относится.
- Когда проверяется логическое поле или переменная, не используйте TRUE, FALSE, YES, и NO для сравнения, потому что это приводит к снижению производительности и большему R-коду .
- Используйте CASE оператор везде, где это возможно.
- Не используйте «пустые» THEN и ELSE.
Оператор CASE
Используйте оператор CASE вместо вложенных операторов IF/THEN/ELSE.
Завершение программы
Все программы должны иметь единственную точку выхода. Последним оператором каждой программы должен быть RETURN, и он должен быть единственным. Для того, чтобы перейти к оператору RETURN из любого места внутри программы, используйте оператор LEAVE.
Наименования полей
- Все наименования полей должны иметь ссылку на таблицу (буфер): filename.field-name.
- Если общие таблицы используются в нескольких БД, то поле должно дополняться ссылкой на БД: dbname.filename.fieldname.
- Если список полей в операторах DISPLAY, UPDATE, FORM и т.д. не помещается на одной строке, каждое поле указывается на отдельной строчке с отступом от оператора. Так же с отступом указывается фрейм.
- Для отображения подмножества элементов массива используйте конструкцию типа
DISPLAY array[1 FOR 5]
вместо перечисления элементов массива.
Опции форматирования (Format-phrase)
Когда используются опции форматирования, их следует выравнивать по вертикали или горизонтали.
Опции фрейма
Записывайте опции фрейма таким образом, чтобы избегать идущих подряд целых значений, относящимся к различным опциям:
WITH RETAIN 1 8 DOWN ROW 2 2 COLUMNS.
Лучше написать:
WITH 2 COLUMNS 8 DOWN ROW 2 RETAIN 1.
Ключевые слова, которые нельзя использовать
- Оператор STOP: полезен только для тестирования.
- Опция USE-INDEX: жестко привязывает запрос к использованию конкретного индекса. Используйте эту опцию только тогда, когда вы точно уверены, что автоматически выбранный Progress индекс не корректен и не соответствует распределению данных.
Ключевые слова, которые не стоит использовать
- OF: OF делает код проще для чтения, но скрывает наименования полей, которые используются для связи таблиц. Можно использовать, когда нет дальнейших уточнений необходимых для выбора записи. Не используйте OF и WHERE вместе.
- Функция ENTERED: флаг ENTERED легко сбрасывается операторами UNDO, RETRY, что может приводить к неправильным результатам.
- Оператор RELEASE. Использование этого оператора внутри транзакции может указывать на непонимание программистом области действия транзакции. RELAESE не может освободить записи в статусах SHARE-LOCK или EXCLUSIVE-LOCK внутри транзакции. ЗАМЕЧАНИЕ: В действительности здесь имеет место непонимание действия оператора RELEASE. Этот оператор проверяет уникальность индексов, заполнение обязательных (mandatory) полей, и сбрасывает измененную запись в базу. Он также гарантирует сброс блокирования (а не понижение его до SHARE-LOCK) по концу транзакции, если область видимости записи больше области действия транзакции.
- Оператор OR: Использование его в выражении WHERE может негативно сказаться на использовании индекса.
Сокращения
- Сокращение наименований полей, переменных и таблиц не допустимо.
- Следующие ключевые слова не должны сокращаться, поскольку минимально допустимое сокращение слишком короткое:
- ACCUMULATE
- AVAILABLE
- AVERAGE
- ALL COLORS (BLACK, BLUE, CYAN, ETC.)
- BLINK
- DATE
- LIGHT
- NO-VALIDATE
- PROMPT-FOR
- RECID
- SUB-AVERAGE
- TRANSACTION
- UNDERLINE
- Следующие ключевые слова можно сокращать, но не так сильно, как это допускает Progress:
- CHARACTER CHAR
- DECIMAL DEC
- DESCENDING DESCEND
- INTEGER INT
- LOGICAL LOG
- Все прочие сокращения, поддерживаемые Progress, допустимы.
Прочее
- Жесткое кодирование значений констант в любой программе не рекомендуется, кроме следующих исключений: параметры, передаваемые в инклюд и неизменяемые константы (например, 12 месяцев в году).
- Не допускается жесткое кодирование меток клавиш.
- Длинные строки в операторе MESSAGE, которые не умещаются в одной строке, следует разбивать.
- Сообщения MESSAGE следует окаймлять пробелами с обоих концов. Это также применимо к TITLE.
- Алгебраический стиль логических выражений более предпочтителен, чем стиль языка FORTRAN. Хотя допустимы оба стиля.
- При использовании циклов DO WHILE / REPEAT WHILE всегда проверяйте условие «меньше» или «больше», а не «равно». Это позволит избежать зацикливания, если условие равно не встретится.
- Используйте функцию TRIM для усечения лидирующих пробелов в символьных полях (особенно участвующих в сортировках).
Фреймы
- Поля в операторе FORM должны располагаться вертикально по одному на строке для облегчения поддержки.
- Фреймы должны быть стандартизированы с использованием рамки по умолчанию или без нее. Для фреймов, используемых для вывода на принтер, следует применять опцию NO-BOX, чтобы убрать пустую строку и столбец, которые Progress выделяет для вывода «невидимой» графической рамки вверху фрейма.
- Для стандартизации ширины фрейма в отчетах, используйте стандартные значения опции WIDTH, которые совпадают с количеством символов на дюйм, которое обычно используется в принтерах:
- 10 CPI: 75/125
- 12 CPI: 90/140
- Избегайте использование ширины фрейма, превышающей 132 символа.
- Для эффективного использования бумаги и сохранения адекватных полей, используйте PAGE-SIZE 60.
Транзакции
- Операторы блоков, объявляющих транзакцию, должны явно использовать ключевое слово TRANSACTION, что позволит компилятору отследить возможные ошибки транзакции.
Ошибки
- Ошибка Progress (например, ввод дублирующего значения в уникальный индекс) не должна отправлять пользователя к началу блока, который по умолчанию имеет опции (UNDO, RETRY). Вместо этого, используйте вложенные блоки DO ON ERROR вместе с оператором NEXT-PROMPT для удержания курсора на поле, где произошла ошибка.
- Оператор UNDO никогда не должен использоваться без операторов RETRY, NEXT, LEAVE или RETURN, хотя Progress это допускает. Всегда сопровождайте оператор UNDO соответствующим действием (RETRY, NEXT, LEAVE или RETURN) и меткой, если нужно. Хотя Progress и допускает использование оператора RETURN вместе с UNDO, но как уже отмечалось ранее, этого следует избегать.
Чтение записей
- Всегда используйте WHERE вместо OF для того, чтобы было понятно, какие поля используются для связи между таблицами. OF используйте тогда, когда нет дополнительных условий, необходимых для выбора записи. Не используйте OF и WHERE вместе.
- USING может применяться вместо WHERE, потому что USING указывает ключ, который используется.
- Хороший стиль программирования подразумевает размещение наименований полей, которые будут использоваться для поиска записи, слева от оператора сравнения в выражении WHERE (Не пишите FIND Customer WHERE 10 = Customer.Cust_Num.).
- Если транзакция допускает, все связанные записи должны искаться одним составным оператором FOR
- Когда оператор PROMT-FOR следует за оператором FIND, используйте опцию NO-ERROR в операторе FIND, только, если вы не хотите использовать обработку ошибок по умолчанию (сообщение об ошибке, следующее за UNDO, RETRY в ближайшем блоке с UNDO). После оператора FIND/NO-ERROR всегда выполняется проверка с использованием функции AVAILABLE.
- За FIND/NO-WAIT должна всегда следовать проверка с помощью функции LOCKED.
- Сравнения в выражении WHERE должны идти в таком порядке:
- Поля индексов, которые используются операторами FIND/FOR EACH. Сравнения должны располагаться в том же самом порядке, что и поля в индексах.
- Поля из индексов, которые не используются операторами FIND/FOR EACH.
- Неиндексированные поля
- Переменные
- Выражения
- Используйте оператор FIND (без FIRST/NEXT/PREY/LAST) только с уникальным индексом и только, когда WHERE выражение включает в себя все поля уникального индекса, т.к. FIND ищет единственную запись по уникальному индексу. Для остальных ситуаций используйте FIND с опциями FIRST/NEXT/PREY/LAST.
- Не используйте FOR блок для поиска одной записи, связанной отношением один-ко-одному.
Блокирование записей
- Используйте NO-LOCK везде, где состояние информации не критично (большинство отчетов и запросов), для снижения вероятности конфликтов блокирования и улучшения производительности.
- В случаях, когда предполагается, что пользователь будет изменять существующую запись, читайте запись с EXCLUSIVE-LOCK.
- SHARE-LOCK не следует использовать никогда.
- Всегда явно указывайте статус блокировки.
Переносимость
Терминалы
Так как Progress может использовать терминалы с различным количеством строк (25 для DOS, 24 для большинства ASCII терминалов), используйте следующие функции (в выражениях для опций DOWN и ROW) для вычисления доступного количества строк и для максимального использования всего доступного экранного пространства:
- SCREEN-LINES
- FRAME-DOWN
- FRAME-ROW
- FRAME-LINE
Имена
Для совместимости с DOS следующие объекты должны быть ограничены 8 символами.
- Имена файлов
- Имена программ
- Имена инклюд-файлов
Расширение файлов ограничено 3 символами.
Наименования всех программ и инклюдов в коде должны быть строчными буквами.
Операционные системы
Используйте функцию OPSYS, чтобы защитить вызовы системных функций.
Программа 69. Проверка и вызов операционной системы
CASE OPSYS WHEN “unix” THEN UNIX. WHEN “msdos” THEN DOS. WHEN “vms” THEN VMS. WHEN “btos” THEN BTOS. WHEN “os2” THEN OS2. WHEN “os400” THEN OS400. WHEN “nt” THEN NT. OTHERWISE MESSAGE “Unknown Operating System:” OPSYS. END CASE.
Замечания:
- Приведенный здесь пример (Программа 69) работать не будет. Функция OPSYS в текущих версиях OpenEdge может возвращать два значения, либо “UNIX”, либо “WIN32”.
- Под Windows возможно изменение возвращаемого функцией OPSYS значения, например, на “MS-DOS”, что может потребоваться при переносе старых приложений на новые версии OpenEdge. Это осуществляется путем изменения ключа Opsys в ini-файле или регистре.
- Под UNIX вызов операционной системы возможен только с помощью оператора UNIX.
- Под Windows вызов операционной системы возможен с помощью любого из перечисленных в примере операторов (кроме NT), так что работоспособен даже такой дикий код:
IF OPSYS = “WIN32” THEN UNIX dir.
Цвет
Используйте опцию COLOR VALUE (color-variable) во всех фреймах. Придерживаясь этого правила легко перенести приложение с монохромного монитора на цветной.
Приложение
- Когда транзакция завершается, пользователь должен быть информирован сообщением, что транзакция успешно завершена и зафиксирована в БД.
- Предупреждения должны предваряться словом “ПРЕДУПРЕЖДЕНИЕ:”
- Сообщения об ошибках должны предваряться словом “ОШИБКА:”
- Все сообщения об ошибке должны сопровождаться звуковым сигналом с помощью оператора BELL.
- Тексты подсказок должны начинаться со слова “Введите:”.
Заключение
Кроме вышеизложенного, рассматриваемый документ содержит еще несколько разделов, не являющихся в полном смысле описанием стандарта, таких как вопросы производительности, работы с несколькими базами данных, транзакции, области видимости записи и прочее.
По некоторым признакам, разработка стандарта начиналась в эпоху Progress версии 5.
По этой причине, а также из-за ориентированности на традиционные терминальные приложения, применимость такого стандарта в настоящее время ограничена.
В то же время, рассматриваемый документ дает определенное основание для выработки собственного стандарта.