FirebirdSQL logo
 Доступ к базам данныхИнтерфейсы от A до Z 

Основной интерфейс любого плагина

Приступим к реализации самого плагина. Тип основного интерфейса зависитот типа плагина, что очевидно, но все они основаны на общем интерфейсеIPluginBase с подсчётом ссылок, который выполняет общие для всехплагинов (и очень простые) задачи. Каждый плагин имеет некоторый (тоже сподсчётом ссылок) объект, которому принадлежит этот плагин. Чтобывыполнять интеллектуальное управление жизненным циклом плагинов, любойплагин должен иметь возможность хранить информацию о владельце исообщать её диспетчеру плагинов по запросу. Это означает, что каждыйплагин должен реализовывать два тривиальных метода setOwner() иgetOwner(), содержащиеся в интерфейсе IPluginBase. Зависимые от типаплагина методы, безусловно, более интересны — они обсуждаются в частиописания интерфейсов.

Давайте рассмотрим типичную часть реализации любого плагина (здесь яспециально использую несуществующий тип SomePlugin):

class MyPlugin : public ISomePluginImpl<MyPlugin, CheckStatusWrapper>
{
public:
  explicit MyPlugin(IPluginConfig* cnf) throw()
     : config(cnf), refCounter(0), owner(NULL)
  {
    config->addRef();
  }
  ...

Конструктор получает в качестве параметра интерфейс конфигурацииплагина. Если вы собираетесь конфигурировать плагин каким-то образом, торекомендуется сохранить этот интерфейс в вашем плагине и использоватьего позже. Это позволит вам использовать общий стиль конфигурацииFirebird, позволяя пользователям иметь привычную конфигурацию и свести кминимуму написание кода. Конечно, при сохранении какого-либо ссылочногоинтерфейса лучше не забывать добавлять ссылку на него. Также не забудьтеустановить счетчик ссылок в 0 и владельца плагина в NULL.

  ~MyPlugin()
  {
    config->release();
  }

Деструктор освобождает конфигурационный интерфейс. Обратите внимание: мыне меняем счетчик ссылок нашего владельца, потому что он принадлежитнам, а не мы принадлежим ему.

  // IRefCounted implementation
  int release()
  {
    if (--refCounter == 0)
    {
      delete this;
      return 0;
    }
    return 1;
  }


  void addRef()
  {
    ++refCounter;
  }

Абсолютно типичная реализация объекта с подсчётом ссылок.

  // IPluginBase implementation
  void setOwner(IReferenceCounted* o)
  {
    owner = o;
  }

  IReferenceCounted* getOwner()
  {
    return owner;
  }

Как и было обещано, реализация IPluginBase тривиальна.

  // ISomePlugin implementation
  // … here go various methods required for particular plugin type
private:
  IPluginConfig* config;
  FbSampleAtomic refCounter;
  IReferenceCounted* owner;
};

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

Фабрика плагинов

Еще один интерфейс, необходимый для работы плагина —IPluginFactory. Фабрика создаетэкземпляры плагина и возвращает их в диспетчер плагинов. Фабрика обычновыглядит так:

class Factory : public IPluginFactoryImpl<Factory, CheckStatusWrapper>
{
public:
  IPluginBase* createPlugin(CheckStatusWrapper* status,
                            IPluginConfig* factoryParameter)
  {
    MyPlugin* p = new MyPlugin(factoryParameter);
    p->addRef();
    return p;
  }
};

Здесь внимание следует уделить тому факту, что даже в случае, когда кодв функции может генерировать исключения (оператор new может бросать вслучае, когда память исчерпана), то не обязательно всегда вручнуюопределять блок try/catch — реализация интерфейсов Firebird делает этуработу за вас, в реализации IPluginFactory эта обработка происходит вшаблоне IPluginFactoryImpl. Обратите внимание, что обертки статуса поумолчанию выполняют полноценную обработку только для FbException. Ноесли вы работаете над каким-то крупным проектом, то определите своюсобственную оболочку, в этом случае вы можете обрабатывать любой типисключения C++ и передавать полезную информацию об этом из своегоплагина.

docnext count = 63

Точка инициализации модуля плагина

Когда диспетчер плагинов загружает модуль плагина, он вызывает процедуруинициализации модуля — единственную экспортируемую функцию плагинаFB_PLUGIN_ENTRY_POINT. Для написания кода ей понадобятся две глобальныепеременные — модуль плагина и фабрика плагинов. В нашем случае это:

PluginModule module;

Factory factory;

Если модуль содержит более одного плагина, вам понадобится фабрика длякаждого плагина.

Для FB_PLUGIN_ENTRY_POINT мы не должны забывать, что она должна бытьэкспортирована из модуля плагина, для этого требуется учет некоторыхособенностей ОС. Мы делаем это, используя макрос FB_DLL_EXPORT,определенный в examples/interfaces/ifaceExamples.h. Если вы уверены,что используете плагин только для некоторых конкретных ОС, то вы можетесделать это место немного проще. В минимальном случае функция должнарегистрировать модуль и все фабрики в диспетчере плагинов:

extern "C" void FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)
{
  IPluginManager* pluginManager = master->getPluginManager();
  module.registerMe(pluginManager);
  pluginManager->registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
                                       "DbCrypt_example",
                                       &factory);
}

Прежде всего, мы вызываем недавно написанную нами функциюPluginModule::registerMe(), которая сохраняет IPluginManager длядальнейшего использования и регистрирует наш модуль плагина. Затемрегистрируем фабрику (или фабрики если в одном модуле будет несколькоплагинов). Мы должны передать правильный тип плагина (допустимые типыперечислены в интерфейсе IPluginManager) и имя, под которым будетзарегистрирован плагин. В простейшем случае он должен совпадать с именемдинамической библиотеки модуля плагина. Это правило поможет вам ненастраивать плагин вручную в plugins.conf.

Обратите внимание — в отличие от приложений плагины не должныиспользовать fb_get_master_interface() для получения IMaster. Вместоэтого следует использовать экземпляр, переданный вFB_PLUGIN_ENTRY_POINT. Если вам нужен мастер-интерфейс в вашем плагине,позаботьтесь об его сохранении в этой функции.

Интерфейсы от A до Z

В этом глоссарии мы не перечисляем интерфейсы, которые не используютсяактивно (например, IRequest, необходимые в первую очередь для поддержкиустаревших запросов API ISC). Та же ссылка может быть получена изнекоторых методов (например, compileRequest() в IAttachment). Дляинтерфейсов/методов, имеющих прямой аналог в старом API, этот аналогбудет указан.

IAttachment

Интерфейс IAttachment заменяет isc_db_handle.

  1. getInfo

    void getInfo(StatusType* status,
                 unsigned itemsLength,
                 const unsigned char* items,
                 unsigned bufferLength,
                 unsigned char* buffer)

    Заменяет isc_database_info().

  2. startTransaction

    ITransaction* startTransaction(StatusType* status,
                                   unsigned tpbLength,
                                   const unsigned char* tpb)

    Частично заменяет isc_start_multiple(), использует координатор, чтобызапустить более одной распределённой транзакции. Позволяет объединить 2транзакции в одну распределённую.

  3. reconnectTransaction

    ITransaction* reconnectTransaction(StatusType* status,
                                       unsigned length,
                                       const unsigned char* id)

    Позволяет подключиться к транзакции в состоянии limbo. Параметр Idсодержит номер транзакции в сетевом формате заданной длины.

  4. compileRequest

    IRequest* compileRequest(StatusType* status,
                             unsigned blrLength,
                             const unsigned char* blr)

    Поддержка ISC API.

  5. transactRequest

    void transactRequest(StatusType* status,
                         ITransaction* transaction,
                         unsigned blrLength,
                         const unsigned char* blr,
                         unsigned inMsgLength,
                         const unsigned char* inMsg,
                         unsigned outMsgLength,
                         unsigned char* outMsg)

    Поддержка ISC API.

  6. createBlob

    IBlob* createBlob(StatusType* status,
                      ITransaction* transaction,
                      ISC_QUAD* id,
                      unsigned bpbLength,
                      const unsigned char* bpb)

    Создает новый blob, сохраняет его идентификатор в id, заменяетisc_create_blob2().

  7. openBlob

    IBlob* openBlob(StatusType* status,
                    ITransaction* transaction,
                    ISC_QUAD* id,
                    unsigned bpbLength,
                    const unsigned char* bpb)

    Открывает существующий blob, заменяет isc_open_blob2().

  8. getSlice

    int getSlice(StatusType* status,
                 ITransaction* transaction,
                 ISC_QUAD* id,
                 unsigned sdlLength,
                 const unsigned char* sdl,
                 unsigned paramLength,
                 const unsigned char* param,
                 int sliceLength,
                 unsigned char* slice)

    Поддержка ISC API.

  9. putSlice

    void putSlice(StatusType* status,
                  ITransaction* transaction,
                  ISC_QUAD* id,
                  unsigned sdlLength,
                  const unsigned char* sdl,
                  unsigned paramLength,
                  const unsigned char* param,
                  int sliceLength,
                  unsigned char* slice)

    Поддержка ISC API.

  10. executeDyn

    void executeDyn(StatusType* status,
                    ITransaction* transaction,
                    unsigned length,
                    const unsigned char* dyn)

    Поддержка ISC API.

  11. prepare

    IStatement* prepare(StatusType* status,
                        ITransaction* tra,
                        unsigned stmtLength,
                        const char* sqlStmt,
                        unsigned dialect,
                        unsigned flags)

    Заменяет isc_dsql_prepare(). Дополнительный параметр flags позволяютконтролировать, какая информация будет предварительно загружена издвижка сразу (т.е. в одном сетевом пакете для удаленной операции).

  12. execute

    ITransaction* execute(StatusType* status,
                          ITransaction* transaction,
                          unsigned stmtLength,
                          const char* sqlStmt,
                          unsigned dialect,
                          IMessageMetadata* inMetadata,
                          void* inBuffer,
                          IMessageMetadata* outMetadata,
                          void* outBuffer)

    Выполняет любую инструкцию SQL, за исключением возврата нескольких строкданных. Частичный аналог isc_dsql_execute2() — вход и выход XSLQDAзаменены на входные и выходные сообщения с соответствующими буферами.

  13. openCursor

    IResultSet* openCursor(StatusType* status,
                           ITransaction* transaction,
                           unsigned stmtLength,
                           const char* sqlStmt,
                           unsigned dialect,
                           IMessageMetadata* inMetadata,
                           void* inBuffer,
                           IMessageMetadata* outMetadata,
                           const char* cursorName,
                           unsigned cursorFlags)

    Выполняет оператор SQL, потенциально возвращающий несколько строкданных. Возвращает интерфейсIResultSet, который используется дляизвлечения этих данных. Формат выходных данных определяется параметромoutMetadata, при задании NULL используется формат по умолчанию. ПараметрcursorName указывает имя открытого курсора (аналогisc_dsql_set_cursor_name()). Параметр cursorFlags необходим, чтобыоткрыть двунаправленный указатель курсора, для этого необходимо указатьзначение IStatement::CURSOR_TYPE_SCROLLABLE.

  14. queEvents

    IEvents* queEvents(StatusType* status,
                       IEventCallback* callback,
                       unsigned length,
                       const unsigned char* events)

    Заменяет вызов isc_que_events(). Вместо функции обратного вызова сvoid* параметром используется интерфейс обратного вызова.

  15. cancelOperation

    void cancelOperation(StatusType* status, int option)

    Замена fb_cancel_operation().

  16. ping

    void ping(StatusType* status)

    Проверяет состояния соединения. Если тест не удаётся, то единственнаявозможная операция с подключением — закрыть его.

  17. getIdleTimeout

    unsigned getIdleTimeout(StatusType* status)

    Возвращает таймаут простоя соединения в секундах.

  18. setIdleTimeout

    void setIdleTimeout(StatusType* status, unsigned timeOut)

    Устанавливает таймаут простоя соединения в секундах.

  19. getStatementTimeout

    unsigned getStatementTimeout(StatusType* status)

    Возвращает таймаут выполнения запроса в миллисекундах.

  20. setStatementTimeout

    void setStatementTimeout(StatusType* status, unsigned timeOut)

    Устанавливает таймаут выполнения запроса в миллисекундах.

  21. createBatch

    IBatch* createBatch(StatusType* status,
                        ITransaction* transaction,
                        unsigned stmtLength,
                        const char* sqlStmt,
                        unsigned dialect,
                        IMessageMetadata* inMetadata,
                        unsigned parLength,
                        const unsigned char* par)

    Подготавливает sqlStmt и создает интерфейс IBatch, готовый принять несколько наборов входных параметровв формате inMetadata. Если оставить NULL в inMetadata, то пакет будет использовать формат по умолчанию для sqlStmt.В функцию createBatch() можно передать блок параметров, что позволит настроить поведение пакета.

  22. createReplicator

    IReplicator* createBatch(StatusType* status)

    Создаёт экземпляр плагина репликации с интерфейсом IReplicator.

  23. detach

    void detach(StatusType* status)

    Отсоединяет от текущей базы данных. Заменяет isc_detach_database(). В случае успеха освобождает интерфейс.

  24. dropDatabase

    void dropDatabase(StatusType* status)

    Удаляет текущую базу данных. Заменяет isc_drop_database(). В случае успеха освобождает интерфейс.

IDtc

Интерфейс IDtc — координатор распределенных транзакций. Используется длязапуска распределенной (работает с двумя или более подключениями)транзакции. В отличие от пред-FB3-подхода, когда распределеннаятранзакция должна запускаться таким образом с самого начала, координаторраспределенных транзакций Firebird 3 позволяет также присоединить ужезапущенные транзакции в единую распределенную транзакцию.

  1. join

    ITransaction* join(StatusType* status, ITransaction* one, ITransaction* two)

    Объединяет 2 независимых транзакции в распределенную транзакцию. Приуспешном выполнении обе транзакции, переданные в join(),освобождаются, а указатели на них больше не должны использоваться.

  2. startBuilder

    IDtcStart* startBuilder(StatusType* status)

    Возвращает IDtcStart интерфейс.

IDtcStart

Интерфейс IDtcStart — заменяет массив структур TEB (переданisc_start_multiple() в ISC API). Этот интерфейс собирает подключения(и, вероятно, соответствующие TPB), для которых должна быть запущенараспределённая транзакция.

  1. addAttachment

    void addAttachment(StatusType* status, IAttachment* att)

    Добавляет подключение, транзакция для него будет запущена с TPB поумолчанию.

  2. addWithTpb

    void addWithTpb(StatusType* status, IAttachment* att, unsigned length, const unsigned char* tpb)

    Добавляет подключение и TPB, которые будут использоваться для запускатранзакции для этого подключения.

  3. start

    ITransaction* start(StatusType* status)

    Начинает распределенную транзакцию для собранных подключений. При успехевозвращает интерфейс IDtcStart.

IEventCallback

Интерфейс IEventCallback — заменяет функцию обратного вызова,используемую в вызове isc_que_events(). Должен быть реализованпользователем для отслеживания событий с помощью методаIAttachment::queEvents().

  1. eventCallbackFunction

    void eventCallbackFunction(unsigned length, const unsigned char* events)

    Вызывается каждый раз, когда происходит событие.

IEvents

Интерфейс IEvents — заменяет идентификатор события при работе смониторингом событий.

  1. cancel

    void cancel(StatusType* status)

    Отменяет мониторинг событий, начатый в IAttachment::queEvents().

IFirebirdConf

Интерфейс IFirebirdConf — доступ к основной конфигурации Firebird.Используется как для конфигурации по умолчанию, заданной конфигурациейfirebird.conf, так и для каждой базы данных, скорректированной спомощью database.conf. Чтобы ускорить доступ к значениям конфигурации,вызовы, обращающиеся к фактическим значениям, используют целочисленныйключ вместо символьного имени параметра. Ключ стабилен во время работысервера (т. е. плагин может получить его один раз и использовать дляполучения значения параметров конфигурации для разных баз данных).

  1. getKey

    unsigned getKey(const char* name)

    Возвращает ключ для заданного имени параметра. ~0 (все биты равны 1)возвращается в случае, когда такого параметра нет.

  2. asInteger

    ISC_INT64 asInteger(unsigned key)

    Возвращает значение целочисленного параметра.

  3. asString

    const char* asString(unsigned key)

    Возвращает значение строкового параметра

  4. asBoolean

    FB_BOOLEAN asBoolean(unsigned key)

    Возвращает значение логического параметра. Стандартные аббревиатуры(1/true/t/yes/y) рассматриваются как true, все остальные — как false.

  5. getVersion

    unsigned getVersion(StatusType* status)

    Возвращает версию диспетчера конфигурации, связанную с этим интерфейсом.Различные версии диспетчера конфигурации могут сосуществовать на одном сервере, например, когдастарый движок БД используется на современном сервере. Обратите внимание — ключи (см. getKey())разных версий не совпадают и при неправильном использовании всегда будут возвращать 0/nullptr/false.

IInt128

Интерфейс IInt128 помогает работать со 128-битными целыми числами, которые используется в качестве базового типадля числовых и десятичных чисел с точностью более 18.

  1. toString

    void toString(StatusType* status, const FB_I128* from, int scale, unsigned bufferLength, char* buffer)

    Преобразует 128-битное целое значение в строку с учетом масштаба.

  2. fromString

    void fromString(StatusType* status, int scale, const char* from, FB_I128* to)

    Собирает 128-битное целое значение из строки с учетом масштаба.

IMaster

IMaster — основной интерфейс, с которого начинаются все операции сAPI-интерфейсом Firebird.

  1. getStatus

    IStatus* getStatus()

    Возвращает экземпляр интерфейса IStatus.

  2. getDispatcher

    IProvider* getDispatcher()

    Возвращает экземпляр интерфейсаIProvider, реализованный YValve(основной экземпляр поставщика).

  3. getPluginManager

    IPluginManager* getPluginManager()

    Возвращает экземпляр интерфейсаIPluginManager.

  4. getTimerControl

    ITimerControl* getTimerControl()

    Возвращает экземпляр интерфейсаITimerControl.

  5. getDtc

    IDtc* getDtc()

    Возвращает экземпляр интерфейса IDtc.

  6. getUtilInterface

    IUtil* getUtilInterface()

    Возвращает экземпляр интерфейса IUtil.

  7. getConfigManager

    IConfigManager* getConfigManager()

    Возвращает экземпляр интерфейсаIConfigManager.

IMessageMetadata

Интерфейс MessageMetadata — частичный аналог XSQLDA (не содержит данныхсообщений, присутствует только информация о формате сообщения).Используется в вызовах, связанных с выполнением операторов SQL.

  1. getCount

    unsigned getCount(StatusType* status)

    Возвращает количество полей/параметров в сообщении. Во всех вызовах,содержащих индексный параметр, это значение должно быть: 0 >= index < getCount().

  2. getField

    const char* getField(StatusType* status, unsigned index)

    Возвращает имя поля.

  3. getRelation

    const char* getRelation(StatusType* status, unsigned index)

    Возвращает имя отношения (из которого выбрано данное поле).

  4. getOwner

    const char* getOwner(StatusType* status, unsigned index)

    Возвращает имя владельца отношения.

  5. getAlias

    const char* getAlias(StatusType* status, unsigned index)

    Возвращает псевдоним поля.

  6. getType

    unsigned getType(StatusType* status, unsigned index)

    Возвращает SQL тип поля.

  7. isNullable

    FB_BOOLEAN isNullable(StatusType* status, unsigned index)

    Возвращает true, если поле может принимать значение NULL.

  8. getSubType

    int getSubType(StatusType* status, unsigned index)

    Возвращает подтип поля BLOB (0 - двоичный, 1 - текст и т. д.).

  9. getLength

    unsigned getLength(StatusType* status, unsigned index)

    Возвращает максимальную длину поля.

  10. getScale

    int getScale(StatusType* status, unsigned index)

    Возвращает масштаб для числового поля.

  11. getCharSet

    unsigned getCharSet(StatusType* status, unsigned index)

    Возвращает набор символов для символьных полей и текстового BLOB.

  12. getOffset

    unsigned getOffset(StatusType* status, unsigned index)

    Возвращает смещение данных поля в буфере сообщений (используйте его длядоступа к данным в буфере сообщений).

  13. getNullOffset

    unsigned getNullOffset(StatusType* status, unsigned index)

    Возвращает смещение NULL индикатора для поля в буфере сообщений.

  14. getBuilder

    IMetadataBuilder* getBuilder(StatusType* status)

    Возвращает интерфейсIMetadataBuilder,инициализированный метаданными этого сообщения.

  15. getMessageLength

    unsigned getMessageLength(StatusType* status)

    Возвращает длину буфера сообщения (используйте его для выделения памятипод буфер).

  16. getAlignment

    unsigned getAlignment(StatusType* status)

    Возвращает выравнивание в байтах.

  17. getAlignedLength

    unsigned getAlignedLength(StatusType* status)

    Возвращает размер структуры метаданных после выравнивания.

IMetadataBuilder

Интерфейс IMetadataBuilder — позволяет описать типы данных длясуществующих сообщений или создавать метаданные с самого начала.

  1. setType

    void setType(StatusType* status, unsigned index, unsigned type)

    Устанавливает SQL тип поля.

  2. setSubType

    void setSubType(StatusType* status, unsigned index, int subType)

    Устанавливает подтип BLOB поля.

  3. setLength

    void setLength(StatusType* status, unsigned index, unsigned length)

    Устанавливает максимальную длину символьного поля.

  4. setCharSet

    void setCharSet(StatusType* status, unsigned index, unsigned charSet)

    Устанавливает набор символов для символьного поля и текстового BLOB.

  5. setScale

    void setScale(StatusType* status, unsigned index, unsigned scale)

    Устанавливает масштаб для числовых полей.

  6. truncate

    void truncate(StatusType* status, unsigned count)

    Обрезает сообщение чтобы оно содержало не более count полей.

  7. moveNameToIndex

    void moveNameToIndex(StatusType* status, const char* name, unsigned index)

    Реорганизует поля в сообщении — перемещает поле с именем name в заданноеположение.

  8. remove

    void remove(StatusType* status, unsigned index)

    Удаляет поле.

  9. addField

    unsigned addField(StatusType* status)

    Добавляет поле.

  10. getMetadata

    IMessageMetadata* getMetadata(StatusType* status)

    Возвращает интерфейсIMessageMetadata, построенныйэтим построителем.

  11. setField

    void setField(StatusType* status, unsigned index, const char* field)

    Устанавливает имя поля/столбца.

  12. setRelation

    void setRelation(StatusType* status, unsigned index, const char* relation)

    Устанавливает имя отношения для поля.

  13. setOwner

    void setOwner(StatusType* status, unsigned index, const char* owner)

    Устанавливает имя владельца.

  14. setAlias

    void setAlias(StatusType* status, unsigned index, const char* alias)

    Устанавливает псевдоним поля.

IOffsetsCallback

Интерфейс IOffsetsCallback

  1. setOffset

    void setOffset(StatusType* status, unsigned index, unsigned offset, unsigned nullOffset)

    Уведомляет, что должны быть установлены смещения для поля/параметра синдексом index. Должен быть реализован пользователем при реализацииинтерфейса MessageMetadata и сиспользованием IUtil::setOffsets().

IBatch

Интерфейс IBatch — позволяет обрабатывать несколько наборов параметров при выполнении одного оператора.

  1. add

    void add(StatusType* status, unsigned count, const void* inBuffer)

    Добавляет количество сообщений из inBuffer в пакет. Общий размер сообщений, которые можно добавить в пакет,ограничен параметром TAG_BUFFER_BYTES_SIZE при создании пакета.

  2. addBlob

    void addBlob(StatusType* status,
                 unsigned length, const void* inBuffer,
                 ISC_QUAD* blobId,
                 unsigned bpbLength, const unsigned char* bpb)

    Добавляет в пакет один BLOB длиной length байт из inBuffer, идентификатор BLOB находится по адресу blobId.Если большой двоичный объект должен быть создан с параметрами, отличными от параметров по умолчанию, то может бытьпередан BPB (формат соответствует формату, используемому в Attachment::createBlob).Общий размер встроенных больших двоичных объектов, которые можно добавить в пакет (включая необязательные BPB,заголовки BLOB, размер сегментов с учётом выравнивания) ограничен параметром TAG_BUFFER_BYTES_SIZE при создании пакета(влияет на все методы, ориентированные на BLOB, кроме registerBlob()).

  3. appendBlobData

    void appendBlobData(StatusType* status, unsigned length, const void* inBuffer)

    Расширяет последний добавленный BLOB: добавляет к нему байты длинной length, взятые по адресу inBuffer.

  4. addBlobStream

    addBlobStream(StatusType* status, unsigned length, const void* inBuffer)

    Добавляет данные BLOB (это может быть несколько объектов или часть одного BLOB) в пакет. Заголовок каждого BLOB в потокевыравнивается по границе getBlobAlignment() и содержит 3 поля: первое - 8-байтовый идентификатор BLOB (в формате ISC_QUAD),второе - 4-байтная длина BLOB, третье - 4-байтная длина BPB. Заголовок большого двоичного объекта не должен пересекатьграницы буфера в этом вызове функции. Данные BPB помещаются сразу после заголовка, затем идут данные BLOB-объектов.Длина большого двоичного объекта включает BPB (если он присутствует). Все данные могут быть распределены междунесколькими вызовами addBlobStream(). Данные BLOB-объекта, в свою очередь, могут быть структурированы в случаесегментированного BLOB-объекта, см. главу "Пакетное изменение данных".

  5. registerBlob

    void registerBlob(StatusType* status, const ISC_QUAD* existingBlob, ISC_QUAD* blobId)

    Позволяет использовать в пакете BLOB, добавленные с помощью стандартного интерфейса IBlob. Эта функция содержит 2параметра ISC_QUAD*, важно их не смешивать – второй параметр (existingBlob) является указателем на идентификатор BLOB,уже добавленный вне области действия пакета, третий (blobId) указывает на идентификатор BLOB, который будет помещен в сообщение в этом пакете'.

  6. execute

    IBatchCompletionState* execute(StatusType* status, ITransaction* transaction)

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

  7. cancel

    void cancel(StatusType* status)

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

  8. getBlobAlignment

    unsigned getBlobAlignment(StatusType* status)

    Возвращает необходимое выравнивание для данных, помещаемых в буфер функцией addBlobStream().

  9. getMetadata

    IMessageMetadata* getMetadata(StatusType* status)

    Возвращает формат метаданных, используемых в пакетных сообщениях.

  10. setDefaultBpb

    void setDefaultBpb(StatusType* status, unsigned parLength, const unsigned char* par)

    Задает BPB, который будет использоваться для всех BLOB-объектов, в которых отсутствует BPB не по умолчанию.Должен вызываться перед добавлением любого сообщения или BLOB в пакет.

  11. getInfo

    void getInfo(StatusType* status,
                 unsigned itemsLength, const unsigned char* items,
                 unsigned bufferLength, unsigned char* buffer)

    Запрашивает информацию о пакете.

Тег для блока параметров:

  • VERSION1

Теги для скоплений в блоке параметров:

  • TAG_MULTIERROR (0/1) – может иметь более одного сообщения с ошибками;

  • TAG_RECORD_COUNTS (0/1) - учет измененных записей по сообщениям;

  • TAG_BUFFER_BYTES_SIZE (integer) - максимально возможный размер буфера на сервере (по умолчанию 16Мб, максимум 256Мб);

  • TAG_BLOB_POLICY - политика, используемая для хранения BLOB-объектов;

  • TAG_DETAILED_ERRORS (integer) - сколько векторов с подробной информацией об ошибках хранится в состоянии завершения (по умолчанию 64, максимум 256).

Политики, используемые для хранения BLOB:

  • BLOB_NONE – нельзя использовать встроенные BLOB-объекты (registerBlob() работает в любом случае);

  • BLOB_ID_ENGINE - BLOB добавляются один за другим, BLOB-идентификаторы генерируются движком firebird;

  • BLOB_ID_USER - BLOB добавляются один за другим, BLOB-идентификаторы генерируются пользователем;

  • BLOB_STREAM - BLOB-объекты добавляются в поток.

Элементы, допустимые в вызове getInfo():

  • INF_BUFFER_BYTES_SIZE – фактический максимально возможный размер буфера (устанавливается через TAG_BUFFER_BYTES_SIZE);

  • INF_DATA_BYTES_SIZE - размер уже добавленных сообщений;

  • INF_BLOBS_BYTES_SIZE - размер уже добавленных BLOB;

  • INF_BLOB_ALIGNMENT - требуемое выравнивание для данных BLOB (дублирует getBlobAlignment).

IPluginConfig

Интерфейс IPluginConfig — передается фабрике плагинов при созданииэкземпляра плагина (с конкретной конфигурацией).

  1. getConfigFileName

    const char* getConfigFileName()

    Возвращает рекомендованное имя файла, в котором ожидается сохранениеконфигурации для плагина.

  2. getDefaultConfig

    IConfig* getDefaultConfig(StatusType* status)

    Конфигурация плагина, загруженная по стандартным правилам.

  3. getFirebirdConf

    IFirebirdConf* getFirebirdConf(StatusType* status)

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

  4. setReleaseDelay

    void setReleaseDelay(StatusType* status, ISC_UINT64 microSeconds)

    Используемые плагином для настройки рекомендуемой задержки, в течениекоторой модуль плагина не будет выгружен менеджером плагинов послеосвобождения последнего экземпляра плагина из этого модуля.

IPluginFactory

Интерфейс IPluginFactory — должен быть реализован автором плагина принаписании плагина.

  1. createPlugin

    IPluginBase* createPlugin(StatusType* status, IPluginConfig* factoryParameter)

    Создает новый экземпляр плагина с переданной рекомендуемойконфигурацией.

IPluginManager

Интерфейс IPluginManager — API диспетчера плагинов.

  1. registerPluginFactory

    void registerPluginFactory(unsigned pluginType,
                               const char* defaultName,
                               IPluginFactory* factory)

    Регистрирует именованную фабрику плагинов данного типа.

  2. registerModule

    void registerModule(IPluginModule* cleanup)

    Регистрирует модуль плагина.

  3. unregisterModule

    void unregisterModule(IPluginModule* cleanup)

    Разрегистрирует модуль плагина.

  4. getPlugins

    IPluginSet* getPlugins(StatusType* status,
                           unsigned pluginType,
                           const char* namesList,
                           IFirebirdConf* firebirdConf)

    Возвращает интерфейс IPluginSet, предоставляющий доступ к спискуплагинов данного типа. Имена включенных плагинов берутся из namesList,если отсутствует (NULL), то из настроек конфигурации для данного типаpluginType. Если указан параметр firebirdConf, то он используется длявсех целей конфигурации (включая получение списка плагинов и переход кметоду PluginFactory::createPlugin()), если отсутствует (NULL), тоиспользуется настройка по умолчанию (из firebird.conf).

  5. getConfig

    IConfig* getConfig(StatusType* status, const char* filename)

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

  6. releasePlugin

    void releasePlugin(IPluginBase* plugin)

    Освобождение данного плагина. Должен использоваться для плагинов вместопростой release() из-за необходимости выполнять дополнительныедействия с владельцем плагина до фактического освобождения.

Константы, определенные интерфейсом IPluginManager (типы плагинов):

  • TYPE_PROVIDER

  • TYPE_AUTH_SERVER

  • TYPE_AUTH_CLIENT

  • TYPE_AUTH_USER_MANAGEMENT

  • TYPE_EXTERNAL_ENGINE

  • TYPE_TRACE

  • TYPE_WIRE_CRYPT

  • TYPE_DB_CRYPT

  • TYPE_KEY_HOLDER

  • TYPE_REPLICATOR

IPluginModule

Интерфейс IPluginModule — представляет модуль плагина (динамическаябиблиотека). Должен быть реализован автором плагина в каждом модулеплагина (по одному экземпляру на модуль).

  1. doClean

    void doClean()

    вызывается диспетчером плагинов перед нормальной выгрузкой модуляплагина.

IPluginSet

Интерфейс IPluginSet — представляет собой набор плагинов данного типа.Обычно используется внутренним кодом Firebird, но рекомендуется дляиспользования в плагинах, загружающих другие плагины.

  1. getName

    const char* getName()

    возвращает имя текущего плагина в наборе.

  2. getModuleName

    const char* getModuleName()

    возвращает имя модуля текущего плагина в наборе (в простом случаесовпадает с именем плагина).

  3. getPlugin

    IPluginBase* getPlugin(StatusType* status)

    возвращает экземпляр текущего плагина, возвращенный интерфейс долженбыть преобразован в основной интерфейс плагина запрошенного типа вметоде IPluginManager::getPlugins(). Возвращает NULL, если в наборебольше нет плагинов. Счётчик ссылок плагина, возвращаемого этойфункцией, увеличивается при возврате — не забудьте использовать методreleasePlugin() интерфейсаIPluginManager для освобожденияплагинов, возвращаемых этим методом.

  4. next

    void next(StatusType* status)

    устанавливает переключатель для перехода к следующему плагину из списка.

  5. set

    void set(StatusType* status, const char* list)

    сбрасывает интерфейс: заставляет его работать со списком плагинов,предоставляемых параметром списка. Тип плагинов остается неизменным.

IProvider

Интерфейс IPluginModule — основной интерфейс для начала доступа к базеданных/сервису.

  1. attachDatabase

    IAttachment* attachDatabase(StatusType* status,
                                const char* fileName,
                                unsigned dpbLength,
                                const unsigned char* dpb)

    Создаёт соединение с существующей базой данных. Заменяет isc_attach_database().

  2. createDatabase

    IAttachment* createDatabase(StatusType* status,
                                const char* fileName,
                                unsigned dpbLength,
                                const unsigned char* dpb)

    Создаёт новую базу данных и возращает интерфейс соединения с ней. Заменяет isc_create_database().

  3. attachServiceManager

    IService* attachServiceManager(StatusType* status,
                                   const char* service,
                                   unsigned spbLength,
                                   const unsigned char* spb)

    Заменяет isc_service_attach().

  4. shutdown

    void shutdown(StatusType* status, unsigned timeout, const int reason)

    Заменяет fb_shutdown().

  5. setDbCryptCallback

    void setDbCryptCallback(IStatus* status, ICryptKeyCallback* cryptCallback)

    Устанавливает интерфейс обратного вызова шифрования базы данных, которыйбудет использоваться для последующих подключений к базе данных исервисам. См. …​ для подробностей.

IResultSet

Интерфейс IResultSet — заменяет (с расширенной функциональностью)некоторые функции isc_stmt_handle. Этот интерфейс возвращается вызовомopenCursor() из IAttachment илиIStatement. Все вызовы fetch…​,кроме fetchNext(), работают только для двунаправленного (открытого сфлагом CURSOR_TYPE_SCROLLABLE) курсора.

  1. fetchNext

    int fetchNext(StatusType* status, void* message)

    выбирает следующую запись, заменяет isc_dsql_fetch(). Этот метод (идругие методы выборки) возвращает код завершенияStatus::RESULT_NO_DATA при достижении EOF, и статусStatus::RESULT_OK при успешном завершении.

  2. fetchPrior

    int fetchPrior(StatusType* status, void* message)

    выбирает предыдущую запись.

  3. fetchFirst

    int fetchFirst(StatusType* status, void* message)

    выбирает первую запись.

  4. fetchLast

    int fetchLast(StatusType* status, void* message)

    выбирает последнюю запись.

  5. fetchAbsolute

    int fetchAbsolute(StatusType* status, int position, void* message)

    получает запись по абсолютной позиции в наборе результатов.

  6. fetchRelative

    int fetchRelative(StatusType* status, int offset, void* message)

    извлекает запись по положению относительно текущей.

  7. isEof

    FB_BOOLEAN isEof(StatusType* status)

    проверка EOF.

  8. isBof

    FB_BOOLEAN isBof(StatusType* status)

    проверка BOF.

  9. getMetadata

    IMessageMetadata* getMetadata(StatusType* status)

    возвращает метаданные для сообщений в наборе результатов, особеннополезно, когда набор результатов открывается вызовомIAttachment::openCursor() с параметром формата вывода метаданныхравным NULL (это единственный способ получить формат сообщения в данномслучае).

  10. close

    void close(IStatus* status)

    закрывает набор результатов, освобождает интерфейс в случае успеха.

IService

Интерфейс IService — заменяет isc_svc_handle.

  1. detach

    void detach(StatusType* status)

    Закрывает подключение к менеджеру сервисов, при успехе освобождаетинтерфейс. Заменяет isc_service_detach().

  2. query

    void query(StatusType* status,
               unsigned sendLength,
               const unsigned char* sendItems,
               unsigned receiveLength,
               const unsigned char* receiveItems,
               unsigned bufferLength,
               unsigned char* buffer)

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

  3. start

    void start(StatusType* status,
               unsigned spbLength,
               const unsigned char* spb)

    Запускает утилиту в диспетчере служб. Заменяет isc_service_start().

IStatement

Интерфейс IStatement — заменяет (частично) isc_stmt_handle.

  1. getInfo

    void getInfo(StatusType* status,
                 unsigned itemsLength,
                 const unsigned char* items,
                 unsigned bufferLength,
                 unsigned char* buffer)

    Заменяет isc_dsql_sql_info().

  2. getType

    unsigned getType(StatusType* status)

    Тип оператора, в настоящее время можно найти только в источникахfirebird в dsql/dsql.h.

  3. getPlan

    const char* getPlan(StatusType* status, FB_BOOLEAN detailed)

    Возвращает план выполнения оператора.

  4. getAffectedRecords

    ISC_UINT64 getAffectedRecords(StatusType* status)

    Возвращает количество записей, которые затронуты оператором.

  5. getInputMetadata

    IMessageMetadata* getInputMetadata(StatusType* status)

    Возвращает метаданные параметров.

  6. getOutputMetadata

    IMessageMetadata* getOutputMetadata(StatusType* status)

    Возвращает метаданные значений выходных данных.

  7. execute

    ITransaction* execute(StatusType* status,
                          ITransaction* transaction,
                          IMessageMetadata* inMetadata,
                          void* inBuffer,
                          IMessageMetadata* outMetadata,
                          void* outBuffer)

    Выполняет любую инструкцию SQL, за исключением тех, что возвращаютнескольких строк данных. Частичный аналог isc_dsql_execute2() — вход ивыход XSLQDA заменены на входные и выходные сообщения с соответствующимибуферами.

  8. openCursor

    IResultSet* openCursor(StatusType* status,
                           ITransaction* transaction,
                           IMessageMetadata* inMetadata,
                           void* inBuffer,
                           IMessageMetadata* outMetadata,
                           unsigned flags)

    Выполняет оператор SQL, потенциально возвращающий несколько строкданных. Возвращает интерфейс IResultSet, который должен использоватьсядля извлечения этих данных. Формат выходных данных определяетсяпараметром outMetadata, если указано NULL, то будет использоватьсяформат по умолчанию.

  9. setCursorName

    void setCursorName(StatusType* status, const char* name)

    Заменяет isc_dsql_set_cursor_name().

  10. free

    void free(StatusType* status)

    Уничтожает оператор, освобождает интерфейс в случае успеха.

  11. getFlags

    unsigned getFlags(StatusType* status)

    Возвращает флаги, описывающие, как должен выполняться этот оператор,упрощенная замена метода getType().

  12. getTimeout

    unsigned getTimeout(StatusType* status)

    Возвращает таймаут выполнения SQL запроса в миллисекундах.

  13. setTimeout

    unsigned setTimeout(StatusType* status)

    Устанавливает таймаут выполнения SQL запроса в миллисекундах.

  14. createBatch

    IBatch* createBatch(StatusType* status,
                        IMessageMetadata* inMetadata,
                        unsigned parLength,
                        const unsigned char* par)

    Создает интерфейс IBatch для оператора SQL с входными параметрами, что позволяет выполнять этот операторс несколькими наборами параметров. Формат входных данных определяется параметром inMetadata, оставив его NULL,пакет использует формат по умолчанию из этого интерфейса. В функцию createBatch() можно передать блок параметров,что позволит настроить поведение пакета.

Константы, определенные интерфейсом IStatement

Флаги IAttachment::prepare():

  • PREPARE_PREFETCH_NONE — константа, чтобы пропускать флаги, значение0.

Следующие флаги могут быть объединены с помощью OR для полученияжелаемого эффекта:

  1. PREPARE_PREFETCH_TYPE

  2. PREPARE_PREFETCH_INPUT_PARAMETERS

  3. PREPARE_PREFETCH_OUTPUT_PARAMETERS

  4. PREPARE_PREFETCH_LEGACY_PLAN

  5. PREPARE_PREFETCH_DETAILED_PLAN

  6. PREPARE_PREFETCH_AFFECTED_RECORDS

  7. PREPARE_PREFETCH_FLAGS (флаги возвращаемые методом getFlags())

Для наиболее часто используемых комбинаций флагов можно использоватьконстанты:

  1. PREPARE_PREFETCH_METADATA

  2. PREPARE_PREFETCH_ALL

Значения возвращаемые методом getFlags():

  1. FLAG_HAS_CURSOR — используйте openCursor() для выполнения этогооператора, а не execute()

  2. FLAG_REPEAT_EXECUTE — когда подготовленный оператор можетвыполняться много раз с разными параметрами.

Флаги передаваемые в openCursor():

  1. CURSOR_TYPE_SCROLLABLE — открывается двунаправленный курсор.

IStatus

Интерфейс IStatus — заменяет ISC_STATUS_ARRAY. Функциональностьрасширена — статус имеет отдельный доступ к векторам ошибок ипредупреждений, может содержать векторы неограниченной длины,самостоятельно хранит строки, используемые в векторах, не имеетнеобходимости в кольцевом буфере строк. В C++ IStatus всегдаиспользуется в оболочке состояния, C++ API предоставляет две разныеоболочки, имеющие различное поведение, когда ошибка возвращается извызова API. Интерфейс сведен к минимуму (методы, такие какпреобразование его в текст, перемещены в интерфейсIUtil), чтобы упростить его реализациюпользователями при необходимости.

  1. init

    void init()

    очищает интерфейс, устанавливая его в исходное состояние.

  2. getState

    unsigned getState()

    возвращает текущее состояние интерфейса, возвращаемые флаги могут бытьобъединены с помощью OR.

  3. setErrors2

    void setErrors2(unsigned length, const intptr_t* value)

    устанавливает содержимое вектора ошибок с длиной, явно указанной ввызове.

  4. setWarnings2

    void setWarnings2(unsigned length, const intptr_t* value)

    устанавливает содержимое вектора предупреждений с длиной, явно указаннойв вызове.

  5. setErrors

    void setErrors(const intptr_t* value)

    устанавливает содержимое вектора ошибок, длина определяется контекстомзначения.

  6. setWarnings

    void setWarnings(const intptr_t* value)

    устанавливает содержимое вектора предупреждений, длина определяетсяконтекстом значения.

  7. getErrors

    const intptr_t* getErrors()

    возвращает вектор ошибок.

  8. getWarnings

    const intptr_t* getWarnings()

    возвращает вектор предупреждений.

  9. clone

    IStatus* clone()

    создаёт клон текущего интерфейса.

Константы определённые в IStatus

Флаги, возвращаемые методом getState():

  • STATE_WARNINGS

  • STATE_ERRORS

Коды завершения:

  • RESULT_ERROR

  • RESULT_OK

  • RESULT_NO_DATA

  • RESULT_SEGMENT

IBatchCompletionState

IBatchCompletionState — одноразовый интерфейс, всегда возвращаемый методом execute() интерфейса IBatch.Он содержит более или менее (в зависимости от параметров, переданных при создании IBatch) подробную информациюо результатах выполнения пакета.

  1. getSize

    unsigned getSize(StatusType* status)

    Возвращает общее количество обработанных сообщений.

  2. getState

    int getState(StatusType* status, unsigned pos)

    Возвращает результат выполнения сообщения с номером pos. При любой ошибке с сообщением это константа EXECUTE_FAILED,возвращаемое значение в случае успеха зависит от наличия параметра RECORD_COUNTS при создании пакета.Когда она присутствует и имеет ненулевое значение, возвращается количество записей, вставленных, обновленных или удаленныхво время обработки конкретного сообщения, иначе возвращается константа SUCCESS_NO_INFO.

  3. findError

    unsigned findError(StatusType* status, unsigned pos)

    Находит следующее (начинающееся с pos) сообщение, обработка которого вызвала ошибку.При отсутствии такого сообщения возвращается константа NO_MORE_ERRORS. Количество векторов состояния,возвращаемых в этом интерфейсе, ограничено значением параметра DETAILED_ERRORS при создании пакета.

  4. getStatus

    void getStatus(StatusType* status, IStatus* to, unsigned pos)

    Возвращает подробную информацию (полный вектор состояния) об ошибке, которая произошла при обработке сообщения pos.Чтобы различать ошибки (в IBatch::execute() или в IBatchCompletionState::getStatus()), этот статус возвращаетсяв отдельном параметре to, в отличие от ошибок в этом вызове, которые помещаются в параметр status.

Специальные значения, возвращаемые getState():

  • EXECUTE_FAILED — при обработке этого сообщения произошла ошибка;

  • SUCCESS_NO_INFO — информация об обновлении записи не была собрана.

Специальное значение, возвращаемое findError():

  • NO_MORE_ERRORS – больше нет сообщений с ошибками в этом пакете.

ITimer

Интерфейс ITimer — пользовательский таймер. Интерфейс обратного вызова,который должен быть реализован пользователем для использования таймераFirebird.

  1. handler

    void handler()

    метод вызывается, когда таймер звонит (или когда сервер выключается).

ITimerControl

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

  1. start

    void start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds)

    запуск ITimer после сигнала (вмикросекундах, 10-6 секунд). Таймер будет разбужен только один разпосле этого вызова.

  2. stop

    void stop(StatusType* status, ITimer* timer)

    остановка ITimer. Не стоит останавливатьне запущенный таймер, что позволит избежать проблем с гонками междуstop() и сигналом таймером.

ITransaction

Интерфейс ITransaction — заменяет isc_tr_handle.

  1. getInfo

    void getInfo(StatusType* status,
                 unsigned itemsLength,
                 const unsigned char* items,
                 unsigned bufferLength,
                 unsigned char* buffer)

    заменяет isc_transaction_info().

  2. prepare

    void prepare(StatusType* status,
                 unsigned msgLength,
                 const unsigned char* message)

    заменяет isc_prepare_transaction2().

  3. commit

    void commit(StatusType* status)

    заменяет isc_commit_transaction().

  4. commitRetaining

    void commitRetaining(StatusType* status)

    заменяет isc_commit_retaining().

  5. rollback

    void rollback(StatusType* status)

    заменяет isc_rollback_transaction().

  6. rollbackRetaining

    void rollbackRetaining(StatusType* status)

    заменяет isc_rollback_retaining().

  7. disconnect

    void disconnect(StatusType* status)

    заменяет fb_disconnect_transaction().

  8. join

    ITransaction* join(StatusType* status, ITransaction* transaction)

    соединяет текущую транзакцию и транзакцию, переданную как параметр вединую распределённую транзакцию (с использованием Dtc). При успешномвыполнении текущая транзакция и транзакция переданная в качествепараметра освобождаются и больше не должны использоваться.

  9. validate

    ITransaction* validate(StatusType* status, IAttachment* attachment)

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

  10. enterDtc

    ITransaction* enterDtc(StatusType* status)

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

IVersionCallback

Интерфейс IVersionCallback — обратный вызов для IUtil::getFbVersion().

  1. callback

    void callback(StatusType* status, const char* text)

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

IUtil

Интерфейс IUtil — различные вспомогательные методы, требуемые здесь илитам.

  1. getFbVersion

    void getFbVersion(StatusType* status,
                      IAttachment* att,
                      IVersionCallback* callback)

    Строит длинный и красивый отчет о версии для firebird. Это можноувидеть в ISQL при вызове с ключом -Z.

  2. loadBlob

    void loadBlob(StatusType* status,
                  ISC_QUAD* blobId,
                  IAttachment* att,
                  ITransaction* tra,
                  const char* file,
                  FB_BOOLEAN txt)

    Загрузка BLOB из файла.

  3. dumpBlob

    void dumpBlob(StatusType* status,
                  ISC_QUAD* blobId,
                  IAttachment* att,
                  ITransaction* tra,
                  const char* file,
                  FB_BOOLEAN txt)

    Сохраняет BLOB в файл.

  4. getPerfCounters

    void getPerfCounters(StatusType* status,
                         IAttachment* att,
                         const char* countersSet,
                         ISC_INT64* counters)

    Получает статистику для данного подключения.

  5. executeCreateDatabase

    IAttachment* executeCreateDatabase(StatusType* status,
                                       unsigned stmtLength,
                                       const char* creatDBstatement,
                                       unsigned dialect,
                                       FB_BOOLEAN* stmtIsCreateDb)

    Выполняет инструкцию CREATE DATABASE …​ — трюк ISC с NULLдескриптором оператора не работает с интерфейсами.

  6. decodeDate

    void decodeDate(ISC_DATE date,
                    unsigned* year,
                    unsigned* month,
                    unsigned* day)

    Заменяет isc_decode_sql_date().

  7. decodeTime

    void decodeTime(ISC_TIME time,
                    unsigned* hours,
                    unsigned* minutes,
                    unsigned* seconds,
                    unsigned* fractions)

    Заменяет isc_decode_sql_time().

  8. encodeDate

    ISC_DATE encodeDate(unsigned year, unsigned month, unsigned day)

    Заменяет isc_encode_sql_date().

  9. encodeTime

    ISC_TIME encodeTime(unsigned hours,
                        unsigned minutes,
                        unsigned seconds,
                        unsigned fractions)

    Заменяет isc_encode_sql_time().

  10. formatStatus

    unsigned formatStatus(char* buffer, unsigned bufferSize, IStatus* status)

    Заменяет fb_interpret(). Размер буфера, переданного в этот метод, недолжен быть меньше 50 байт.

  11. getClientVersion

    unsigned getClientVersion()

    Возвращает целое число, содержащее основную версию в байте 0 и младшуюверсию в байте 1.

  12. getXpbBuilder

    IXpbBuilder* getXpbBuilder(StatusType* status,
                               unsigned kind,
                               const unsigned char* buf,
                               unsigned len)

    Возвращает интерфейс IXpbBuilder.Допустимые kind перечислены в IXpbBuilder.

  13. setOffsets

    unsigned setOffsets(StatusType* status,
                        IMessageMetadata* metadata,
                        IOffsetsCallback* callback)

    Устанавливает допустимые смещения вIMessageMetadata. Выполняетвызовы для обратного вызова вIOffsetsCallback для каждогополя/параметра.

  14. getDecFloat16

    IDecFloat16* getDecFloat16(StatusType* status)

    Возвращает интерфейс IDecFloat16.

  15. getDecFloat34

    IDecFloat34* getDecFloat34(StatusType* status)

    Возвращает интерфейс IDecFloat34.

  16. decodeTimeTz

    void decodeTimeTz(StatusType* status,
                      const ISC_TIME_TZ* timeTz,
                      unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
                      unsigned timeZoneBufferLength, char* timeZoneBuffer)

    Декодирует время с часовым поясом.

  17. decodeTimeStampTz

    void decodeTimeStampTz(StatusType* status,
                           const ISC_TIMESTAMP_TZ* timeStampTz,
                           unsigned* year, unsigned* month, unsigned* day,
                           unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
                           unsigned timeZoneBufferLength, char* timeZoneBuffer)

    Декодирует временную метку (дату-время) с часовым поясом.

  18. encodeTimeTz

    void encodeTimeTz(StatusType* status,
                      ISC_TIME_TZ* timeTz,
                      unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions,
                      const char* timeZone)

    Кодирует время с часовым поясом.

  19. encodeTimeStampTz

    void encodeTimeStampTz(StatusType* status,
                           ISC_TIMESTAMP_TZ* timeStampTz,
                           unsigned year, unsigned month, unsigned day,
                           unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions,
                           const char* timeZone)

    Кодирует временную метку (дату-время) с часовым поясом.

  20. getInt128

    IInt128* getInt128(StatusType* status)

    Возвращает интерфейс IInt128.

  21. decodeTimeTzEx

    void decodeTimeTzEx(StatusType* status,
                        const ISC_TIME_TZ_EX* timeTz,
                        unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
                        unsigned timeZoneBufferLength, char* timeZoneBuffer)

    Декодирует время в расширенном формате с часовым поясом.

  22. decodeTimeStampTzEx

    void decodeTimeStampTzEx(StatusType* status,
                             const ISC_TIMESTAMP_TZ_EX* timeStampTz,
                             unsigned* year, unsigned* month, unsigned* day, unsigned* hours,
                             unsigned* minutes, unsigned* seconds, unsigned* fractions,
                             unsigned timeZoneBufferLength, char* timeZoneBuffer)

    Декодирует временную метку (дату-время) в расширенном формате с часовым поясом.

IXpbBuilder

Интерфейс IXpbBuilder

  1. clear

    void clear(StatusType* status)

    Сбрасывает построитель в пустое состояние.

  2. removeCurrent

    void removeCurrent(StatusType* status)

    Удаляет текущий clumplet.

  3. insertInt

    void insertInt(StatusType* status, unsigned char tag, int value)

    Вставляет clumplet со значением, представляющим целое число в сетевомформате.

  4. insertBigInt

    void insertBigInt(StatusType* status, unsigned char tag, ISC_INT64 value)

    Вставляет clumplet со значением, представляющим 64-битное целое число всетевом формате.

  5. insertBytes

    void insertBytes(StatusType* status, unsigned char tag, const void* bytes, unsigned length)

    Вставляет clumplet со значением, содержащим переданные байты.

  6. insertTag

    void insertTag(StatusType* status, unsigned char tag)

    Вставляет clumplet без значения.

  7. isEof

    FB_BOOLEAN isEof(StatusType* status)

    Проверяет, нет ли текущего clumplet.

  8. moveNext

    void moveNext(StatusType* status)

    Переходит к следующему clumplet.

  9. rewind

    void rewind(StatusType* status)

    Переходит к первому clumplet.

  10. findFirst

    FB_BOOLEAN findFirst(StatusType* status, unsigned char tag)

    Находит первый clumplet с данным тегом.

  11. findNext

    FB_BOOLEAN findNext(StatusType* status)

    Находит следующий clumplet с заданным тегом.

  12. getTag

    unsigned char getTag(StatusType* status)

    Возвращает тег для текущего clumplet.

  13. getLength

    unsigned getLength(StatusType* status)

    Возвращает длину текущего значения clumplet.

  14. getInt

    int getInt(StatusType* status)

    Возвращает значение текущего clumplet как целое.

  15. getBigInt

    SC_INT64 getBigInt(StatusType* status)

    Возвращает значение текущего clumplet как 64-битное целое число.

  16. getString

    const char* getString(StatusType* status)

    Возвращает значение текущего clumplet как указатель на нуль-терминальнуюстроку (указатель действителен до следующего вызова этого метода).

  17. getBytes

    const unsigned char* getBytes(StatusType* status)

    Возвращает значение текущего clumplet как указатель на unsigned char.

  18. getBufferLength

    unsigned getBufferLength(StatusType* status)

    Возвращает длину блока параметров.

  19. getBuffer

    const unsigned char* getBuffer(StatusType* status)

    Возвращает указатель на блок параметров.

Константы, определенные интерфейсом IXpbBuilder

Допустимые типы построителей:

  • BATCH (IBatch parameters block)

  • BPB (BLOB parameters block)

  • DPB (database attachment parameters block)

  • SPB_ATTACH (service attachment parameters block)

  • SPB_START (start service parameters)

  • SPB_SEND (send items in IService::query())

  • SPB_RECEIVE (receive items in IService::query())

  • SPB_RESPONSE (response from IService::query())

  • TPB (transaction parameters block)

Плагин шифрования данных передаваемых по сети

Алгоритмы, выполняющие шифрование данных для разных целей, хорошоизвестны на протяжении многих лет. Единственной "маленькой" типичнойпроблемой остается то, где можно получить секретный ключ, который будетиспользоваться этим алгоритмом. К счастью для шифрования сетевоготрафика есть одно хорошее решение — уникальный ключ шифрования долженбыть сгенерирован плагином аутентификации. По крайней мере, по умолчаниюплагин SRP может создать такой ключ. Этот ключ устойчив к атакам, в томчисле с помощью "человека в середине" (man-in-the-middle). Поэтому дляплагина шифрования сетевого трафика был выбран следующий способпредоставления ключей: получать его от плагина проверки подлинности(аутентификации). (В случае, если используемый плагин аутентификации неможет предоставить ключ, псевдоплагин может быть добавлен в спискиAuthClient и AuthServer для создания ключей, что-то вроде двухасимметричных пар приватного и публичного.)

ICryptKey

Интерфейс ICryptKey используется для хранения ключа, предоставленногоплагином аутентификации, и передает его в плагин шифрования сетевоготрафика. Этот интерфейс следует использовать следующим образом: когдаплагин аутентификации сервера или клиента готов предоставить ключ, то онзапрашивает IServerBlock илиIClientBlock для создания новогоинтерфейса ICryptKey и хранит в нем ключ. Подходящий дляIWireCryptPlugin тип ключабудет выбран Firebird и передан этому интерфейсу.

  1. setSymmetric

    void setSymmetric(StatusType* status,
                      const char* type,
                      unsigned keyLength,
                      const void* key)

    сохраняет симметричный ключ заданного типа.

  2. setAsymmetric

    void setAsymmetric(StatusType* status,
                       const char* type,
                       unsigned encryptKeyLength,
                       const void* encryptKey,
                       unsigned decryptKeyLength,
                       const void* decryptKey)

    сохраняет пару асимметричных ключей заданного типа.

  3. getEncryptKey

    const void* getEncryptKey(unsigned* length)

    возвращает ключ для шифрования.

  4. getDecryptKey

    const void* getDecryptKey(unsigned* length))

    возвращает ключ для дешифрирования (в случае симметричного ключаполучается тот же результат, что и getEncryptKey()).

IWireCryptPlugin

Интерфейс IWireCryptPlugin является основным интерфейсом плагинасетевого шифрования. Как и любой другой такой интерфейс, он должен бытьреализован автором плагина.

  1. getKnownTypes

    const char* getKnownTypes(StatusType* status)

    возвращает список допустимых ключей, разделённыхпробелами/табуляциями/запятыми.

  2. setKey

    void setKey(StatusType* status, ICryptKey* key)

    плагин должен использовать ключ, переданный ему этим вызовом.

  3. encrypt

    void encrypt(StatusType* status,
                 unsigned length,
                 const void* from,
                 void* to)

    шифрует пакет, который должен быть отправлен по сети.

  4. decrypt

    void decrypt(StatusType* status,
                 unsigned length,
                 const void* from,
                 void* to)

    расшифровывает пакет, полученный из сети.

Плагин аутентификации на серверной стороне

Плагин аутентификации содержит две требуемые части — клиентскую исерверную, а также может содержать связанную с ним третью часть —менеджер пользователей. В процессе аутентификации клиент Firebirdвызывает клиентский плагин и отправляет сгенерированные им данные насервер, затем сервер вызывает серверный плагин и отправляетсгенерированные им данные клиенту. Этот процесс повторяется до тех пор,пока оба плагина возвращают код AUTH_MORE_DATA. AUTH_SUCCESS,возвращенный на стороне сервера, означает успешную аутентификацию,AUTH_FAILED с любой стороны — немедленное прерывание итеративногопроцесса и отказ, сообщаемый клиенту, AUTH_CONTINUE означает, чтодолжен быть проверен следующий плагин из списка настроенных плагиновпроверки подлинности.

Нет выделенных примеров плагинов для аутентификации, но в исходных кодахfirebird в каталоге src/auth можно найти плагин AuthDbg, с помощьюкоторого можно учиться на тривиальном примере (без сложных вычисленийкак, например, в Srp, и без вызовов сумасшедших функций WinAPI, таких,как в AuthSspi), как клиентская и серверная сторона выполняютаутентификацию (рукопожатие).

IAuth

Интерфейс IAuth не содержит методов, только некоторые константы,определяющие коды, возвращаются из метода authenticate() вIClient иIServer.

  • AUTH_FAILED

  • AUTH_SUCCESS

  • AUTH_MORE_DATA

  • AUTH_CONTINUE

IWriter

Интерфейс IWriter — записывает блок параметров аутентификации.

  1. reset

    void reset()

    очищает целевой блок.

  2. add

    void add(StatusType* status, const char* name)

    добавляет имя логина.

  3. setType

    void setType(StatusType* status, const char* value)

    устанавливает тип добавленного логина (пользователь, роль, группа ит.д.).

  4. setDb

    void setDb(StatusType* status, const char* value)

    устанавливает базу данных безопасности, в которой была выполненааутентификация.

IBlob

Интерфейс IBlob заменяет isc_blob_handle.

  1. getInfo

    void getInfo(StatusType* status,
                 unsigned itemsLength,
                 const unsigned char* items,
                 unsigned bufferLength,
                 unsigned char* buffer)

    заменяет isc_blob_info().

  2. getSegment

    int getSegment(StatusType* status,
                   unsigned bufferLength,
                   void* buffer,
                   unsigned* segmentLength)

    заменяет isc_get_segment(). В отличие от него никогда не возвращаютсяошибки isc_segstr_eof и isc_segment (которые на самом деле неявляются ошибками), вместо этого возвращаются коды завершенияIStatus::RESULT_NO_DATA и IStatus::RESULT_SEGMENT, обычно возвращаетIStatus::RESULT_OK.

  3. putSegment

    void putSegment(StatusType* status,
                    unsigned length,
                    const void* buffer)

    заменяет isc_put_segment().

  4. cancel

    void cancel(StatusType* status)

    заменяет isc_cancel_blob(). В случае успеха освобождает интерфейс.

  5. close

    void close(StatusType* status)

    заменяет isc_close_blob(). В случае успеха освобождает интерфейс.

  6. seek

    int seek(StatusType* status,
             int mode,
             int offset)

    заменяет isc_seek_blob().

IServerBlock

Интерфейс IServerBlock используется серверной частью модуляаутентификации для обмена данными с клиентом.

  1. getLogin

    const char* getLogin()

    возвращает имя пользователя, переданное от клиента.

  2. getData

    const unsigned char* getData(unsigned* length)

    возвращает данные аутентификации, переданные от клиента.

  3. putData

    void putData(StatusType* status, unsigned length, const void* data)

    передаёт данные аутентификации клиенту.

  4. newKey

    ICryptKey* newKey(StatusType* status)

    создаёт новый ключ шифрования и добавляет его в список доступных дляплагинов шифрования сетевого трафика.

IServer

Интерфейс IServer является основным интерфейсом серверной части плагинааутентификации.

  1. authenticate

    int authenticate(StatusType* status,
                     IServerBlock* sBlock,
                     IWriter* writerInterface)

    Выполняет один этап аутентификации. Обмен данными с клиентомосуществляется с использованием интерфейса sBlock. Когда создаетсянекоторый элемент аутентификации, его следует добавить в блокаутентификации с помощью writerInterface. Возможные значения возвратаопределяются в интерфейсе IAuth.

  2. setDbCryptCallback

    void setDbCryptCallback(StatusType* status, ICryptKeyCallback* cryptCallback)

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

Плагин аутентификации на клиентской стороне

IClientBlock

Интерфейс IClientBlock используется клиентской стороной модуляаутентификации для обмена данными с сервером.

  1. getLogin

    const char* getLogin()

    Возвращает имя пользователя, если оно присутствует в DPB.

  2. getPassword

    const char* getPassword()

    Возвращает пароль, если он присутствует в DPB.

  3. getData

    const unsigned char* getData(unsigned* length)

    Возвращает данные аутентификации, переданные с сервера.

  4. putData

    void putData(StatusType* status, unsigned length, const void* data)

    Передаёт данные аутентификации на сервер.

  5. newKey

    ICryptKey* newKey(StatusType* status)

    Создаёт новый ключ шифрования и добавляет его в список доступных дляплагинов шифрования сетевого трафика

  6. getAuthBlock

    IAuthBlock* getAuthBlock(StatusType* status)

IClient

Интерфейс IClient является основным интерфейсом клиентской сторонымодуля аутентификации.

  1. authenticate

    int authenticate(StatusType* status,
                     IClientBlock* cBlock)

    выполняет один этап аутентификации. Обмен данными с серверомосуществляется с использованием интерфейса cBlock. Возможные значениявозврата определяются в интерфейсе IAuth. AUTH_SUCCESS обрабатываетсяклиентской стороной как AUTH_MORE_DATA (т.е. клиент отправляетсгенерированные данные на сервер и ждет ответа от него).

Плагин управления пользователями

Этот плагин активно связан с серверной частью проверки подлинности — онподготавливает список пользователей для плагина аутентификации. Длякаждого плагина проверки подлинности требуется менеджер пользователей —некоторые из них могут получить доступ к списку пользователей, созданныхс использованием не Firebird программного обеспечения (например,AuthSspi). Запись, описывающая пользователя, состоит из несколькихполей, и поддерживать выполнение нескольких операций, таких какдобавление пользователя, изменение пользователя, получение спискапользователей и т. д. Плагин должен уметь интерпретировать команды,полученные в интерфейсе IUser.

IUserField

Интерфейс IUserField не используется как автономный интерфейс, онявляется базовым для ICharUserField и IIntUserField.

  1. entered

    int entered()

    возвращает ненулевое значение, если было введено (присвоено) значениедля поля.

  2. specified

    int specified()

    возвращает ненулевое значение, если для поля было присвоено значениеNULL.

  3. setEntered

    void setEntered(StatusType* status, int newValue)

    устанавливает entered флаг в 0 или ненулевое значение для поля. Нетспособа назначить NULL для поля, потому что он никогда не требуется.NULL, если они используются, назначаются реализациями интерфейсами и,следовательно, имеют полный доступ к их внутренним элементам.

ICharUserField

Интерфейс ICharUserField:

  1. get

    const char* get()

    возвращает значение поля как C-строку (\0 терминальную).

  2. set

    void set(StatusType* status, const char* newValue)

    присваивает значение полю. Устанавливает флаг entered в true.

IIntUserField

Интерфейс IIntUserField:

  1. get

    int get()

    возвращает значение поля.

  2. set

    void set(StatusType* status, int newValue)

    присваивает значение полю. Устанавливает флаг entered в true.

IUser

Интерфейс IUser — это список методов доступа к полям, включенным взапись о пользователе.

  1. operation

    unsigned operation()

    код операции (см. список ниже).

  2. userName

    ICharUserField* userName()

    имя пользователя.

  3. password

    ICharUserField* password()

    пароль.

  4. firstName

    ICharUserField* firstName()

    это и 2 следующие компоненты полного имени пользователя.

  5. lastName

    ICharUserField* lastName()
  6. middleName

    ICharUserField* middleName()
  7. comment

    ICharUserField* comment()

    комментарий (из SQL оператора COMMENT ON USER IS …).

  8. attributes

    ICharUserField* attributes()

    теги в форме tag1=val1, tag2=val2, …, tagN=valN. Val может бытьпустым, что означает, что тег будет удален.

  9. active

    IIntUserField* active()

    изменяет настройку ACTIVE/INACTIVE для пользователя.

  10. admin

    IIntUserField* admin()

    устанавливает/отменяет права администратора для пользователя.

  11. clear

    void clear(StatusType* status)

    устанавливает, что все поля не введены и не указаны.

Константы, определенные пользовательским интерфейсом — действующие кодыопераций.

  • OP_USER_ADD — добавление пользователя.

  • OP_USER_MODIFY — редактирование пользователя.

  • OP_USER_DELETE — удаление пользователя.

  • OP_USER_DISPLAY — отображение пользователя.

  • OP_USER_SET_MAP — включение отображения администраторов Windows нароль RDB$ADMIN.

  • OP_USER_DROP_MAP — выключение отображения администраторов Windows нароль RDB$ADMIN.

IListUsers

Интерфейс IListUsers — это обратный вызов, используемый плагиномпроверки подлинности при запросе списка пользователей. Плагин заполняетинтерфейс IUser для всех элементов всписке пользователей один за другим и для каждого пользователя вызываетметод list() этого интерфейса.

  1. list

    void list(StatusType* status, IUser* user)

    функция обратного вызова. Реализация может делать с полученными даннымито что хочет. Например, она может поместить данные из пользовательскогопараметра в выходной поток сервиса или разместить в специальных таблицахSEC$ группы.

ILogonInfo

Интерфейс ILogonInfo содержит данные, переданные плагину управленияпользователями для подключения к базе данных безопасности сдействительными учётными данными.

  1. name

    const char* name()

    возвращает имя пользователя текущего подключения.

  2. role

    const char* role()

    возвращает активную роль текущего подключения.

  3. networkProtocol

    const char* networkProtocol()

    возвращает сетевой протокол текущего подключения. В настоящее время неиспользуется плагинами.

  4. remoteAddress

    const char* remoteAddress()

    возвращает удаленный адрес текущего подключения. В настоящее время неиспользуется плагинами.

  5. authBlock

    const unsigned char* authBlock(unsigned* length)

    возвращает блок аутентификации текущего подключения. Если не NULLпереписывает имя пользователя.

IConfig

Интерфейс IConfig — общий интерфейс файла конфигурации.

  1. find

    IConfigEntry* find(StatusType* status, const char* name)

    Находит запись по имени.

  2. findValue

    IConfigEntry* findValue(StatusType* status, const char* name, const char* value)

    Находит запись по имени и значению

  3. findPos

    IConfigEntry* findPos(StatusType* status, const char* name, unsigned pos)

    Находит запись по имени и позиции. Если файл конфигурации содержитстроки:

    Db=DBA
    Db=DBB
    Db=DBC

    вызов findPos(status, "Db", 2) вернет запись со значением DBB.

IManagement

Интерфейс IManagement является основным интерфейсом плагина управленияпользователями.

  1. start

    void start(StatusType* status, ILogonInfo* logonInfo)

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

  2. execute

    int execute(StatusType* status, IUser* user, IListUsers* callback)

    выполняет команду, предоставляемую методом operation() параметра user.При необходимости будет использоваться интерфейс обратного вызова.Параметр callback может иметь значение NULL для команд, не требующихполучения списка пользователей.

  3. commit

    void commit(StatusType* status)

    подтверждает изменения, выполненные вызовами метода execute().

  4. rollback

    void rollback(StatusType* status)

    отменяет изменения, выполненные вызовами метода execute().

Плагин шифрования базы данных

Возможность шифрования базы данных присутствовала в Firebird со времёнInterbase, но соответствующие места в коде были закомментированы.Реализация была сомнительной — ключ шифрования всегда отправлялся отклиента в DPB, не было сделано попыток скрыть его от внешнего мира, и непредлагалось путей для шифрования существующих баз данных. Firebird 3.0решает большинство проблем, за исключением, вероятно, худшей — какуправлять ключами шифрования. Мы предлагаем различные типы решений, ноони требуют усилий в плагинах, т. е. нет красивого способа работы сключами как, например, для плагинов шифрования сетевого трафика.

Перед запуском с собственным плагином шифрования базы данных следуетпринять во внимание следующее. Мы видим два основных случая для которыхиспользуется шифрование базы данных — во-первых, может оно потребоватьсяизбежать утечки данных, если сервер базы данных физически украден, аво-вторых, оно может использоваться для защиты данных в базе данных,которая распространяется вместе со специальным приложением, обращающимсяк этим данным. Требования к этим случаям совершенно разные. В первомслучае мы можем доверять серверу базы данных, что он не модифицирован,чтобы красть ключи, переданные в плагин безопасности, то есть мыожидаем, что этот ключ не будет отправлен на неподходящий сервер. Вовтором случае сервер может быть каким-то образом модифицирован для кражиключей (если они передаются из приложения в плагин через код сервера)или даже данных (в качестве последнего места для снятия дампов из кэша,где они находятся в не зашифрованном виде). Поэтому ваш плагин долженубедиться, что он работает с не измененными двоичными файлами Firebird ивашим приложением перед отправкой ключа в плагин, например, плагин можетпотребоваться от них какой-то цифровой подписи. Кроме того, еслииспользуется сетевой доступ к серверу, то хорошей идеей являетсяпроверка того, что сетевой канал зашифрован (разбор выводаIUtil::getFbVersion()) или используется собственный ключ шифрования.Вся эта работа должна выполняться в плагине (и в приложении, работающимс ним), то есть алгоритм шифрования блока базы данных сам по себе можетоказаться наиболее простой частью плагина шифрования базы данных,особенно когда для него используется некоторая стандартная библиотека.

ICryptKeyCallback

Интерфейс ICryptKeyCallback должен обеспечивать передачу ключашифрования в плагин шифрования базы данных или плагин хранителя ключа.

  1. callback

    unsigned callback(unsigned dataLength,
                      const void* data,
                      unsigned bufferLength,
                      void* buffer)

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

IDbCryptInfo

Интерфейс IDbCryptInfo передается движку IDbCryptPlugin. Плагин можетсохранить этот интерфейс и использовать, когда это необходимо, дляполучения дополнительной информации о базе данных.

  1. getDatabaseFullPath

    const char* getDatabaseFullPath(StatusType* status)

    возвращает полное (включая путь) имя первичного файла базы данных.

IDbCryptPlugin

Интерфейс IDbCryptPlugin является основным интерфейсом плагинашифрования базы данных.

  1. setKey

    void setKey(StatusType* status,
                unsigned length,
                IKeyHolderPlugin** sources,
                const char* keyName)

    используется для предоставления информации плагину шифрования базыданных о ключе шифрования. Firebird никогда не передает ключи для этоготипа плагина напрямую. Вместо этого массивIKeyHolderPlugins заданнойдлины передается в плагин шифрования, который должен получить от одногоиз них интерфейсICryptKeyCallback и затемполучить ключ, используя его. Параметр keyName — это имя ключа, котороебыло введено в операторе ALTER DATABASE ENCRYPT …​.

  2. encrypt

    void encrypt(StatusType* status,
                 unsigned length,
                 const void* from,
                 void* to)

    шифрует данные перед записью блока в файл базы данных

  3. decrypt

    void decrypt(StatusType* status,
                 unsigned length,
                 const void* from,
                 void* to)

    расшифровывает данные после чтения блока из файла базы данных.

  4. setInfo

    void setInfo(StatusType* status,
                 IDbCryptInfo* info)

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

Хранитель ключа для плагина шифрования базы данных

Этот тип плагина необходим для разграничения функциональности — плагиншифрования базы данных имеет дело с фактическим шифрованием, держательключа решает вопросы, связанные с предоставлением ему ключа безопаснымспособом. Плагин может получить ключ из приложения или загрузить егокаким-либо другим способом (вплоть до использования флэш-устройства,вставленного в сервер при запуске Firebird).

IKeyHolderPlugin

Интерфейс IKeyHolderPlugin является основным интерфейсом для плагинахранения ключей шифрования.

  1. keyCallback

    int keyCallback(StatusType* status,
                    ICryptKeyCallback* callback)

    используется для передачи интерфейсаICryptKeyCallback вподключение (если он предоставляется пользователем с вызовомIProvider::setDbCryptCallback()). Этот вызов всегда выполняется в моментподключения к базе данных, и некоторые держатели ключа могут отклонитьподключение, если не был предоставлен удовлетворительный ключ.

  2. keyHandle

    ICryptKeyCallback* keyHandle(StatusType* status,
                                 const char* keyName)

    предназначен для непосредственного вызова интерфейсомIDbCryptPlugin для полученияинтерфейса обратного вызова для именованного ключа из держателя ключа.Это позволяет использовать код Firebird с открытым исходным кодом так,чтобы никогда не касаться фактических ключей, избегая возможности кражиключа, изменяющим код Firebird. После получения интерфейсаICryptKeyCallback плагиншифрования запускает обмен данными, используя его. Держатель ключа может(например) проверить цифровую подпись плагина шифрования перед отправкойему ключа, чтобы избежать использования модифицированного плагинашифрования, способного украсть секретный ключ.

  3. useOnlyOwnKeys

    FB_BOOLEAN useOnlyOwnKeys(StatusType* status)

    информирует Firebird о том, будет ли использоваться ключ,предоставленный другим держателем ключа, или нет. Имеет смысл только дляSuperServer — только он может делиться ключами шифрования базы данныхмежду подключениями. Возвращая FB_TRUE из этого метода, принудительнозаставляет Firebird убедиться, что этот конкретный держатель ключа (и,следовательно, связанное с ним подключение) предоставляет правильныйключ шифрования, прежде чем позволить ему работать с базой данных.

  4. chainHandle

    ICryptKeyCallback* chainHandle(StatusType* status)

    поддержка цепочки держателей ключей. В некоторых случаях ключ долженпроходить через более чем один держатель ключа, прежде чем он достигнетплагина шифрования базы данных. Это необходимо (например) для поддержкиEXECUTE STATEMENT в зашифрованной базе данных. Это всего лишь пример —цепочки также используются в некоторых других случаях. Интерфейсобратного вызова, возвращенный этим методом, может отличаться отвозвращаемого функцией keyHandle() (см. выше). Как правило, он должениметь возможность дублировать ключи один в один, полученные изIKeyHolderPlugin при вызове функции keyCallback().

IConfigManager

Интерфейс IConfigManager — общий интерфейс для доступа к различнымобъектам конфигурации.

  1. getDirectory

    const char* getDirectory(unsigned code)

    Возвращает местоположение соответствующего каталога в текущем экземпляреFirebird. См. коды каталогов для этого вызова ниже.

  2. getFirebirdConf

    IFirebirdConf* getFirebirdConf()

    Возвращает интерфейс для доступа к значениям конфигурации по умолчанию(из firebird.conf).

  3. getDatabaseConf

    IFirebirdConf* getDatabaseConf(const char* dbName)

    Возвращает интерфейс для доступа к конфигурации, специфичной для базыданных (берёт в расчёт firebird.conf и соответствующую частьdatabase.conf).

  4. getPluginConfig

    IConfig* getPluginConfig(const char* configuredPlugin)

    Возвращает интерфейс для доступа к конфигурации именованного плагина.

  5. getInstallDirectory

    const char* getInstallDirectory()

    Возвращает каталог, в котором установлен firebird.

  6. getRootDirectory

    const char* getRootDirectory()

    Возвращает корневой каталог текущего экземпляра, в случае с единственнымэкземпляром обычно совпадает с каталогом установки.

  7. getDefaultSecurityDb

    const char* getDefaultSecurityDb()

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

Коды каталогов:

  • DIR_BIN — bin (утилиты наподобие isql, gbak, gstat);

  • DIR_SBIN — sbin (fbguard и firebird сервер);

  • DIR_CONF — каталог файлов конфигурации (firebird.conf,databases.conf, plugins.conf);

  • DIR_LIB — lib (fbclient, ib_util);

  • DIR_INC — include (ibase.h, firebird/Interfaces.h);

  • DIR_DOC — каталог документации;

  • DIR_UDF — UDF (ib_udf, fbudf);

  • DIR_SAMPLE — каталог примеров;

  • DIR_SAMPLEDB — каталог, где расположена база данных примеров(employee.fdb);

  • DIR_HELP — qli help (help.fdb);

  • DIR_INTL — каталог библиотек интернационализации (fbintl);

  • DIR_MISC — различные файлы (как манифест деинсталлятора и другое);

  • DIR_SECDB — каталог, где расположена база данных безопасности(securityN.fdb);

  • DIR_MSG — каталог, где расположен файл сообщений (firebird.msg);

  • DIR_LOG — каталог, где расположен лог файл (firebird.log);

  • DIR_GUARD — каталог, где расположена блокировка хранителя (fb_guard);

  • DIR_PLUGINS — директория плагинов ([lib]Engine12.\{dll|so}).

IConfigEntry

Интерфейс IConfigEntry — представляет запись (Key = Values с возможнымиподзаголовками (подзаписями)) в файле конфигурации firebird.

  1. getName

    const char* getName()

    Возвращает имя ключа.

  2. getValue

    const char* getValue()

    Возвращает значение в качестве символьной строки.

  3. getIntValue

    ISC_INT64 getIntValue()

    Обрабатывает значение как целое и возвращает его.

  4. getBoolValue

    FB_BOOLEAN getBoolValue()

    Обрабатывает значение как boolean и возвращает его.

  5. getSubConfig

    IConfig* getSubConfig(StatusType* status)

    Рассматривает подзаголовки как отдельный файл конфигурации и возвращаетинтерфейс IConfig для него.

IDecFloat16

Интерфейс IDecFloat16 помогает работать с типом данных DECFLOAT(16).

  1. toBcd

    void toBcd(const FB_DEC16* from, int* sign, unsigned char* bcd, int* exp)

    Преобразует десятичное значение с плавающей запятой в BCD.

  2. toString

    void toString(StatusType* status, const FB_DEC16* from, unsigned bufferLength, char* buffer)

    Преобразует десятичное значение с плавающей запятой в строку.

  3. fromBcd

    void fromBcd(int sign, const unsigned char* bcd, int exp, FB_DEC16* to)

    Собирает десятичное значение с плавающей запятой из BCD.

  4. fromString

    void fromString(StatusType* status, const char* from, FB_DEC16* to)

    Собирает десятичное значение с плавающей запятой из строки.

IDecFloat34

Интерфейс IDecFloat34 помогает работать с типом данных DECFLOAT(34).

  1. toBcd

    void toBcd(const FB_DEC34* from, int* sign, unsigned char* bcd, int* exp)

    Преобразует десятичное значение с плавающей запятой в BCD.

  2. toString

    void toString(StatusType* status, const FB_DEC34* from, unsigned bufferLength, char* buffer)

    Преобразует десятичное значение с плавающей запятой в строку.

  3. fromBcd

    void fromBcd(int sign, const unsigned char* bcd, int exp, FB_DEC34* to)

    Собирает десятичное значение с плавающей запятой из BCD.

  4. fromString

    void fromString(StatusType* status, const char* from, FB_DEC34* to)

    Собирает десятичное значение с плавающей запятой из строки.

Не интерфейсные объекты, используемые в API

Note

Они находятся в специальном заголовке Message.h C++

Следующие 3 класса используются для представления типов DATE, TIME иTIMESTAMP (datetime) при использовании макроса FB_MESSAGE. Членыструктуры данных, представляющие статическое сообщение, соответствуютполям типов FB_DATE/FB_TIME/ FB_TIMESTAMP, будут иметь тип одного изэтих классов. Для получения доступа к полям даты и времени в статическихсообщениях необходимо знать методы и члены класса (которые достаточносамо описательны, чтобы не описывать их здесь).

FbDate

Методы класса FbDate:

  1. decode

    void decode(IUtil* util,
                unsigned* year,
                unsigned* month,
                unsigned* day)
  2. getYear

    unsigned getYear(IUtil* util)
  3. getMonth

    unsigned getMonth(IUtil* util)
  4. getDay

    unsigned getDay(IUtil* util)
  5. encode

    void encode(IUtil* util,
                unsigned year,
                unsigned month,
                unsigned day)

FbTime

Методы класса FbTime:

  1. decode

    void decode(IUtil* util,
                unsigned* hours,
                unsigned* minutes,
                unsigned* seconds,
                unsigned* fractions)
  2. getHours

    unsigned getHours(IUtil* util)
  3. getMinutes

    unsigned getMinutes(IUtil* util)
  4. getSeconds

    unsigned getSeconds(IUtil* util)
  5. getFractions

    unsigned getFractions(IUtil* util)
  6. encode

    void encode(IUtil* util,
                unsigned hours,
                unsigned minutes,
                unsigned seconds,
                unsigned fractions)

FbChar и FbVarChar

Следующие два шаблона используются в статических сообщениях дляпредставления полей CHAR(N) и VARCHAR(N).

template <unsigned N>
struct FbChar
{
    char str[N];
};
template <unsigned N>
struct FbVarChar
{
    ISC_USHORT length;
    char str[N];
    void set(const char* s);
};

Заключение

В этом документе отсутствуют три типа плагинов — ExternalEngine, Trace и Replicator.Информация о них будет доступна в следующем выпуске.