ADD (добавить новую запись)
ADD(файл,[длина])
файл | Метка файла. |
длина | Целочисленная константа, переменная или выражение, содержащее число байт, записываемых в файл. ДЛИНА должная быть больше нуля но не больше длины структуры RECORD. Если ДЛИНА пропущена или выходит за разрешенный диапазон, то она сбрасывается до длины структуры RECORD. |
Оператор ADD создает в файле новую запись и заполняет ее данными из буфера структуры RECORD. При выполнении ADD, обновляются все ключевые файлы (НЕ индексы!). Если происходит какая-либо ошибка, то запись не добавляется в файл. Конкретное действие ADD зависит от файлового драйвера.
Если на диске не хватает места для размещения новой записи, то возвращается ошибка "Доступ запрещен".
Возвращаемые ошибки:
05 Доступ запрещен
37 Файл еще не открыт
40 Такой ключ уже есть
Пример:
ADD(Customer) !Заносим данные о новом
! покупателе
IF ERRORCODE() THEN STOP(ERROR()). !и проверяем на нали-
! чие ошибок.
APPEND (добавить новую запись)
APPEND(файл[,длина])
файл | Метка файла. |
длина | Целочисленная константа, переменная или выражение, содержащее число байт, записываемых в файл. ДЛИНА должная быть больше нуля но не больше длины структуры RECORD. Если ДЛИНА пропущена или выходит за разрешенный диапазон, то она сбрасывается до длины структуры RECORD. |
Оператор APPEND вводит в файл данных новую запись из буфера, выделенного под структуру RECORD. Ключевые файлы НЕ обновляются. После добавления записи командой APPEND, надо перестроить ключи командой BUILD. Обычно APPEND используется для пакетного добавления нескольких записей в один прием (С.П.А - без обновления ключе, добавление записи, разумеется, происходит быстрее).
Если на диске не хватает места для размещения новой записи, то возвращается ошибка "Доступ запрещен". Конкретное действие APPEND зависит от файлового драйвера.
Возвращаемые ошибки:
05 Доступ запрещен
37 Файл еще не открыт
Пример:
LOOP UNTIL EOF(InFile) !Обработка входного файла
NEXT(InFile) ! читаем все записи подряд
IF ERRORCODE() THEN STOP(ERROR()). ! Есть ошибки?
Cus:Record = Inf:Record !Копируем данные в буфер файла
! покупателей
APPEND(Customer) ! и ДОБАВЛЯЕМ новую запись в
! этот файл
IF ERRORCODE() THEN STOP(ERROR()). ! Есть ошибки?
. !Конец цикла обработки
BUILD(Customer) !А теперь перестроим ключи...
См. также:
BINARY (MEMO содержит двоичные данные)
BINARY
Атрибут МЕМО-поля BINARY указывает на то, что MEMO-поле может содержать не только текстовые, но и двоичные данные. Обычно, этот атрибут используется для хранения в МЕМО-полях небольших картинок, которые можно выводить в IMAGE-полях на экране.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam),
NameKey KEY(Nam:Name)
NbrKey KEY(Nam:Number)
Picture MEMO(48000),BINARY !Двоичное поле длиной
! до 48,000 байт
Rec RECORD
Name STRING(20)
Number SHORT
См. также: , IMAGE
BOF (начало файла)
BOF(файл)
файл | Метка файла. |
Функция BOF возвращает НЕнулевое значение (истину), если операторами PREVIOUS или SKIP(-count) была прочитана или пропущена самая первая запись последовательности. В противном случае возвращается ноль (ложь).
Функция BOF наиболее часто используется для проверки условия в цикле LOOP UNTIL. Поскольку условие выполнения этого цикла вычисляется в НАЧАЛЕ цикла, то BOF вернет ИСТИНУ после прочтения первой записи последовательности.
Тип возвращаемого результата: LONG
Пример:
SET(Trn:DateKey) !Пляшем от конца файла по ключу
LOOP UNTIL BOF(Trans) !Обрабатываем файл с конца
PREVIOUS(Trans) ! последовательно читая записи
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
См. также: , , LOOP
BUILD (построить ключи и/или индексы для файла)
| ключ |
BUILD( |индекс| [,компоненты])
| файл |
ключ | Метка описания КЛЮЧА. |
индекс | Метка описания ИНДЕКСА. |
файл | Метка описания ФАЙЛА. |
компоненты | Строковая константа или переменная, содержащая список полей, на основе которых построить динамический ИНДЕКС. Имена полей должны разделяться запятыми, перед именем поля должен стоять знак плюс или минус, чтобы задать сортировку по возрастанию или по убыванию. |
Оператор BUILD строит ключи и индексы. BUILD(ключ), BUILD(индекс) и BUILD(файл) требуют монопольного доступа к файлу. Т.е., файл должен быть заблокирован (через LOCK) или открыт с кодом доступа 12h (ВСЕМ кроме меня запрещено чтение/запись) или 22h (ВСЕМ кроме меня запрещена запись). BUILD(индекс,компоненты) НЕ требует монопольного доступа к файлу.
BUILD(ключ) BUILD(индекс) | Строит только указанный КЛЮЧ или ИНДЕКС. Файл должен быть закрыт, заблокирован или открыт в режиме 12h или 22h. |
BUILD(файл) | Строит все КЛЮЧИ или ИНДЕКСЫ ФАЙЛА. Файл должен быть закрыт, заблокирован или открыт в режиме доступа 12h или 22h. |
BUILD(индекс,компоненты) | Позволяет строить динамический ИНДЕКС. Эта форма BUILD не требует монопольного доступа к файлу, тем не менее файл должен быть открыт в любом разрешенном режиме доступа. Динамический ИНДЕКС создается как временный файл только для строящего его пользователя. Этот временный файл автоматически удаляется при закрытии файла. |
Возвращаемые ошибки:
37 Файл еще не открыт
40 Такой ключ уже есть
63 Требуется монопольный доступ
76 Неверные параметры для индекса
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)!Описание структуры файла
NameKey KEY(Nam:Name).OPT !Описание ключа по имени
NbrNdx INDEX(Nam:Number),OPT !Описание индекса по но-
! меру
DynNdx INDEX() !Описываем динамический
! индекс
Rec RECORD
Name STRING(20)
Number SHORT
. .
CODE
OPEN(Names,12h) !Открываем файл с исключительным
! правом чтения/записи
BUILD(Names) !Строим все ключи для файла имен
BUILD(Nam:NbrNdx) !Строим индекс по номеру
BUILD(Nam:DynNdx.'-Nam:Number,+Nam:Name')
!Строим динамический индекс - по номеру с убыванием,
! по имени с возрастанием.
См. также: ,
BYTES (размер файла в байтах)
BYTES(файл)
файл | Метка файла. |
Функция BYTES возвращает размер в байтах либо файла, либо последней записи, к которой было обращение. Если выполнить BYTES сразу после открытия файла, то она вернет размер этого файла. После того, как к файлу обратились операторами GET, NEXT, ADD или PUT, BYTES верней размер в байтах записи, прочитанной в структуру RECORD. Функцию BYTES можно использовать для того, чтобы узнать, сколько было прочитано байт при работе с записями переменной длины.
Пример:
OPEN(DosFile) !Открыть файл
IF (BYTES(DosFile) % 80) > 0 !Check for short record
SavPtr = INT(BYTES(DosFile)%80)+1
! compute short record pointer
ELSE
SavPtr = BYTES(DosFile)/80 ! compute last record pointer
.
GET(DosFile,SavPtr) !Get the last record
LastRec = BYTES(DosFile) !Save size of the short record
CLOSE (закрыть файл данных)
CLOSE(файл)
файл | Метка ФАЙЛА. |
Оператор CLOSE закрывает ФАЙЛ. Обычно, это вызывает сброс дисковых буферов на диск и освобождение памяти, выделенной под них, кроме буфера, хранящего данные структуры RECORD. Точный порядок закрытия файла зависит от файлового драйвера.
Пример:
CLOSE(Customer) !Закрыть файл покупателей
COMMIT (завершить успешно проведенную транзакцию)
COMMIT
Оператор COMMIT завершает активную транзакцию. Выполнение оператора COMMIT подразумевает, что транзакция успешно завершена и не возникнет необходимость выполнения ROLLBACK. После выполнения COMMIT, выполнение ROLLBACK становится НЕВОЗМОЖНЫМ.
COMMIT информирует участвующий в транзакции файловый драйвер о том, что временные файлы, необходимые для приведения базы в исходное состояние (как было до транзакции), можно удалять. После этого, файловый драйвер производит действия, необходимые в его файловой системе для завершения транзакции.
Пример:
LOGOUT(.1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailOue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
См. также: ,
COPY (копировать файл данных)
COPY(файл,новый_файл)
файл | Метка копируемого файла. |
новый_файл | Строковая константа или переменная, содержащая полную спецификацию файла (диск, каталог и имя). Если в спецификации отсутствуют диск и каталог, то подразумеваются текущий каталог текущего диска. Если указан только путь, то для имени НОВОГО_ФАЙЛа используются имя и расширение копируемого ФАЙЛа. |
Оператор COPY создает копию файла, и делает соответствующую запись в каталоге. Копируемый ФАЙЛ должен быть закрыт, иначе будет возвращена ошибка "Файл уже открыт". Если спецификация НОВОГО_ФАЙЛа совпадает со спецификацией оригинала, то такой оператор COPY игнорируется.
Поскольку некоторые файловые драйверы используют несколько физических ФАЙЛОВ для работы с ними как с ОДНИМ ФАЙЛОМ, то подразумеваемые имя и расширение файла зависят от файлового драйвера. Если происходит какая-либо ошибка, то файл не копируется.
Возвращаемые ошибки:
02 Файл не найден
03 Путь не существует
05 Доступ запрещен
52 Файл уже открыт
Пример:
COPY(Names,'A:\') !Копируем файл имен на дискету
COPY(CompText,Filename) !Копируем текстовый файл под другим
! именем
CREATE (разрешает создание файла)
CREATE
Атрибут CREATE, в описании файла, позволяет создавать файл на диске оператором CREATE из программы, в которой этот файл описан.
Файлы, описанные без атрибута CREATE, могут быть созданы с помощью Clarion Data Dictionary Administrator.
Пример:
Names FILE,DRIVER('Clarion'),CREATE!Описываем файл и разрешаем
!его создание
Rec RECORD
Name STRING(20)
. . !Конец описания файла
CREATE (создать пустой файл данных)
CREATE(файл)
файл | Метка файла, который надо создать. |
Оператор CREATE создает в заданном каталоге пустой файл данных. Если файл уже существует, то он удаляется и пересоздается как файл, не содержащий данных. Файл должен быть закрыт, иначе возникает ошибка "Файл уже открыт". CREATE не оставляет созданный файл открытым.
Возвращаемые ошибки:
03 Путь не существует
04 Слишком много открытых файлов
05 Доступ запрещен
52 Файл уже открыт
54 Нет атрибута CREATE
Пример:
CREATE(Master) !Создать новый основной файл
CREATE(Detail) !Создать новый файл подробностей
DELETE (удалить запись)
DELETE(файл)
файл | Метка файла. |
Этот оператор удаляет последнюю запись, к которой происходило обращение операторами NEXT, PREVIOUS, GET, ADD или PUT. Также удаляются сведения об этой записи из ключевых файлов. DELETE не очищает буфер структуры RECORD, таким образом, данные удаленной записи остаются по-прежнему доступны до тех пор, пока содержимое буфера RECORD не изменится.
Если не было обращения к какой-либо записи или запись блокирована другой рабочей станцией, DELETE возвращает ошибку "Запись недоступна" и удаления записи не происходит. Точное действие оператора DELETE зависит от файлового драйвера.
Возвращаемые ошибки:
05 Доступ запрещен
33 Запись недоступна
Пример:
Customer FILE,DRIVER('Clarion'),PRE(Cus)
NameKey KEY(Cus:Name),OPT
NbrKey KEY(Cus:Number),OPT
Rec RECORD
Name STRING(20)
Number SHORT
. .
CODE
Cus:Number = 12345 !Инициализируем ключевое
! поле
GET(Customer,Cus:NbrKey) !Читаем соответствующую ему
! запись
IF ERRORCODE() THEN STOP(ERROR()).
DELETE(Customer) !Если это то, что нам надо,
! то удаляем эту запись.
См. также: , , , , ,
DRIVER (задает тип файла данных)
DRIVER(filetype[,driver string])
filetype | Строковая константа, содержащая имя менеджера файлов (Btrieve, Clarion и т.д.). |
driver string | Строковая константа или переменная. содержащая любые добавочные инструкции для драйвера. Атрибут DRIVER задает, какой драйвер используется для работы с файлом. Атрибут DRIVER требуется во всех описаниях файлов. |
Программы на Кларионе используют драйверы для доступа к файлам. Файловый драйвер служит переводчиком между программой и файловой системой, позволяя использовать одни и те же команды для разных файловых систем.
Внутренняя реализация той или иной команды доступа к файлу зависит от файлового драйвера. Некоторые команды могут быть недоступны с определенным драйвером из-за ограничений, налагаемых файловой системой. Каждый файловый драйвер документируется отдельно. Все неподдерживаемые команды, атрибуты полей, типы данных и/или идиосинкразии файловой системы приводятся в документации.
Пример:
Names FILE,DRIVER('Clarion') !Начало описания файла
Record RECORD
Name STRING(20)
!Конец описания файла
DUP (разрешить повторяющиеся значения полей ключа)
DUP
Атрибут DUP, в описании ключа, позволяет иметь в файле несколько записей с одинаковым значением ключевых полей. Если атрибут DUP пропущен, то попытка добавить или перезаписать запись с уже существующими значениями ключевых полей, вызовет ошибку "Такая запись уже есть" ("Creates Duplicate Key"), и запись не будет записана в файл. Во время последовательной обработки по ключу, записи с одинаковыми ключевыми полями обрабатываются в том физическом порядке, в котором их ключевые поля расположены в файле ключа. Операторы GET и SET обращаются к первой записи из тех, что имеют одинаковые ключевые поля. Атрибут DUP НЕ нужен для индексов, поскольку индексы ВСЕГДА допускают дублированные значения ключевых полей.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name),DUP
!Ключ по имени, разрешаем одинаковые имена
NbrKey KEY(Nam:Number)
!Ключ по номеру. Одинаковые номера запрещены
Rec RECORD
Name STRING(20)
Number SHORT
. .
DUPLICATE (проверить на дублирование ключевых полей)
DUBLICATE(ключ)
файл
ключ | Метка описания ключа. |
файл | Метка файла. |
Функция DUPLICATE возвращает НЕнулевое значение (истину), если при внесении записи в файл возникла ошибка "Такой ключ уже есть" ("CREATES DUPLICATE KEY"). Если задан параметр КЛЮЧ, то проверяется заданный ключевой файл. С параметром ФАЙЛ проверяются все ключи, описанные без атрибута DUP.
Функция DUPLICATE подразумевает, что содержимое структуры RECORD аналогично содержимому записи, на которую указывает указатель текущей записи. Таким образом, при использовании DUPLICATE ДО добавления записи, указатель текущей записи должен быть очищен командой GET(файл,0).
Тип возвращаемого результата: LONG
Пример:
IF Action = 'ADD' THEN GET(Vendor,0).
!При добавлении очищаем указатель
IF DUPLICATE(Vendor) !Если такой продавец уже есть, то
SCR:MESSAGE = 'Уже есть продавец с таки номером'
! выводим сообщение
SELECT(?) ! и снова ждем ввода в тоже самое
! поле
. !Конец оператора if
См. также:
EMPTY (очистить файл данных)
EMPTY(файл)
файл | Метка существующего файла. |
EMPTY удаляет ВСЕ записи из заданного файла. EMPTY требует монопольного доступа к файлу. То есть файл должен быть открыт в режиме доступа 12h (всем, кроме меня запрещены чтение/запись) или 22h (всем, кроме меня запрещена запись)
Возвращаемые ошибки:
63 Требуется монопольный доступ
Пример:
OPEN(Master,18) !Открыть основной файл
EMPTY(Master) ! и опустошить его
См. также: ,
ENCRYPT (шифровать файл данных)
ENCRYPT
Атрибут ENCRYPT, используемый совместно с атрибутом OWNER, указывает на необходимость шифрования данных в файле. ENCRYPT разрешен ТОЛЬКО с атрибутом OWNER. Даже используя 16-ричный редактор, весьма трудно расшифровать зашифрованные данные.
(С.П.А - Сильно сомневаюсь. Если ключ к шифру задан как в примере для OWNER, то расшифровка - дело нескольких минут.)
Пример:
Names FILE,DRIVER('Clarion'),OWNER('Clarion'),ENCRYPT
Record RECORD
Name STRING(20)
. .
См. также:
EOF (конец файла)
EOF(файл)
файл | Метка файла. |
Функция EOF возвращает ИСТИНУ (НЕ ноль) если была прочитана (оператором NEXT) или пропущена (оператором SKIP) последняя запись последовательности. В противном случае возвращается ЛОЖЬ (нулевое значение). Функция EOF обычно используется для проверки условия в циклах LOOP UNTIL. Поскольку условие в таком цикле вычисляется в начале цикла, то EOF вернет ИСТИНУ после того, как будет прочитана последняя запись.
Тип возвращаемого результата: LONG
Пример:
SET(Trn:DateKey) !Пляшем от начала файла по ключу
LOOP UNTIL EOF(Trans) !Обрабатываем файл с начала,
PREVIOUS(Trans) ! последовательно читая записи
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
См. также: , , LOOP
FILE (описание структуры файла данных)
метка FILE,DRIVER()[,CREATE][,RECLAIM][,OWNER()][,ENCRYPT]
[,NAME()][,PRE()]
метка [INDEX()]
метка [KEY()]
метка [MEMO()]
[метка] RECORD
fields
. .
DRIVER | Задает тип файла данных. Атрибут DRIVER требуется для всех описаний структуры FILE. |
CREATE | Позволяет создать файл командой CREATE во время работы программы. |
RECLAIM | Разрешает повторно использовать место, освобожденное удаленными записями. |
OWNER | Задает пароль для шифрования данных. |
ENCRYPT | Шифрует файл данных. |
NAME | Останавливает имя файла в стандарте ДОС. |
PRE | Объявляет префикс метки для структуры. |
INDEX | Объявляет статический индекс файла, который должен быть перестроен во время исполнения. |
KEY | Объявляет динамически обновляющийся индекс файла. |
MEMO | Описывает текстовое поле переменной длины до 64K длиной). |
RECORD | Объявляет структуру записи по полям. Структура RECORD ДОЛЖНА быть в описании каждого файла. |
fields | Элементы данных в структуре RECORD. |
FILE объявляет структуру файла данных. Метка структуры FILE используется в операторах и функциях, работающих с файлами. Структура FILE должна завершаться точкой или оператором END.
Атрибуты структур FILE, KEY, INDEX, MEMO, операторы описания данных и типы данных, которые могу содержаться в файле, целиком зависят от конкретного файлового драйвера. Все, что не поддерживается файловой системой, заданной в атрибуте DRIVER, при открытии файла вызовет сообщение об ошибке файлового драйвера. Атрибуты и (или) типы данных, разрешенных для конкретной файловой системы, перечислены в документации на файловый драйвер.
Во время выполнения, под структуру RECORD выделяется память для использования в качестве буфера, где хранятся данные, считанные с диска. В файле обязательно должна быть структура RECORD.
Пример:
Names FILE,DRIVER('Clarion') !Описание структуры файла
Rec RECORD
Name STRING(20)
. . !Конец описания файла
FLUSH (сбросить буфера ДОС на диск)
FLUSH(файл)
файл | Метка файла. |
Оператор FLUSH завершает операцию STREAM. Он сбрасывает буфера ДОС, что приводит к обновлению записи каталога для данного файла. Поддержка этого оператора зависит от файловой системы и конкретные результаты этой команды описаны в документации по файловому драйверу.
Пример:
STREAM(History) !Используем буфера ДОС
SET(Current) !Идем в начало файла CURRENT.
LOOP UNTIL EOF(Current)
NEXT(Current)
His:Record - Cur:Record
ADD(History)
. !Конец цикла
FLUSH(History) !Заканчиваем поточную обра-
! ботку и сбрасываем буфера.
См. также:
Документация по Clarion
файл,ключ
GET( файл,указатель_в_файле[,длина] )
ключ,указатель_в_ключе
файл | Метка файла. |
ключ | Метка ключа или индекса. |
указатель_в_файле | Числовая константа, переменная или выражение, содержащая значение, возвращаемое функцией POINTER(файл). Конкретное значение зависит от файлового драйвера. |
указатель_в_ключе | Числовая константа, переменная или выражение, содержащая значение, возвращаемое функцией POINTER(ключ). Конкретное значение зависит от файлового драйвера. |
длина | Целочисленная константа, переменная или выражение, содержащее число байт, записываемых в файл. ДЛИНА должная быть больше нуля но не больше длины структуры RECORD. Если ДЛИНА пропущена или выходит за разрешенный диапазон, то она сбрасывается до длины структуры RECORD. |
Оператор GET находит заданную запись в файле данных и считывает ее в буфер структуры RECORD. Прямой доступ к записи осуществляется либо по относительному номеру записи в файле либо совпадению ключевого поля со значением заданного ключа.
GET(файл,ключ) | Получает первую запись из файла (согласно ключу), которая содержит значения, совпадающие со значениями компонент ключа. |
GET(файл,указатель_в_файле[,длина]) | Получает запись из файла на которую указывает указатель_в_файле. Если указатель_в_файле равен нулю, то указатель на текущую запись очищается и запись не считывается. |
GET(ключ,указатель_в_ключе) | Получает запись на которую указывает указатель_в_ключе. |
Значения указателя_в_файле и указателя_в_ключе зависят от файлового драйвера. Это может быть: номер записи; номер байта в файле или какой-либо другой вид "опорной точки" в файле. Если значение указателя_в_файле или указателя_в_ключе выходят за разрешенные пределы или в файле нет подходящих по значениям записей, возникает ошибка "Запись не найдена".
Возвращаемые ошибки:
35 Запись не найдена
37 Файл еще не открыт
43 Запись уже заблокирована
Пример:
Customer FILE,DRIVER('Clarion'),PRE(Cus)
NameKey KEY(Cus:Name),OPT
NbrKey KEY(Cus:Number),OPT
Rec RECORD
Name STRING(20)
Number SHORT
. .
CODE
Cus:Name = 'Clarion' !Инициализируем ключевое поле
GET(Customer,Cus:NameKey) ! получаем соответствующую запись
IF ERRORCODE() THEN STOP(ERROR()).
GET(Customer,3) !Читаем третью физическую запись
! файла
IF ERRORCODE() THEN STOP(ERROR()).
GET(Cus:NameKey,3) !Получаем третью запись в порядке,
! задаваемом ключом NameKey
IF ERRORCODE() THEN STOP(ERROR()).
См. также: ,
Файлы данных
(описание структуры файла данных)
(разрешает создание файла)
(задает тип файла данных)
(шифровать файл данных)
(задает пароль для шифрования файла данных)
(использовать место от удаленных записей)
(описывает статический индекс для файла)
(описывает динамический индекс (ключ) для файла)
(описывает текстовое поле)
(описывает структуру записи)
(MEMO содержит двоичные данные)
(разрешить повторяющиеся значения полей ключа)
(KEY или INDEX - НЕ чувствительны к регистру)
(пустые или нулевые ключевые поля отбрасываются)
(построить ключи и/или индексы для файла)
(закрыть файл данных)
(копировать файл данных)
(создать пустой файл данных)
(очистить файл данных)
(сбросить буфера ДОС на диск)
(монопольный доступ к файлу)
(открыть файл данных)
(физически стереть удаленные записи)
(стереть файл данных)
(переименовать файл данных)
(открыть файл данных)
(разрешить буферизацию через ДОС)
(разблокировать заблокированный файл)
(добавить новую запись)
(добавить новую запись)
(удалить запись)
(считать запись по прямому доступу)
(монопольный доступ к записи)
(прочитать следующую запись последовательности)
(прочитать предыдущую запись последовательности)
(записать запись обратно в файл)
(освободить заблокированную запись)
(сброс указателя текущей записи)
(инициировать последовательную обработку файла)
(пропустить записи в последовательности)
(начало файла)
(размер файла в байтах)
(проверить на дублирование ключевых полей)
(конец файла)
(относительный номер записи)
(номер записи в последовательности)
(число записей)
(отправить сообщение файловому драйверу)
(завершить успешно проведенную транзакцию)
(начать транзакцию)
(завершить ошибочную транзакцию)
HOLD (монопольный доступ к записи)
HOLD(файл[,секунды])
файл | Метка файла, открытого для совместного доступа. |
seconds | Числовая константа или переменная, которая задает максимальное время ожидания в секундах. |
Оператор HOLD включает блокирование записи для следующих за ним операторов GET, NEXT или PREVIOUS в многопользовательской среде. Когда GET, NEXT или PREVIOUS успешно захватывают запись, они выставляют флажок "held" (заблокирована). Обычно это не дает остальным пользователям изменять эту запись, но не мешает читать ее. Конкретное действие HOLD зависит от файлового драйвера.
HOLD(файл) | Запускает процесс блокировки так, что последующие GET, NEXT или PREVIOUS пытаются захватить запись до тех пор, пока это не удастся. Если запись уже захвачена другой рабочей станцией, то эти операторы будут ожидать освобождения этой записи. |
HOLD(файл,секунды) | Запускает процесс так, что последующие GET, NEXT или PREVIOUS вернут ошибку "Запись уже заблокирована", если за заданное число секунд они не смогут захватить ее. |
В один момент времени только одна запись в каждом файле может быть заблокирована. Если происходит обращение к другой записи этого файла, то захваченная ранее запись автоматически освобождается.
Так же как и для LOCK, существует проблема "смертельного объятия". Оно возникает когда две рабочих станции пытаются захватить один и тот же нвбор записей, но в разной последовательности и обе они используют оператор HOLD(файл). Одна станция уже захватила запись, которую пытается захватить другая и наоборот. Этой проблемы можно избежать, используя оператор HOLD(файл,секунды) и отслеживая возникновение ошибки "Запись уже заблокирована".
Пример:
LOOP !Цикл во избежание "смертельного
! объятия"
HOLD(Master,1) !1 секунду пытаемся захватить запись глав-
! ного файла
GET(Master,1) !Читаем и блокируем запись
IF ERRORCODE() = 208 !Если кто-то уже захватил ее, то
BEEP(0,100); CYCLE ! подождем секунду и попробуем
! снова
.
HOLD(Detail,1) !1 секунду пытаемся захватить запись из
! файла подробностей
GET(Detail,1) !Читаем и блокируем запись
IF ERRORCODE() = 208 !Если кто-то уже захватил ее, то
RELEASE(Master) ! освободим захваченную ранее,
BEEP(0,100); CYCLE ! подождем секунду и попробуем
! снова
. . !Конец операторов IF и LOOP
См. также: , , ,
INDEX (описывает статический индекс для файла)
метка INDEX([-][field])[NAME()][,NOCASE][,OPT]
- | Знак МИНУС перед компонентой индекса означает, что для полей с этой компонентой, индекс сортируется по убыванию (от больших значений к меньшим), по умолчанию сортировка по возрастанию. |
field | Метка поля из структуры RECORD файла, для которого строится индекс. Поле - это компонента индекса. Переменные с атрибутом DIM (массивы) нельзя использовать в качестве индексных полей. |
NAME | Имя файла для индекса. |
OPT | В индекс не попадут сведения о тех записях, у которых все поля, используемые как компоненты индекса, пусты или содержат нуль. |
NOCASE | Сортировку проводить без учета регистра. |
INDEX описывает "статичный" ключ для файла данных. INDEX обновляется только оператором BUILD. Он используется для доступа к записям в порядке, отличном от физического размещения записей в файле. INDEX можно использовать как для последовательного, так и для произвольного доступа к файлу. В INDEX-е ВСЕГДА разрешены записи с одинаковым значением индексных полей (duplicated entries).
INDEX может строиться на основании более чем одного поля. Порядок, в котором заданы компоненты индекса, определяет порядок сортировки записей по этому индексу. Самые первые компоненты МЕНЕЕ значимы, самые последние - БОЛЕЕ. В общем, файл данных может иметь до 255 индексов (и/или ключей) и каждый индекс может быть длиной до 255 байт (имеется в виду суммарная длина всех полей, задействованных для построения индекса), хотя точное число индексных и ключевых файлов зависит от файлового драйвера.
Если в описании INDEX не заданы имена полей, то создается "динамический" индекс, который позволяет использовать любые поля структуры RECORD в качестве своих компонент, за исключением массивов. Такие компоненты задаются во время исполнения вторым параметром оператора BUILD. Такой подход позволяет произвольно индексировать файлы во время исполнения (С.П.А - и позволяет избежать одинаковых, в целом, процедур, использующих разные порядки сортировки одного и того же файла).
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameNdx INDEX(Nam:Name),NOCASE !Индекс по имени
NbrNdx INDEX(Nam:Number),OPT !Индекс по номеру
Rec RECORD
Name STRING(20)
Number SHORT
. .
См. также: ,
KEY (описывает динамический индекс (ключ) для файла)
метка KEY([-][field])[NAME()][,NOCASE][,OPT]
- | Знак МИНУС перед компонентой ключа означает, что для полей с этой компонентой, индекс сортируется по убыванию (от больших значений к меньшим), по умолчанию сортировка по возрастанию. |
field | Метка поля из структуры RECORD файла, для которого строится ключ. Поле - это компонента ключа. Переменные с атрибутом DIM (массивы) нельзя использовать в качестве ключевых полей. |
NAME | Имя файла для ключа. |
OPT | В ключ не попадут сведения о тех записях, у которых все поля, используемые как компоненты ключа, пусты или содержат нуль. |
NOCASE | Сортировку проводить без учета регистра. |
DUP | В файле данных разрешены записи с одинаковыми значениями ключевых полей. |
KEY - это индекс файла данных, который автоматически обновляется при добавлении, изменении или удалении записей. Он используется для доступа к записям в порядке, отличном от физического размещения записей в файле. INDEX можно использовать как для последовательного, так и для произвольного доступа к файлу.
KEY может строиться на основании более чем одного поля. Порядок, в котором заданы компоненты ключа, определяет порядок сортировки записей по этому индексу. Самые первые компоненты МЕНЕЕ значимы, самые последние - БОЛЕЕ. В общем, файл данных может иметь до 255 ключей (и индексов) и каждый ключ может быть длиной до 255 байт (имеется в виду суммарная длина всех полей, задействованных для построения ключа), хотя точное число ключевых и индексных файлов зависит от файлового драйвера.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name),NOCASE,DUP !Ключ по имени
NbrKey KEY(Nam:Number),OPT !Ключ по номеру
Rec RECORD
Name STRING(20)
Number SHORT
CODE
Nam:Name = 'Clarion Software' !Инициализируем ключевое
! поле
GET(Names,Nam:NameKey) !Читаем запись
SET(Nam:NbrKey) !Обрабатывать в порядке
! возрастания поля
! NAM:NUMBER
См. также: , ,
LOCK (монопольный доступ к файлу)
LOCK(файл[,секунды])
файл | Метка файла, открытого для совместного доступа. |
секунды | Числовая константа или переменная, которая задает максимальное время ожидание в секундах. |
Оператор LOCK блокирует файл от доступа к нему других рабочих станций в многопользовательской среде. Обычно, это блокирует запись в файл или его чтение другими пользователями. Конкретная работа оператора LOCK зависит от файлового драйвера.
LOCK(файл) | Пытается заблокировать файл до тех пор, пока это не удастся. Если файл уже заблокирован другой станцией, то LOCK будет ждать, пока та станция не разблокирует файл. |
LOCK(файл,секунды) | Если за заданное время не удалось заблокировать файл, то возвращается ошибка "Файл уже заблокирован". |
Главная проблема с блокированными файлами, это как избежать "смертельного объятия". Это происходит, когда две станции пытаются заблокировать один и тот же набор файлов в разной последовательности, и обе используют оператор LOCK(файл). Одна станция уже заблокировала файл, который хочет заблокировать другая, и наоборот. Этой проблемы можно избежать, если использовать оператор LOCK(файл,секунды) и всегда блокировать файлы в одном и том же порядке.
Возвращаемые ошибки:
32 Файл уже заблокирован
Пример:
LOOP !Цикл во избежание "смертельного
! объятия"
LOCK(Master,1) !1 секунду пытаемся заблокировать
! основной файл
IF ERRORCODE() = 201 !Если кто-то уже блокирует его, то
BEEP(0,100) ! ждем секунду и
CYCLE ! пытаемся снова...
.
LOCK(Detail,1) !За секунду пытаемся заблокировать
! файл подробностей
IF ERRORCODE() = 201 !Если кто-то уже блокирует его, то
UNLOCK(Master) ! разблокируем занятый нами файл,
BEEP(0,100) ! подождем секунду и
CYCLE ! еще разок попробуем
. . !Конец операторов IF и LOOP
LOGOUT (начать транзакцию)
LOGOUT(таймаут,файл[,файл,...,файл])
таймаут | Числовая константа или переменная, задающая сколько секунд пытаться начать транзакцию для файла(ов), прежде чем прервать ее и вернуть ошибку. |
файл | Метка файла. Можно задать сразу несколько параметров ФАЙЛ, разделенных запятыми. Должны быть перечислены все файлы, участвующие в транзакции. |
Оператор LOGOUT начинает обработку транзакции для заданного файла или набора файлов. Все задействованные файлы должны работать с одним и тем же файловым драйвером. LOGOUT сообщает драйверу о начале транзакции. Драйвер, в свою очередь, выполняет действия, необходимые в его файловой системе для начала обработки транзакции в заданном наборе файлов. Если файловая система требует, чтобы файлы были заблокированы перед началом транзакции, то LOGOUT автоматически блокирует их (для этого и нужен ТАЙМАУТ).
Только одна транзакция, инициированная через LOGOUT, может выполняться одновременно. Второй LOGOUT (без предварительного COMMIT или ROLLBACK) останавливает программу с сообщением об ошибке и вываливается в DOS.
Возвращаемые ошибки:
32 Файл уже заблокирован
Пример:
LOGOUT(,1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailQue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
См. также: ,
MEMO (описывает текстовое поле)
метка MEMO(длина)[,BINARY][,NAME()]
длина | Числовая константа, задающая максимальную длину текста в символах. Должна быть в диапазоне от 1 до 65,536 байт. |
BINARY | Указывает, что в МЕМО-поле должны храниться двоичные данные. |
NAME | Задает имя файла, в котором будут находиться МЕМO-поля. Использование этого параметра зависит от файлового драйвера. |
(МЕМО - англ. записка, памятка, примечание)
MEMO описывает строковое поле переменной длины, которое хранится на диске. Параметр ДЛИНА задает максимальный размер поля примечаний. МЕМО должно быть описано ПОСЛЕ описания структуры RECORD. Память под буфер МЕМО-полей выделяется при открытии файла, к которому это примечание относится, и освобождается при его закрытии.
Теоретически, можно описать до 255 МЕОМ-полей для каждого файла. Точное же их число и способ их хранения на диске зависит от файлового драйвера. Просматриваются MEMO-поля, обычно, с помощью полей типа TEXT в экранах и отчетах.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name)
NbrKey KEY(Nam:Number)
Notes MEMO(4800) !Примечание длиной до 4800 байт.
Rec RECORD
Name STRING(20)
Number SHORT
. .
NEXT (прочитать следующую запись последовательности)
NEXT(файл)
файл | Метка файла. |
NEXT читает из файла данных следующую, в ранее заданной последовательности, запись и заносит ее в буфер структуры RECORD. Оператор SET устанавливает последовательность, в которой будут считываться записи. Первый NEXT, выполнившийся сразу после SET, читает запись в позиции, установленной оператором SET. Последующие NEXT-ы читают следующие записи в этой последовательности. Последовательность не изменяется операторами GET, ADD, PUT или DELETE.
Выполнение NEXT, перед которым не был выполнен SET, или попытка считать запись после конца файла, приводит к ошибке "Запись недоступна".
Возвращаемые ошибки:
33 Запись недоступна
37 Файл еще не открыт
43 Запись уже заблокирована
Пример:
SET(Cus:NameKey) !Начинаем с начала файла, последова-
! тельность задается ключом NameKey.
LOOP UNTIL EOF(Customer) !Читаем все, что можно, до конца фай-
! ла
NEXT(Customer) ! последовательно читаем записи
IF ERRORCODE() THEN STOP(ERROR()).
DO PostTrans ! вызываем процедуру обслуживания
! транзакций.
. !Конец цикла
См. также: , , ,
NOCASE (KEY или INDEX - НЕ чувствительны к регистру)
NOCASE
Атрибут NOCASE в описании KEY или INDEX означает, что сортировка полей по алфавиту будет производиться без учета регистра букв. При записи в ключевой файл, все буквы будут приводиться к верхнему регистру. Этот атрибут не влияет на данные, хранящиеся в файле данных и на не буквы.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name),NOCASE
!Ключ по имени без учета регистра
NbrKey KEY(Nam:Number) !Ключ по номеру
Rec RECORD
Name STRING(20)
Number SHORT
. .
См. также: ,
OPEN (открыть файл данных)
OPEN(файл[,режим доступа])
файл | Метка файла. |
режим доступа | Числовая константа, переменная или выражение, задающее уровень доступа к файлу как для открывающего его пользователя, так и для остальных пользователей многопользовательской системы. Если пропущен, то подразумевается 22h (всем, кроме меня запрещена запись в этот файл) |
Оператор OPEN открывает структуру FILE для обработки и устанавливает режим доступа. Поддержка различных уровней доступа зависит от файлового драйвера. Все файлы должны быть явно открыты перед их использованием. РЕЖИМ ДОСТУПА это битовая карта, указывающая операционке, какой доступ предоставить открывающему пользователю, и какой доступ запретить для остальных потенциальных пользователей этого файла. Допустимы следующие значения режима доступа:
Открывающий пользователь | 0 | 0h | Только для чтения (Read Only) |
1 | 1h | Только для записи (Write Only) | |
2 | 2h | Для чтения и записи (Read/Write) | |
Остальные пользователи | 0 | 0h | Любой доступ (режим FCB-совместимости) |
16 | 10h | Запрещен любой доступ (Deny All) | |
32 | 20h | Запрещена запись (Deny Write) | |
48 | 30h | Запрещено чтение (Deny Read) | |
64 | 40h | ??? (Deny None) |
Возвращаемые ошибки:
02 Файл не найден
04 Слишком много открытых файлов
05 Доступ запрещен
52 Файл уже открыт
75 Неверный описатель типа поля
Пример:
ReadOnly EQUATE(0) !Мнемонические значения для режимов
WriteOnly EQUATE(1) ! доступа
ReadWrite EOUATE(2)
DenyAll EQUATE(10h)
DenyWrite EQUATE(20h)
DenyRead EQUATE(30h)
DenyNone EQUATE(40h)
CODE
OPEN(Names,ReadWrite+DenyNone) !Открываем полностью в
! режиме разделения.
См. также:
OPT (пустые или нулевые ключевые поля отбрасываются)
OPT
Если задан атрибут ОРТ, то в ключ или индекс НЕ попадут сведения о записях, у которых все ключевые поля пусты. В терминах атрибута ОРТ, "пустое поле" означает, что числовое поле содержит нуль, а символьное - только пробелы.
Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)!Описание структуры файла
NameKey KEY(Nam:Name),OPT !Ключ по имени, имя не может быть
! пустым
NbrKey KEY(Nam:Number),OPT !Ключ по номеру. Номера не могут
! быть нулевыми
Rec RECORD
Name STRING(20)
Number SHORT
. .
См. также: ,
OWNER (задает пароль для шифрования файла данных)
OWNER(password)
password | Строковая константа или переменная. |
Атрибут OWNER задает пароль, который используется атрибутом ENCRYPT для шифрования данных. Реализация метода шифрования зависит от конкретного файлового драйвера.
Пример:
Customer FILE,DRIVER('Clarion'),OWNER('abCdeF'),ENCRYPT
!Шифруем данные с
!паролем "abCdeF"
Record RECORD
Name STRING(20)
. .
См. также:
PACK (физически стереть удаленные записи)
PACK(файл)
файл | Метка файла. |
Оператор PACK убирает удаленные записи из файла данных и перестраивает его ключи. Полученный файл будет компактен, насколько это возможно. PACK требует, как минимум, вдвое больше места на диске, чем занимает файл с ключами и МЕМО-файлами. Новые файлы создаются из старых, а старые файлы стираются ТОЛЬКО после успешного завершения процесса. PACK требует монопольного доступа к файлу.
Возвращаемые ошибки:
63 Требуется монопольный доступ
Пример:
OPEN(Trans,12h) !Монопольно открывает файл и
PACK(Trans) ! упаковывает его.
См. также: ,
POINTER (относительный номер записи)
POINTER(файл)
ключ
файл | Метка файла. Этим указывается на физическое расположение записей в файле. |
ключ | Метка ключа или индекса. Это указывает на порядок записей, задаваемый ключом или индексом. |
POINTER возвращает относительный номер записи в файле или в последовательности либо относительное положение указателя на запись в ключе или индексе (в последовательности "по ключу"). Значение, возвращаемое функцией, зависит от файлового драйвера. Это может быть номер записи, относительный номер байта в файле или какой-либо другой вид "опорной точки в файле".
Тип возвращаемого результата: LONG
Пример:
SavePtr# = POINTER(Customer) !Сохраняем указатель на запись
См. также:
POSITION (номер записи в последовательности)
POSITION(последовательность)
последовательность | Метка файла, ключа или индекса. |
POSITION возвращает строку, которая идентифицирует уникальный номер записи в последовательности. POSITION возвращает положение в файле последней записи, к которой происходило обращение (то есть содержимое записи находится в буфере структуры RECORD).
Значение и длина возвращаемой строки зависят от файлового драйвера. POSITION используется совместно с RESET для временного изменения порядка обработки записей, и, затем, его восстановления.
Тип возвращаемого результата: STRING
Пример:
RecordQue QUEUE,PRE(Dsp)
QueFields LIKE(Trn:Record),PRE(Dsp)
.
SavPosition STRING(260)
CODE !От начала файла идем по ключу
SET(Trn:DateKey) !Последовательно читаем
LOOP ! все записи
NEXT(Trans)
IF ERRORCODE() THEN STOP(ERROR()).
RecordOue = Trn:Record !Добавляем запись в
ADD(RecordQue) ! очередь
IF ERRORCODE() THEN STOP(ERROR()).
IF RECORDS(RecordOue) >= 20 OR EOF(Trans)
!если в очереди 20 записей, то
SavPosition = POSITION(Trn:DateKey) !сохраняем номер теку-
! щей записи,
DO DisplayQue !показываем очередь и
FREE(RecordQue) ! очищаем ее
IF EOF(Trans) THEN BREAK.
!Если все записи обработаны, то
! заканчиваем работу
RESET(Trn:DateKey,SavPosition) !Восстанавливаем указатель
. . !Конец цикла
См. также:
PREVIOUS (прочитать предыдущую запись последовательности)
PREVIOUS(файл)
файл | Метка файла. |
PREVIOUS читает из файла данных предыдущую, в ранее заданной последовательности, запись и заносит ее в буфер структуры RECORD. Оператор SET устанавливает последовательность, в которой будут считываться записи. Первый PREVIOUS, выполнившийся сразу после SET, читает запись в позиции, установленной оператором SET. Последующие PREVIOUS-ы :) читают следующие записи этой последовательности В ОБРАТНОМ ПОРЯДКЕ. Последовательность не изменяется операторами GET, ADD, PUT или DELETE.
Выполнение PREVIOUS, перед которым не был выполнен SET, или попытка считать запись перед началом файла, приводит к ошибке "Запись недоступна".
Возвращаемые ошибки:
33 Запись недоступна
37 Файл еще не открыт
43 Запись уже заблокирована
Пример:
SET(Trn:DateKey) !Устанавливаем последовательность обра-
! ботки записей
LOOP UNTIL BOF(Trans) !Читаем все записи в обратном порядке
PREVIOUS(Trans) ! читаем записи последовательно
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut ! вызываем процедуру LIFO
. !Конец цикла
См. также: , , ,
PUT (записать запись обратно в файл)
PUT(файл[,указатель_в_файле][,длина])
файл | Метка файла. |
указатель_в_файле | Числовая константа, переменная или выражение, содержащая значение, возвращаемое функцией POINTER(файл). Конкретное значение зависит от файлового драйвера. |
длина | Целочисленная константа, переменная или выражение, содержащее число байт, записываемых в файл. ДЛИНА должная быть больше нуля но не больше длины структуры RECORD. Если ДЛИНА пропущена или выходит за разрешенный диапазон, то она сбрасывается до длины структуры RECORD. |
Оператор PUT записывает содержимое буфера RECORD в последнюю запись, к которой производилось обращение.
PUT(файл) | Записывает запись в то место, к которому последний раз обращались NEXT, PREVIOUS, GET, или ADD. Если изменились значения ключевых полей, то ключи (НЕ индексы!) обновляются. |
PUT(файл,указатель_в_файле) | Записывает запись в то место, на которое указывает указатель_в_файле и обновляет ключи. |
PUT(файл,указатель_в_файле,длина) | Записывает ДЛИНА байтов в то место, на которое указывает указатель_в_файле и обновляет ключи. |
Если к записи не было обращения операторами NEXT, PREVIOUS, GET и ADD или она была удалена, то возвращается ошибка "Запись недоступна". PUT также может вернуть ошибку "Такой ключ уже есть". При возникновении какой-либо ошибки файл не изменяется.
Возвращаемые ошибки:
05 Доступ запрещен
33 Запись недоступна
40 Такой ключ уже есть
Пример:
SET(Trn:DateKey) !End/Beginning of file in keyed sequence
LOOP UNTIL BOF(Trans) !Читаем все записи в обратном порядке
PREVIOUS(Trans) ! одну за другой
IF ERRORCODE() THEN STOP(ERROR()).
DO LastInFirstOut !Вызываем процедуру LIFO
PUT(Trans) !Записываем транзакцию обратно в файл
IF ERRORCODE() THEN STOP(ERROR()).
. !Конец цикла
См. также: , , ,
RECLAIM (использовать место от удаленных записей)
RECLAIM
Атрибут RECLAIM говорит о том, что файловый драйвер будет помещать новые записи в файл на место ранее удаленных, если таковые имеются. В противном случае запись будет добавлена в конец файла. Реализация метода RECLAIM зависит от файлового драйвера и поддерживается НЕ всем файловыми системами.
Пример:
Names FILE,DRIVER('Clarion'),RECLAIM !Помещать новые записи на
!место ранее удаленных.
Record RECORD
Name STRING(20)
. .
RECORD (описывает структуру записи)
[метка] RECORD[PRE()][,NAME()]
поля
.
поля | Одно или более описание переменных. |
PRE | Задает метку-префикс структуры. |
NAME | Задает внешнее имя структуры RECORD. Использование этого параметра зависит от файлового драйвера. |
Оператор RECORD описывает начало структуры файла данных. Структура RECORD обязательно должна быть в описании файла. Каждое ПОЛЕ элемент структуры RECORD. Длина структуры RECORD складывается из длин входящих в нее ПОЛЕЙ. При обращении к структуре RECORD, она рассматривается, как структура типа GROUP.
Во время исполнения, под данные
структуры RECORD, выделяется буфер в статической памяти. ПОЛЯ, в буфере записи, дрступны независимо от того открыт файл или нет. Записи считываются в буфер из файла операторами NEXT, PREVIOUS или GET. Данные ПОЛЕЙ обрабатываются, а затем записываются в файл в виде цельной структуры RECORD операторами ADD, PUT или DELETE.
Пример:
Names FILE,DRIVER('Clarion') !Описание структуры файла
Record RECORD ! начало описания записи
Name STRING(20) ! описываем поле ИМЯ
Number SHORT ! описываем поле НОМЕР
. . !Конец описаний записи и файла
RECORDS (число записей)
RECORDS(файл)
ключ
файл | Метка файла. |
ключ | Метка ключа или индекса. |
Эта функция количество записей в файле или ключе. Поскольку атрибут OPT для ключа или индекса не дает заносить в них данные о записях, у которых ключевые поля пусты, то RECORDS может вернуть для ключа или индекса меньшее значение чем для файла, к которому они принадлежат.
Тип возвращаемого результата: LONG
Пример:
SaveCount = RECORDS(Master) !Сохраняем количество записей
SaveNameCount = RECORDS(Nam:NameKey)
!Число карточек, в которых заполнено
! поле NAME
См. также: , ,
RELEASE (освободить заблокированную запись)
RELEASE(файл)
файл | Метка файла. |
Оператор RELEASE освобождает захваченную ранее запись. Он не может освободить запись, захваченную другим пользователем. Если запись не захвачена или захвачена другим пользователем, то этот оператор игнорируется.
Пример:
LOOP !Цикл во избежание "смертельного объятия"
HOLD(Master,1) !1 секунду пытаемся захватить главный файл
GET(Master,1) !получаем и блокируем запись
IF ERRORCODE() = 208 !если кто-то успел раньше нас, то
BEEP(0,100) ! секунду подождем
CYCLE ! и попробуем еще раз
.
HOLD(Detail,1) !1 секунду пытаемся захватить файл
! подробностей
GET(Detail,1) !получаем и блокируем запись
IF ERRORCODEO = 208 !если кто-то успел раньше нас, то
RELEASE(Master) ! осободим запись, захваченную ранее
BEEP(0,100) ! секунду подождем
CYCLE ! и попробуем еще раз
. . !Конец операторов IF и LOOP
REMOVE (стереть файл данных)
REMOVE(файл)
файл | Метка файла, подлежащего удалению. |
Оператор REMOVE стирает заданный файл из каталога аналогично команде ДОС Delete. Файл должен быть закрыт, иначе будет ошибка "Файл уже открыт". При возникновении какой-либо ошибки файл НЕ удаляется.
Возвращаемые ошибки:
02 Файл не найден
05 Доступ запрещен
52 Файл уже открыт
Пример:
REMOVE(OldFile) !Удаляем старый файл
REMOVE(Changes) !Удаляем файл изменений
RENAME (переименовать файл данных)
RENAME(файл,новый_файл)
файл | Метка переименовываемого файла. |
новый_файл | Строковая константа или переменная, содержащая спецификацию файла. Если в спецификации не заданы диск и путь, то используется текущий каталог текущего диска. Если указан только путь, то в качестве имени и расширения нового файла используются имя и расширение оригинала. Файл не может быть переименован на другой диск. |
Оператор RENAME либо меняет имя файла, либо переносит его в другой каталог на этом же диске. Файл, подлежащий переименованию, должен быть закрыт, иначе произойдет ошибка "Файл уже открыт". Если ФАЙЛ и НОВЫЙ_ФАЙЛ идентичны, то оператор RENAME игнорируется. При возникновении какой-либо ошибки, файл не переименовывается.
Поскольку некоторые файловые драйверы используют несколько физических ФАЙЛОВ для работы с ними как с ОДНИМ ФАЙЛОМ, то подразумеваемые имя и расширение файла зависят от файлового драйвера.
Возвращаемые ошибки:
02 Файл не найден
03 Путь не существует
05 Доступ запрещен
52 Файл уже открыт
Пример:
RENAME(Text,'text.bak') !Делаем резервную копию
RENAME(Master,'\newdir') !Перемещаем в другой каталог
RESET (сброс указателя текущей записи)
RESET(последовательность,строка)
последовательность | Метка файла, ключа или индекса. |
строка | Строка, возвращаемая функцией POSITION. |
RESET устанавливает указатель записи на запись, задаваемую строкой, возвращаемой функцией POSITION. После того, как RESET установил указатель, NEXT или PREVIOUS могут считать эту запись.
Значение, содержащееся в СТРОКЕ, и его длина зависят от файлового драйвера. RESET, обычно, используется вместе с POSITION для временного изменения порядка обработки записей.
Пример:
RecordQue QUEUE,PRE(Dsp)
QueFields LIKE(Trn:Record),PRE(Dsp)
.
SavPosition STRING(260)
CODE
SET(Trn:DateKey) !Top of file in keyed sequence
LOOP !Последовательно читаем
NEXT(Trans) ! записи, одну за другой
IF ERRORCODE() THEN STOP(ERROR()).
RecordQue = Trn:Record !Помещаем запись в очередь
ADD(RecordQue) !
IF ERRORCODE() THEN STOP(ERROR()).
IF RECORDS(RecordQue) >= 20 OR EOF(Trans)
!В очереди 20 записей?
SavPosition = POSITION(Trn:DateKey) !сохраним указатель
!на текущую запись
DO DisplayQue !Выведем очередь на экран
FREE(RecordQue) ! и очистим ее
IF EOF(Trans) THEN BREAK.
!Если обработаны все записи, то выходим
RESET(Trn:DateKey,SavPosition) !Сбрасываем указатель
. . !Конец цикла
См. также: , ,
ROLLBACK (завершить ошибочную транзакцию)
ROLLBACK
Оператор ROLLBACK завершает текущую транзакцию как и COMMIT. Выполнение оператора ROLLBACK подразумевает, что транзакция прошла НЕВЕРНО и база данных нуждается в восстановлении в то состояние, в котором она была до транзакции.
ROLLBACK сообщает файловому драйверу, участвующему в транзакции, о том, что временные файлы, необходимые для возвращения базы в первоначальное состояние, должны быть использованы для восстановления базы. Драйвер, в свою очередь, выполняет действия, которые необходимы в его файловой системе для отката транзакции.
Пример:
LOGOUT(,1,OrderHeader,OrderDetail) !Начинаем транзакцию
DO ErrHandler ! нет ли ошибок?
ADD(OrderHeader) !Добавим запись о родителе
DO ErrHandler ! нет ли ошибок?
LOOP X# = 1 TO RECORDS(DetailQue)
!Обработка сохраненных подробностей
GET(DetailQue,X#) !Читаем одну из очереди
DO ErrHandler ! нет ли ошибок?
Det:Record = DetailQue !Помещаем в буфер записи
ADD(OrderDetail) ! и добавляем ее в файл
DO ErrHandler ! нет ли ошибок?
.
COMMIT !Завершаем успешную транзакцию
ErrHandler ROUTINE !Обработчик ошибок
IF NOT ERRORCODE() THEN EXIT. !Ошибок нет? Вернемся.
ROLLBACK !Отмена прерванной транзакции
BEEP !Предупреждаем пользователя
SHOW(25,1,'Ошибка транзакции - ' & ERROR())
ASK ! и ждем нажатия клавиши
RETURN ! затем возвращаемся
См. также: ,
SEND (отправить сообщение файловому драйверу)
SEND(файл,сообщение)
файл | Метка файла. Атрибут файла DRIVER идентифицирует файловый драйвер, которому адресовано сообщение. |
сообщение | Строковая константа или переменная, содержащая информацию, передаваемую драйверу. |
Функция SEND позволяет программе передать файловому драйверу, во время выполнения, специфичные параметры. Примеры таких специфичных параметров приведены в документации на драйвер.
Тип возвращаемого результата: STRING
Пример:
FileCheck = SEND(ClarionFile,'RECOVER=120')
!Запустить восстановление для файла
! в стандарте Кларион
SET (инициировать последовательную обработку файла)
файл
SET( файл,ключ )
файл,указатель_в_файле
ключ
ключ,ключ
ключ,указатель_в_ключе
ключ,ключ,указатель_в_файле
файл | Метка файла. Этот параметр указывает на то, что обработка происходит в том порядке, в котором записи физически расположены в файле. |
ключ | Метка ключа или индекса. Если этот параметр стоит первым, то обработка происходит в последовательности, задаваемой ключом или индексом. |
указатель_в_файле | Числовая константа, переменная или выражение, для значения, возвращаемого функцией POINTER(файл). Конкретное значение зависит от файлового драйвера. |
указатель_в_ключе | Числовая константа, переменная или выражение, для значения, возвращаемого функцией POINTER(ключ). Конкретное значение зависит от файлового драйвера. |
SET инициирует последовательную обработку файла. SET НЕ считывает запись, а только устанавливает порядок обработки и начальную точкц для последующих операторов NEX или PREVIOUS. Первый параметр определяет порядок обработки записей. Второй и третий - задают первую обрабатываемую запись (начальную точку обработки). Если они опущены, то обработка начнется с начала (или конца) файла.
SET(файл) | Задает обработку в физической последовательности с начала (SET .. NEXT) или конца (SET ..PREVIOUS) файла. |
SET(файл,ключ) | Обработка в физическом порядке, начиная с первой записи, значения ключевых полей которой, ближе всего подходят к установленным ранее значениям компонент ключа. |
SET(файл,указатель_в_файле) | Обработка в физическом порядке, начиная с записи, на которую указывает указатель_в_файле. |
SET(ключ) | Обработка в последовательности, задаваемой ключом, с начала (SET..NEXT) или конца (SET ..PREVIOUS) файла в этой последовательности. |
SET(ключ,ключ) | Обработка в последовательности, задаваемой ключом, начиная с записи, значения ключевых полей которой, наиболее близки к установленным значениям компонент ключа. |
SET(ключ,указатель_в_ключе) | Обработка в последовательности, задаваемой ключом, начиная с записи, на которую указывает указатель_в_ключе. |
SET(ключ, ключ, указатель_в_файле) | Обработка по ключу, начиная с записи, содержащей данные, наиболее близкие к содержимому компонент ключа в (с - ?) конкретной записи, задаваемой указателем_в_файле. |
Если второй параметр - ключ, то обработка начнется с первой записи, содержащей значения, наиболее близкие к значениям компонент ключа или индекса. Если найдено ТОЧНОЕ совпадение, то и NEXT и PREVIOUS считают найденную запись. Если нет точного совпадения, то NEXT прочитает запись с ближайшим БОЛЬШИМ значением, а PREVIOUS - с ближайшим меньшим.
Значения указателя_в_файле и указателя_в_ключе зависят от файлового драйвера. Это может быть номер записи, относительный номер байта в файле или какой либо иной вид "опорной точки" в файле. Эти параметры используются для начала обработки с конкретной записи в файле.
Пример:
SET(Customer) !Обработка в физическом порядке
Cus:Name = 'Smith'
SET(Customer,Cus:NameKey)
!Обработка в физическом порядке, начиная с записи, в
! которой поле Name = 'Smith'
SavePtr = POINTER(Customer)
SET(Customer,SavePtr)
!Обработка в физическом порядке, начиная с записи,
! физический номер которой хранится в SavePtr
SET(Cus:NameKey)
!Обработка в порядке, задаваемом ключом NameKey
SavePtr = POINTER(Cus:NameKey)
SET(Cus:NameKey,SavePtr)
!Обработка в порядке, задаваемом ключом NameKey, с за-
! писи, относительный номер которой в ключе содержит
! SavePtr
Cus:Name = 'Smith'
SET(Cus:NameKey,Cus:NameKey)
!Обработка в порядке, задаваемом ключом NameKey, начи-
! ная с первой записи, в которой поле = 'Smith'
Cus:Name = 'Smith'
SavePtr = POINTER(Customer)
SET(Cus:NameKey,Cus:NameKey,SavePtr)
!Обработка в порядке, задаваемом ключом NameKey,
! Name = 'Smith' и номер записи = SavePtr
См. также: , , , ,
SHARE (открыть файл данных)
SHARE(файл[,режим доступа])
файл | Метка файла. |
режим доступа | Числовая константа, переменная или выражение, задающее уровень доступа к файлу как для открывающего его пользователя, так и для остальных пользователей многопользовательской системы. Если пропущен, то подразумевается 42h (всем, кроме меня, DENY NONE). |
Оператор SHARE открывает файл для обработки и устанавливает режим доступа к нему. Оператор SHARE аналогичен оператору OPEN и отличается от него только режимом доступа по умолчанию. РЕЖИМ ДОСТУПА это битовая карта, указывающая операционке, какой доступ предоставить открывающему пользователю, и какой доступ запретить для остальных потенциальных пользователей этого файла. Допустимы следующие значения режима доступа:
Открывающий пользователь | 0 | 0h | Только для чтения (Read Only) |
1 | 1h | Только для записи (Write Only) | |
2 | 2h | Для чтения и записи (Read/Write) | |
Остальные пользователи | 0 | 0h | Любой доступ (режим FCB-совместимости) |
16 | 10h | Запрещен любой доступ (Deny All) | |
32 | 20h | Запрещена запись (Deny Write) | |
48 | 30h | Запрещено чтение (Deny Read) | |
64 | 40h | ??? (Deny None) |
Возвращаемые ошибки:
02 Файл не найден
04 Слишком много открытых файлов
05 Доступ запрещен
52 Файл уже открыт
75 Неверный описатель типа поля
Пример:
ReadOnly EQUATE(0) !Мнемонические значения для режимов
WriteOnly EQUATE(1) ! доступа
ReadWrite EOUATE(2)
DenyAll EQUATE(10h)
DenyWrite EQUATE(20h)
DenyRead EQUATE(30h)
DenyNone EQUATE(40h)
CODE
SHARE(Names,ReadOnly+DenyWrite) !Открываем в режиме толь-
! ко для чтения.
См. также:
SKIP (пропустить записи в последовательности)
SKIP(файл,count)
файл | Метка файла. |
count | Числовая константа или переменная. COUNT задает число пропускаемых записей. Если значение положительное, то записи пропускаются ВПЕРЕД (аналогично NEXT). Если же COUNT отрицательно, то записи пропускаются НАЗАД (аналогично PREVIOUS). |
Оператор SKIP используется для пропуска записей во время последовательной обработки файла. Он пропускает записи в порядке, задаваемом оператором SET, перемещая указатель записи в файле на COUNT записей вперед или назад. SKIP более эффективен, чем NEXT или PREVIOUS при пропуске нескольких записей, поскольку он НЕ считывает записи в буфер, отведенный под структуру RECORD.
Если SKIP пытается выйти за конец или начало файла, то функции EOF() и BOF() возвращают истину. Если ранее не был выполнен SET, то SKIP игнорируется.
Пример:
SET(Itm:InvoiceKey) !Начинаем от начала файла товаров
LOOP UNTIL EOF(Items) !Обрабатываем все записи
NEXT(Items) !Читаем запись
IF ERRORCODE() THEN STOP(ERROR()).
IF Itm:InvoiceNo <> SavinvNo !Если это первый товар в зака-
! зе, то
Hea:InvoiceNo = Itm:InvoiceNo !инициализируем ключевое
! поле и
GET(Header,Hea:InvoiceKey)
!получаем соответствующий ему за-
! головок столбца
IF ERRORCODE() THEN STOP(ERROR()).
IF Hea:InvoiceStatus = 'Cancel' !Если заказ отменен,
SKIP(Items,Hea:ltemCount-1) ! то пропускаем осталь-
! ные товары
CYCLE ! и обрабатываем следую-
! щий заказ
. . ! конец операторов IF
DO ItemProcess ! обрабатываем товар
SavInvNo = Itm:lnvoiceNo ! сохраняем номер счета
. !Конец цикла
STREAM (разрешить буферизацию через ДОС)
STREAM(файл)
файл | Метка файла. |
Некоторые файловые системы сбрасывают буфера при каждой записи на диск. Оператор STREAM запрещает это автоматический сброс. Буфера ДОС выделяются командой BUFFERS= в файле CONFIG.SYS. Они хранят записываемое на диск до тех пор, пока все буфера не заполнятся, а затем все сразу сбрасываются на диск. Элементы каталога обновляются только при физической записи буферов на диск. Операция STREAM завершается с закрытием файла, что автоматически сбрасывает буфера на диск, либо с выполнением оператора FLUSH.
Поддержка этого оператора зависит от файловой системы и описана в документации по файловому драйверу данной системы.
Пример:
STREAM(History) !Используем буфера ДОС
SET(Current) !Идем в начало файла CURRENT
LOOP UNTIL EOF(Current)
NEXT(Current)
His:Record - Cur:Record
ADD(History)
. !End loop
FLUSH(History) !Завершаем поточную обработку
! и сбрасываем буфера на диск
См. также:
UNLOCK (разблокировать заблокированный файл)
UNLOCK(файл)