Extra Systems Database

рекомендации сторонним разработчикам

ОБЩИЕ ЗАМЕЧАНИЯ

Этот документ описывает методы создания собственных программных модулей сторонними разработчиками для ESDB. Рекомендуется использовать в качестве базового уровня для своих модулей файл database.pas, который обеспечивает для вас API низкого уровня. Весь комплект базовой поставки для сторонних разработчиков включает в себя помимо файла database.pas также файлы common.pas (файл констант и базовых структур) и файл inet.pas (файл работы через TCP/IP).

Указанные три базовых файла (database.pas, common.pas и inet.pas) рекомендуется включать в свои разработки в полном составе и без изменений. Их можно включать как в виде исходных кодов, так и в виде объектных модулей. Такой подход рекомендуется из соображений совместимости, поскольку Extra Systems, разработчик ESDB, оставляет за собой право вносить изменения в эти файлы одновременно с внесением соответствующих изменений в сервер ESDB. В то же время, это требование не является обязательным: лицензионное соглашение ESDB допускает внесение изменений в указанные базовые файлы, а также полное или частичное включение кода этих файлов в любые ваши собственные клиентские приложения или компоненты для ESDB. (При этом потенциальный риск несовместимости таких разработок с новыми версиями сервера ESDB ложится целиком на сторонних разработчиков.)

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

Следует отметить, что разработчик ESDB открыт для любых предложений по поводу внесения необходимых дополнений в модуль database.pas, нужда в которых может возникнуть у того или иного строннего разработчика. Поэтому оптимальный путь, если вам чего-то не хватает - обратиться по этому поводу в Extra Systems, и если вам удастся убедить нас в необходимости того или иного дополнения, то мы бесплатно внесем новые процедуры и функции в базовый модуль database.pas, так что вы в будущем сможете быть уверены в том, что и в любой последующей поставке эти необходимые для вас процедуры и функции будут присутствовать и никуда не исчезнут.

МЕТОДЫ РАБОТЫ

Для работы с базой данных предназначен класс TDatabase, описанный в файле database.pas, примеры использования которого содержит файл table.pas. Для каждого активного соединения с сервером ESDB необходимо создать свой экземпляр объекта этого класса. В то же время, возможно повторное использование любого конкретного объекта этого класса: можно создать его один раз, а затем неограниченное количество раз, в цикле:

  1. вызвать метод Open
  2. произвести некоторые манипуляции с базой данных
  3. вызвать метод Close

(конечно, к стадиям 2 и 3 допускается переходить лишь в том случае, если вызов Open закончился успешно, то есть вернул значение true)

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

Конкретная работа с таблицами производится посредством вызова методов GetTableStructure, PostTableRecord, GetTableRecord, DeleteTableRecord, GetTotalRecordsCount, GetRealRecordsCount, PackTable и т. д. Все эти функции требуют наличия указателя на открытую таблицу, который необходимо предварительно получить через вызов метода OpenTable. Тот же указатель используется и для закрытия таблицы (по окончании работы с ней) через вызов метода CloseTable. Успешное открытие таблицы методом OpenTable возвращает положительный указатель на таблицу, при неудаче возвращаемое значение будет меньше нуля (код ошибки, описан в файле common.pas). Разумеется, сторонние разработчики не должны каким-либо образом пытаться интерпретировать положительное значение hTable, его следует лишь сохранять в переменной соответсвующего типа и использовать для вызова функций работы с таблицей.

Конечно, хорошим тоном программирования является аккуратное закрытие всех открытых в ходе сеанса работы таблиц по окончании подключения к базе данных. Однако, сервер ESDB сам отслеживает эту ситуацию, и если программист ошибется и забудет закрыть некие таблицы (в частности, это может произойти и непреднамерено - при разрыве TCP/IP подключения из-за сбоев сети), сам сервер ESDB исправит эту ошибку: при разрыве соединения (отключении от базы данных) все незакрытые таблицы будут корректно закрыты, так что целостность данных и индексов будет обеспечена в полном объеме.

В каждой таблице записи нумеруются числами натурального ряда - 1, 2, 3, и т. д. Доступ к записям такими функциями как GetTableRecord, DeleteTableRecord, PostTableRecord и т. д. производится именно через указанную нумерацию записей. При вызове функций доступа к записям сторонние разработчики должны самостоятельно контролировать, чтобы номер запрашиваемой записи не выходил за предел общего количества записей конкретной таблицы, возвращаемый методом GetTotalRecordsCount (впрочем, ошибочный выход за этот предел никакой аварии в сервере ESDB не вызовет). Если модуль стороннего разработчика успешно добавил запись в таблицу (такая операция производится через вызов метода PostTableRecord с нулевым номером записи), то он должен увеличить у себя на единицу внутренние счетчики общего и активного количества записей, первоначальные значения которых должны быть получены при открытии таблицы через GetTotalRecordsCount и GetRealRecordsCount, соответственно. (Тот же результат может быть получен и через непосредственный вызов GetTotalRecordsCount и GetRealRecordsCount - впрочем, уже с учетом работы параллельных подключений к той же таблице).

Каждая запись в некоторый момент времени может находится в одном из двух состояний: активная запись, либо удаленная запись. Метод GetTotalRecordsCount возвращает общее количество записей в таблице, а GetRealRecordsCount - количество активных (то есть не удаленных) записей. Разумеется, при одновременной работе с одной и той же таблицей из нескольких потоков (или через несколько клиентских подключений с разных машин) как общее, так активное количество записей может меняться самым непредсказуемым образом по ходу работы. Единственное, что можно гарантировать, так это то, что общее количество записей не может уменьшится (его уменьшение может произойти только после вызова метода PackTable, однако это осуществимо только при монопольной работе с данной таблицей). При реализации своего метода Next сторонний разрабочик, таким образом, должен сделать попытку прочитать следующую (по номеру) запись, а если она окажется удаленной, то либо выставить флаг EndOfFile (если достигнут предельный номер по данным GetTotalRecordsCount), либо перейти к попытке прочитать запись со следующим по порядку номером (в противном случае). Аналогично выполняется реализация метода Prior, с тем лишь отличием, что при необходимости выставляется флаг BeginOfFile, а не EndOfFile, номер записи декрементируется, а не инкрементируется, а граничным номером служит единица, а не результат GetTotalRecordsCount.