32.12. Функции разного назначения #
Как всегда, находятся функции, которые не попадают ни в одну из категорий.
PQfreemem
#Освобождает память, которую выделила libpq.
void PQfreemem(void *ptr);
Освобождает память, выделенную библиотекой libpq, а именно функциями
PQescapeByteaConn
,PQescapeBytea
,PQunescapeBytea
иPQnotifies
. Особенно важно использовать именно эту функцию, а неfree()
, в Microsoft Windows. Это связано с тем, что выделение памяти в DLL и освобождение её в приложении будет работать, только если флаги многопоточной/однопоточной, выпускаемой/отладочной или статической/динамической сборки для DLL и приложения полностью совпадают. На других платформах эта функция действует так же, как стандартная библиотечная функцияfree()
.PQconninfoFree
#Освобождает структуры данных, выделенные функциями
PQconndefaults
иPQconninfoParse
.void PQconninfoFree(PQconninfoOption *connOptions);
Если аргумент является указателем
NULL
, операция не выполняется.Простая функция
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
, а соответствующее сообщение помещается в объект соединения.PQchangePassword
#Меняет пароль PostgreSQL.
PGresult *PQchangePassword(PGconn *conn, const char *user, const char *passwd);
Данная функция использует
PQencryptPasswordConn
для создания и выполнения командыALTER USER ... PASSWORD '...'
, что приводит к изменению пароля. Она используется для того же, что иPQencryptPasswordConn
, но является предпочтительней, поскольку и создаёт, и выполняет команду. ФункцииPQencryptPasswordConn
передаётсяNULL
в качестве аргумента алгоритма, таким образом шифрование происходит в соответствии с конфигурацией сервера password_encryption.В аргументах
passwd
иuser
задаётся пароль в открытом виде и SQL-имя пользователя, для которого он задаётся.Возвращает указатель на
PGresult
как результат выполнения командыALTER USER
или, возможно, пустой указатель (null), если произошёл сбой до запуска команды. Для проверки возвращаемого значения на наличие ошибок следует вызвать функциюPQresultStatus
(в случае нулевого указателя она возвратитPGRES_FATAL_ERROR
). Для получения дополнительной информации о таких ошибках используйте функциюPQerrorMessage
.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
(см. Раздел 32.14) для каждой процедуры событий, зарегистрированной в объекте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
— событий из исходного объекта результата. (Но любые данные, связанные с экземпляром исходного объекта, не копируются.) Процедуры событий получают событияPGEVT_RESULTCOPY
.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 или новее.
PQgetCurrentTimeUSec
#Выдаёт текущее время в микросекундах в формате Unix (то есть
time_t
, умноженное на 1 миллион).pg_usec_time_t PQgetCurrentTimeUSec(void);
Главным образом это удобно для расчёта тайм-аута для использования с функцией
PQsocketPoll
.