33.11. Функции разного назначения

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

PQfreemem

Освобождает память, которую выделила libpq.

void PQfreemem(void *ptr);

Освобождает память, выделенную библиотекой libpq, а именно функциями PQescapeByteaConn, PQescapeBytea, PQunescapeBytea и PQnotifies. Особенно важно использовать именно эту функцию, а не free(), в Microsoft Windows. Это связано с тем, что выделение памяти в DLL и освобождение её в приложении будет работать, только если флаги многопоточной/однопоточной, выпускаемой/отладочной или статической/динамической сборки для DLL и приложения полностью совпадают. На других платформах эта функция действует так же, как стандартная библиотечная функция free().

PQconninfoFree

Освобождает структуры данных, выделенные функциями PQconndefaults и PQconninfoParse.

void PQconninfoFree(PQconninfoOption *connOptions);

Простая функция PQfreemem не подойдёт для этого, так как эти структуры содержат ссылки на подчинённые строки.

PQencryptPasswordConn

Подготавливает зашифрованную форму пароля PostgreSQL.

char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm);

Эта функция предназначена для клиентских приложений, желающих передавать команды вида ALTER USER joe PASSWORD 'pwd'. В такой команде лучше не передавать исходный пароль открытым текстом, так как он может появиться в журналах команд, мониторе активности и т. д. Вместо этого воспользуйтесь данной функцией и переведите пароль в зашифрованную форму.

В аргументах passwd и user задаётся пароль в открытом виде и SQL-имя пользователя, для которого он задаётся. В аргументе algorithm задаётся алгоритм для шифрования пароля. В настоящее время поддерживаются алгоритмы md5 и scram-sha-256 (в качестве альтернативных обозначений md5 для совместимости со старыми версиями сервера поддерживаются значения on и off). Заметьте, что поддержка scram-sha-256 появилась в PostgreSQL версии 10 и со старыми версиями серверов этот вариант работать не будет. Если algorithm равен NULL, эта функция запросит у сервера текущее значение параметра password_encryption. При этом возможна блокировка и отказ при выполнении функции, если текущая транзакция прерывается или если в текущем соединении выполняется другой запрос. Если вы хотите использовать алгоритм по умолчанию для данного сервера, но при этом избежать блокировки, получите значение password_encryption самостоятельно до вызова PQencryptPasswordConn и передайте его в параметре algorithm.

Эта функция возвращает строку, выделенную функцией malloc. Вызывающий код может рассчитывать на то, что эта строка не содержит никаких спецсимволов, требующих экранирования. Закончив работу с ней, освободите память, вызвав PQfreemem. В случае ошибки эта функция возвращает NULL, а соответствующее сообщение помещается в объект соединения.

PQencryptPassword

Подготавливает зашифрованную md5 форму пароля PostgreSQL.

char *PQencryptPassword(const char *passwd, const char *user);

PQencryptPassword — старая, подлежащая ликвидации версия PQencryptPasswordConn. Отличие состоит в том, что для PQencryptPassword не требуется объект соединения, а в качестве алгоритма шифрования всегда используется md5.

PQmakeEmptyPGresult

Конструирует пустой объект PGresult с указанным состоянием.

PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);

Это внутренняя функция libpq, выделяющая память и инициализирующая пустой объект PGresult. Эта функция возвращает NULL, если не может выделить память. Она сделана экспортируемой, так как некоторые приложения находят полезным создавать объекты результатов (в частности, объекты с состоянием ошибки) самостоятельно. Если в conn передаётся не null и status указывает на ошибку, в PGresult копируется текущее сообщение об ошибке для заданного соединения. Также, если в conn передаётся не null, в PGresult копируются все процедуры событий, зарегистрированные для этого соединения. (При этом вызовы PGEVT_RESULTCREATE не выполняются; см. описание PQfireResultCreateEvents.) Заметьте, что в конце для этого объекта следует вызвать PQclear, как и для объекта PGresult, возвращённого самой библиотекой libpq.

PQfireResultCreateEvents

Вызывает событие PGEVT_RESULTCREATE (см. Раздел 33.13) для каждой процедуры событий, зарегистрированной в объекте PGresult. Возвращает ненулевое значение в случае успеха или ноль в случае ошибки в одной из процедур.

int PQfireResultCreateEvents(PGconn *conn, PGresult *res);

Аргумент conn передаётся процедурам событий, но непосредственно не используется. Он может быть равен NULL, если он не нужен процедурам событий.

Процедуры событий, уже получившие событие PGEVT_RESULTCREATE или PGEVT_RESULTCOPY для этого объекта, больше не вызываются.

Основная причина отделения этой функции от PQmakeEmptyPGresult в том, что часто требуется создать объект PGresult и наполнить его данными, прежде чем вызывать процедуры событий.

PQcopyResult

Создаёт копию объекта PGresult. Эта копия никак не связана с исходным результатом и поэтому, когда она становится не нужна, необходимо вызвать PQclear. Если функция завершается ошибкой, она возвращает NULL.

PGresult *PQcopyResult(const PGresult *src, int flags);

Создаваемая копия не будет точной. В возвращаемый результат всегда помещается состояние PGRES_TUPLES_OK и в него не копируются никакие сообщения об ошибках из исходного объекта. (Однако в него копируется строка состояния команды.) Что ещё в него будет копироваться, определяет аргумент flags, в котором складываются несколько флагов. Флаг PG_COPYRES_ATTRS включает копирование атрибутов исходного объекта (определений столбцов), а флаг PG_COPYRES_TUPLES включает копирование кортежей из исходного объекта (при этом также копируются и атрибуты.) Флаг PG_COPYRES_NOTICEHOOKS включает копирование обработчиков замечаний, а флаг PG_COPYRES_EVENTS — событий из исходного объекта результата. (Но любые данные, связанные с экземпляром исходного объекта, не копируются.)

PQsetResultAttrs

Устанавливает атрибуты объекта PGresult.

int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs);

Предоставленная структура attDescs копируется в результат. Если указатель attDescs равен NULL или numAttributes меньше одного, запрос игнорируется и функция выполняется без ошибки. Если res уже содержит атрибуты, функция завершается ошибкой. В случае ошибки функция возвращает ноль, а в обратном случае — ненулевое значение.

PQsetvalue

Устанавливает значение поля кортежа в объекте PGresult.

int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len);

Эта функция автоматически увеличивает внутренний массив кортежей при необходимости. Однако значение tup_num должно быть меньше или равно PQntuples, что означает, что эта функция может увеличивать массив кортежей только на один кортеж. Но в существующем кортеже любые поля могут изменяться в любом порядке. Если значение в поле с номером field_num уже существует, оно будет перезаписано. Если len равно -1 или value равно NULL, в поле будет записано значение SQL NULL. Устанавливаемое значение (value) копируется в закрытую область объекта результата, так что от него можно избавиться после завершения функции. Если функция завершается ошибкой, она возвращает ноль, а в обратном случае — ненулевое значение.

PQresultAlloc

Выделяет подчинённую область памяти для объекта PGresult.

void *PQresultAlloc(PGresult *res, size_t nBytes);

Любая память, выделенная этой функцией, будет освобождена при очистке объекта res. В случае ошибки эта функция возвращает NULL. Результат гарантированно выравнивается должным образом для любого типа данных, как и при malloc.

PQresultMemorySize

Выдаёт объём памяти (в байтах), выделенной для объекта PGresult.

size_t PQresultMemorySize(const PGresult *res);

Этот объём равен сумме размеров всех запросов malloc, связанных с данным объектом PGresult, то есть это общий объём памяти, который будет освобождён функцией PQclear. Данная информация может быть полезна для управления потреблением памяти.

PQlibVersion

Возвращает версию используемой библиотеки libpq.

int PQlibVersion(void);

По результату этой функции можно во время выполнения определить, предоставляется ли определённая функциональность загруженной в данный момент версией libpq. Эта функция может использоваться, например, чтобы понять, какие параметры соединения может принять PQconnectdb.

Это число формируется в результате умножения номера основной версии библиотеки на 10000 и добавления номера дополнительной версии. Например, для версии 10.1 будет выдано 100001, а для версии 11.0 — 110000.

До версии 10, в PostgreSQL номера версий образовывались из трёх чисел, первые два из которых представляли основную версию. Для таких версий PQlibVersion отводит на каждое число по две цифры; например, для версии 9.1.5 будет выдано 90105, а для версии 9.2.0 — 90200.

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

Примечание

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