Использование макросов FB_MESSAGE для статических сообщений
Работа с данными с использованием смещений довольно эффективна, нотребует написания большого количества кода. В C++ эту проблему можнорешить с помощью шаблонов, но даже по сравнению с ними наиболее удобнымспособом работы с сообщением является представление его в родном (длязаданного языка) форме — структуре в C/C++, записи в Pascal и т. д.Конечно это работает только в том случае, если формат сообщения известензаранее. Для создания таких структур в C++ в Firebird существуетспециальный макрос FB_MESSAGE
.
FB_MESSAGE
имеет 3 аргумента: имя сообщения (структуры), тип обёрткистатуса (status wrapper) и список полей. Использование первого и второгоаргумента очевидно, список полей содержит пары (field_type, field_name)
,где field_type является одним из следующих:
-
FB_BIGINT
-
FB_BLOB
-
FB_BOOLEAN
-
FB_CHAR(len)
-
FB_DATE
-
FB_DECFLOAT16
-
FB_DECFLOAT34
-
FB_DOUBLE
-
FB_FLOAT
-
FB_INTEGER
-
FB_INTL_CHAR(len, charSet)
-
FB_INTL_VARCHAR(len, charSet)
-
FB_SCALED_BIGINT(x)
-
FB_SCALED_INTEGER(x)
-
FB_SCALED_SMALLINT(x)
-
FB_SMALLINT
-
FB_TIME
-
FB_TIME_TZ
-
FB_TIME_TZ_EX
-
FB_TIMESTAMP
-
FB_TIMESTAMP_TZ
-
FB_TIMESTAMP_TZ_EX
-
FB_VARCHAR(len)
В сгенерированной препроцессором структуре типы integer
и float
сопоставляются с соответствующими типами C, типы date
и time
— склассами FbDate
иFbTime
(все упомянутые здесь классынаходятся в пространстве имен Firebird), тип timestamp
— с классомFbTimestamp
, содержащим два публичныхчлена данных дату и время соответствующих классов, тип char
— соструктурой FbChar
и varchar
— со структуройFbVarChar
. Для каждого поля препроцессорсоздаст два члена данных — name для значения поля/параметра и nameNullдля индикатора NULL
. Конструктор сообщений имеет 2 параметра — указательна оболочку статуса (status wrapper) и главный интерфейс (masterinterface):
FB_MESSAGE(Output, ThrowStatusWrapper,
(FB_SMALLINT, relationId)
(FB_CHAR(31), relationName)
(FB_VARCHAR(100), description)
) output(&status, master);
Для статических сообщений использование FB_MESSAGE
является самым лучшимвыбором, в то же время они легко могут быть переданы в методы execute
,openCursor
и fetch
:
rs = att->openCursor(&status, tra, 0, sqlText,
SQL_DIALECT_V6, NULL, NULL, output.getMetadata(), NULL, 0);
и используется для работы со значениями отдельных полей:
while (rs->fetchNext(&status, output.getData()) == IStatus::RESULT_OK)
{
printf("%4d %31.31s %*.*s\n", output->relationId, output->relationName.str,
output->descriptionNull ? 0 : output->description.length,
output->descriptionNull ? 0 : output->description.length,
output->description.str);
}
Пример использования макроса FB_MESSAGE
для работы с сообщениямиприведен в примере 06.fb_message.cpp
.