/ext/pgsql/pgsql.c
C | 7202 lines | 5778 code | 805 blank | 619 comment | 1478 complexity | 38495fc75f0dc23018d5a5adc7c27896 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /*
- +----------------------------------------------------------------------+
- | Copyright (c) The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Zeev Suraski <zeev@php.net> |
- | Jouni Ahto <jouni.ahto@exdec.fi> |
- | Yasuo Ohgaki <yohgaki@php.net> |
- | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) |
- | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) |
- +----------------------------------------------------------------------+
- */
- #include <stdlib.h>
- #define PHP_PGSQL_PRIVATE 1
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #define SMART_STR_PREALLOC 512
- #include "php.h"
- #include "php_ini.h"
- #include "ext/standard/php_standard.h"
- #include "zend_smart_str.h"
- #include "ext/pcre/php_pcre.h"
- #ifdef PHP_WIN32
- # include "win32/time.h"
- #endif
- #include "php_pgsql.h"
- #include "php_globals.h"
- #include "zend_exceptions.h"
- #if HAVE_PGSQL
- #ifndef InvalidOid
- #define InvalidOid ((Oid) 0)
- #endif
- #define PGSQL_ASSOC 1<<0
- #define PGSQL_NUM 1<<1
- #define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM)
- #define PGSQL_NOTICE_LAST 1 /* Get the last notice */
- #define PGSQL_NOTICE_ALL 2 /* Get all notices */
- #define PGSQL_NOTICE_CLEAR 3 /* Remove notices */
- #define PGSQL_STATUS_LONG 1
- #define PGSQL_STATUS_STRING 2
- #define PGSQL_MAX_LENGTH_OF_LONG 30
- #define PGSQL_MAX_LENGTH_OF_DOUBLE 60
- #if ZEND_LONG_MAX < UINT_MAX
- #define PGSQL_RETURN_OID(oid) do { \
- if (oid > ZEND_LONG_MAX) { \
- smart_str s = {0}; \
- smart_str_append_unsigned(&s, oid); \
- smart_str_0(&s); \
- RETURN_NEW_STR(s.s); \
- } \
- RETURN_LONG((zend_long)oid); \
- } while(0)
- #else
- #define PGSQL_RETURN_OID(oid) RETURN_LONG((zend_long)oid)
- #endif
- #if HAVE_PQSETNONBLOCKING
- #define PQ_SETNONBLOCKING(pg_link, flag) PQsetnonblocking(pg_link, flag)
- #else
- #define PQ_SETNONBLOCKING(pg_link, flag) 0
- #endif
- #define CHECK_DEFAULT_LINK(x) if ((x) == NULL) { php_error_docref(NULL, E_WARNING, "No PostgreSQL link opened yet"); RETURN_FALSE; }
- #define FETCH_DEFAULT_LINK() PGG(default_link)
- #ifndef HAVE_PQFREEMEM
- #define PQfreemem free
- #endif
- ZEND_DECLARE_MODULE_GLOBALS(pgsql)
- static PHP_GINIT_FUNCTION(pgsql);
- /* {{{ arginfo */
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1)
- ZEND_ARG_INFO(0, connection_string)
- ZEND_ARG_INFO(0, connect_type)
- ZEND_ARG_INFO(0, host)
- ZEND_ARG_INFO(0, port)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, tty)
- ZEND_ARG_INFO(0, database)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_pconnect, 0, 0, 1)
- ZEND_ARG_INFO(0, connection_string)
- ZEND_ARG_INFO(0, host)
- ZEND_ARG_INFO(0, port)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, tty)
- ZEND_ARG_INFO(0, database)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect_poll, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #if HAVE_PQPARAMETERSTATUS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_parameter_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, param_name)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_close, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_dbname, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_error, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_options, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_port, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_tty, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_host, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_version, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_ping, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #if HAVE_PQEXECPARAMS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query_params, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQPREPARE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_prepare, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQEXECPREPARED
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_execute, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_rows, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_fields, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #if HAVE_PQCMDTUPLES
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_affected_rows, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, option)
- ZEND_END_ARG_INFO()
- #ifdef HAVE_PQFTABLE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_table, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_ARG_INFO(0, oid_only)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_name, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_size, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_type_oid, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_num, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, field_name)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_result, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row_number)
- ZEND_ARG_INFO(0, field_name)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_row, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_assoc, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_array, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_object, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, class_name)
- ZEND_ARG_INFO(0, l)
- ZEND_ARG_INFO(0, ctor_params)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, column_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_seek, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, offset)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_prtlen, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, field_name_or_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_field_is_null, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, row)
- ZEND_ARG_INFO(0, field_name_or_number)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_free_result, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_oid, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_trace, 0, 0, 1)
- ZEND_ARG_INFO(0, filename)
- ZEND_ARG_INFO(0, mode)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_untrace, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_create, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_id)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_unlink, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_open, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_ARG_INFO(0, mode)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_close, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, len)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_write, 0, 0, 2)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, buf)
- ZEND_ARG_INFO(0, len)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_read_all, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_import, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, filename)
- ZEND_ARG_INFO(0, large_object_oid)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_export, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, objoid)
- ZEND_ARG_INFO(0, filename)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_seek, 0, 0, 2)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, offset)
- ZEND_ARG_INFO(0, whence)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_tell, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_END_ARG_INFO()
- #if HAVE_PG_LO_TRUNCATE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_lo_truncate, 0, 0, 1)
- ZEND_ARG_INFO(0, large_object)
- ZEND_ARG_INFO(0, size)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_error_verbosity, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, verbosity)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQCLIENTENCODING
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_set_client_encoding, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, encoding)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_client_encoding, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_end_copy, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_put_line, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_to, 0, 0, 2)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, table_name)
- ZEND_ARG_INFO(0, delimiter)
- ZEND_ARG_INFO(0, null_as)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_copy_from, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, table_name)
- ZEND_ARG_INFO(0, rows)
- ZEND_ARG_INFO(0, delimiter)
- ZEND_ARG_INFO(0, null_as)
- ZEND_END_ARG_INFO()
- #if HAVE_PQESCAPE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_string, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_bytea, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_unescape_bytea, 0, 0, 1)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQESCAPE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_literal, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_escape_identifier, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, data)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_END_ARG_INFO()
- #if HAVE_PQRESULTERRORFIELD
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_error_field, 0, 0, 2)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, fieldcode)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #if HAVE_PGTRANSACTIONSTATUS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_transaction_status, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_reset, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_cancel_query, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connection_busy, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query, 0, 0, 2)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #if HAVE_PQSENDQUERYPARAMS
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_query_params, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, query)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSENDPREPARE
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_prepare, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, query)
- ZEND_END_ARG_INFO()
- #endif
- #if HAVE_PQSENDQUERYPREPARED
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_send_execute, 0, 0, 3)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, stmtname)
- ZEND_ARG_INFO(0, params)
- ZEND_END_ARG_INFO()
- #endif
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_result, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_result_status, 0, 0, 1)
- ZEND_ARG_INFO(0, result)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_notify, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_ARG_INFO(0, e)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_pid, 0, 0, 0)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_socket, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_consume_input, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_flush, 0, 0, 1)
- ZEND_ARG_INFO(0, connection)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_meta_data, 0, 0, 2)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_convert, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, values)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_insert, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, values)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_update, 0, 0, 4)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, fields)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_delete, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_select, 0, 0, 3)
- ZEND_ARG_INFO(0, db)
- ZEND_ARG_INFO(0, table)
- ZEND_ARG_INFO(0, ids)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, result_type)
- ZEND_END_ARG_INFO()
- /* }}} */
- /* {{{ pgsql_functions[]
- */
- static const zend_function_entry pgsql_functions[] = {
- /* connection functions */
- PHP_FE(pg_connect, arginfo_pg_connect)
- PHP_FE(pg_pconnect, arginfo_pg_pconnect)
- PHP_FE(pg_connect_poll, arginfo_pg_connect_poll)
- PHP_FE(pg_close, arginfo_pg_close)
- PHP_FE(pg_connection_status, arginfo_pg_connection_status)
- PHP_FE(pg_connection_busy, arginfo_pg_connection_busy)
- PHP_FE(pg_connection_reset, arginfo_pg_connection_reset)
- PHP_FE(pg_host, arginfo_pg_host)
- PHP_FE(pg_dbname, arginfo_pg_dbname)
- PHP_FE(pg_port, arginfo_pg_port)
- PHP_FE(pg_tty, arginfo_pg_tty)
- PHP_FE(pg_options, arginfo_pg_options)
- PHP_FE(pg_version, arginfo_pg_version)
- PHP_FE(pg_ping, arginfo_pg_ping)
- #if HAVE_PQPARAMETERSTATUS
- PHP_FE(pg_parameter_status, arginfo_pg_parameter_status)
- #endif
- #if HAVE_PGTRANSACTIONSTATUS
- PHP_FE(pg_transaction_status, arginfo_pg_transaction_status)
- #endif
- /* query functions */
- PHP_FE(pg_query, arginfo_pg_query)
- #if HAVE_PQEXECPARAMS
- PHP_FE(pg_query_params, arginfo_pg_query_params)
- #endif
- #if HAVE_PQPREPARE
- PHP_FE(pg_prepare, arginfo_pg_prepare)
- #endif
- #if HAVE_PQEXECPREPARED
- PHP_FE(pg_execute, arginfo_pg_execute)
- #endif
- PHP_FE(pg_send_query, arginfo_pg_send_query)
- #if HAVE_PQSENDQUERYPARAMS
- PHP_FE(pg_send_query_params, arginfo_pg_send_query_params)
- #endif
- #if HAVE_PQSENDPREPARE
- PHP_FE(pg_send_prepare, arginfo_pg_send_prepare)
- #endif
- #if HAVE_PQSENDQUERYPREPARED
- PHP_FE(pg_send_execute, arginfo_pg_send_execute)
- #endif
- PHP_FE(pg_cancel_query, arginfo_pg_cancel_query)
- /* result functions */
- PHP_FE(pg_fetch_result, arginfo_pg_fetch_result)
- PHP_FE(pg_fetch_row, arginfo_pg_fetch_row)
- PHP_FE(pg_fetch_assoc, arginfo_pg_fetch_assoc)
- PHP_FE(pg_fetch_array, arginfo_pg_fetch_array)
- PHP_FE(pg_fetch_object, arginfo_pg_fetch_object)
- PHP_FE(pg_fetch_all, arginfo_pg_fetch_all)
- PHP_FE(pg_fetch_all_columns, arginfo_pg_fetch_all_columns)
- #if HAVE_PQCMDTUPLES
- PHP_FE(pg_affected_rows,arginfo_pg_affected_rows)
- #endif
- PHP_FE(pg_get_result, arginfo_pg_get_result)
- PHP_FE(pg_result_seek, arginfo_pg_result_seek)
- PHP_FE(pg_result_status,arginfo_pg_result_status)
- PHP_FE(pg_free_result, arginfo_pg_free_result)
- PHP_FE(pg_last_oid, arginfo_pg_last_oid)
- PHP_FE(pg_num_rows, arginfo_pg_num_rows)
- PHP_FE(pg_num_fields, arginfo_pg_num_fields)
- PHP_FE(pg_field_name, arginfo_pg_field_name)
- PHP_FE(pg_field_num, arginfo_pg_field_num)
- PHP_FE(pg_field_size, arginfo_pg_field_size)
- PHP_FE(pg_field_type, arginfo_pg_field_type)
- PHP_FE(pg_field_type_oid, arginfo_pg_field_type_oid)
- PHP_FE(pg_field_prtlen, arginfo_pg_field_prtlen)
- PHP_FE(pg_field_is_null,arginfo_pg_field_is_null)
- #ifdef HAVE_PQFTABLE
- PHP_FE(pg_field_table, arginfo_pg_field_table)
- #endif
- /* async message function */
- PHP_FE(pg_get_notify, arginfo_pg_get_notify)
- PHP_FE(pg_socket, arginfo_pg_socket)
- PHP_FE(pg_consume_input,arginfo_pg_consume_input)
- PHP_FE(pg_flush, arginfo_pg_flush)
- PHP_FE(pg_get_pid, arginfo_pg_get_pid)
- /* error message functions */
- PHP_FE(pg_result_error, arginfo_pg_result_error)
- #if HAVE_PQRESULTERRORFIELD
- PHP_FE(pg_result_error_field, arginfo_pg_result_error_field)
- #endif
- PHP_FE(pg_last_error, arginfo_pg_last_error)
- PHP_FE(pg_last_notice, arginfo_pg_last_notice)
- /* copy functions */
- PHP_FE(pg_put_line, arginfo_pg_put_line)
- PHP_FE(pg_end_copy, arginfo_pg_end_copy)
- PHP_FE(pg_copy_to, arginfo_pg_copy_to)
- PHP_FE(pg_copy_from, arginfo_pg_copy_from)
- /* debug functions */
- PHP_FE(pg_trace, arginfo_pg_trace)
- PHP_FE(pg_untrace, arginfo_pg_untrace)
- /* large object functions */
- PHP_FE(pg_lo_create, arginfo_pg_lo_create)
- PHP_FE(pg_lo_unlink, arginfo_pg_lo_unlink)
- PHP_FE(pg_lo_open, arginfo_pg_lo_open)
- PHP_FE(pg_lo_close, arginfo_pg_lo_close)
- PHP_FE(pg_lo_read, arginfo_pg_lo_read)
- PHP_FE(pg_lo_write, arginfo_pg_lo_write)
- PHP_FE(pg_lo_read_all, arginfo_pg_lo_read_all)
- PHP_FE(pg_lo_import, arginfo_pg_lo_import)
- PHP_FE(pg_lo_export, arginfo_pg_lo_export)
- PHP_FE(pg_lo_seek, arginfo_pg_lo_seek)
- PHP_FE(pg_lo_tell, arginfo_pg_lo_tell)
- #if HAVE_PG_LO_TRUNCATE
- PHP_FE(pg_lo_truncate, arginfo_pg_lo_truncate)
- #endif
- /* utility functions */
- #if HAVE_PQESCAPE
- PHP_FE(pg_escape_string, arginfo_pg_escape_string)
- PHP_FE(pg_escape_bytea, arginfo_pg_escape_bytea)
- PHP_FE(pg_unescape_bytea, arginfo_pg_unescape_bytea)
- PHP_FE(pg_escape_literal, arginfo_pg_escape_literal)
- PHP_FE(pg_escape_identifier, arginfo_pg_escape_identifier)
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- PHP_FE(pg_set_error_verbosity, arginfo_pg_set_error_verbosity)
- #endif
- #if HAVE_PQCLIENTENCODING
- PHP_FE(pg_client_encoding, arginfo_pg_client_encoding)
- PHP_FE(pg_set_client_encoding, arginfo_pg_set_client_encoding)
- #endif
- /* misc function */
- PHP_FE(pg_meta_data, arginfo_pg_meta_data)
- PHP_FE(pg_convert, arginfo_pg_convert)
- PHP_FE(pg_insert, arginfo_pg_insert)
- PHP_FE(pg_update, arginfo_pg_update)
- PHP_FE(pg_delete, arginfo_pg_delete)
- PHP_FE(pg_select, arginfo_pg_select)
- /* aliases for downwards compatibility */
- PHP_FALIAS(pg_exec, pg_query, arginfo_pg_query)
- PHP_FALIAS(pg_getlastoid, pg_last_oid, arginfo_pg_last_oid)
- #if HAVE_PQCMDTUPLES
- PHP_FALIAS(pg_cmdtuples, pg_affected_rows, arginfo_pg_affected_rows)
- #endif
- PHP_FALIAS(pg_errormessage, pg_last_error, arginfo_pg_last_error)
- PHP_FALIAS(pg_numrows, pg_num_rows, arginfo_pg_num_rows)
- PHP_FALIAS(pg_numfields, pg_num_fields, arginfo_pg_num_fields)
- PHP_FALIAS(pg_fieldname, pg_field_name, arginfo_pg_field_name)
- PHP_FALIAS(pg_fieldsize, pg_field_size, arginfo_pg_field_size)
- PHP_FALIAS(pg_fieldtype, pg_field_type, arginfo_pg_field_type)
- PHP_FALIAS(pg_fieldnum, pg_field_num, arginfo_pg_field_num)
- PHP_FALIAS(pg_fieldprtlen, pg_field_prtlen, arginfo_pg_field_prtlen)
- PHP_FALIAS(pg_fieldisnull, pg_field_is_null, arginfo_pg_field_is_null)
- PHP_FALIAS(pg_freeresult, pg_free_result, arginfo_pg_free_result)
- PHP_FALIAS(pg_result, pg_fetch_result, arginfo_pg_get_result)
- PHP_FALIAS(pg_loreadall, pg_lo_read_all, arginfo_pg_lo_read_all)
- PHP_FALIAS(pg_locreate, pg_lo_create, arginfo_pg_lo_create)
- PHP_FALIAS(pg_lounlink, pg_lo_unlink, arginfo_pg_lo_unlink)
- PHP_FALIAS(pg_loopen, pg_lo_open, arginfo_pg_lo_open)
- PHP_FALIAS(pg_loclose, pg_lo_close, arginfo_pg_lo_close)
- PHP_FALIAS(pg_loread, pg_lo_read, arginfo_pg_lo_read)
- PHP_FALIAS(pg_lowrite, pg_lo_write, arginfo_pg_lo_write)
- PHP_FALIAS(pg_loimport, pg_lo_import, arginfo_pg_lo_import)
- PHP_FALIAS(pg_loexport, pg_lo_export, arginfo_pg_lo_export)
- #if HAVE_PQCLIENTENCODING
- PHP_FALIAS(pg_clientencoding, pg_client_encoding, arginfo_pg_client_encoding)
- PHP_FALIAS(pg_setclientencoding, pg_set_client_encoding, arginfo_pg_set_client_encoding)
- #endif
- PHP_FE_END
- };
- /* }}} */
- /* {{{ pgsql_module_entry
- */
- zend_module_entry pgsql_module_entry = {
- STANDARD_MODULE_HEADER,
- "pgsql",
- pgsql_functions,
- PHP_MINIT(pgsql),
- PHP_MSHUTDOWN(pgsql),
- PHP_RINIT(pgsql),
- PHP_RSHUTDOWN(pgsql),
- PHP_MINFO(pgsql),
- PHP_PGSQL_VERSION,
- PHP_MODULE_GLOBALS(pgsql),
- PHP_GINIT(pgsql),
- NULL,
- NULL,
- STANDARD_MODULE_PROPERTIES_EX
- };
- /* }}} */
- #ifdef COMPILE_DL_PGSQL
- #ifdef ZTS
- ZEND_TSRMLS_CACHE_DEFINE()
- #endif
- ZEND_GET_MODULE(pgsql)
- #endif
- static int le_link, le_plink, le_result, le_lofp, le_string;
- /* Compatibility definitions */
- #ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
- #define pg_encoding_to_char(x) "SQL_ASCII"
- #endif
- #if !HAVE_PQESCAPE_CONN
- #define PQescapeStringConn(conn, to, from, len, error) PQescapeString(to, from, len)
- #endif
- #if HAVE_PQESCAPELITERAL
- #define PGSQLescapeLiteral(conn, str, len) PQescapeLiteral(conn, str, len)
- #define PGSQLescapeIdentifier(conn, str, len) PQescapeIdentifier(conn, str, len)
- #define PGSQLfree(a) PQfreemem(a)
- #else
- #define PGSQLescapeLiteral(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 0)
- #define PGSQLescapeLiteral2(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 1)
- #define PGSQLescapeIdentifier(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 0, 0)
- #define PGSQLfree(a) efree(a)
- /* emulate libpq's PQescapeInternal() 9.0 or later */
- static char *php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) /* {{{ */
- {
- char *result, *rp, *s;
- if (!conn) {
- return NULL;
- }
- /* allocate enough memory */
- rp = result = (char *)safe_emalloc(len, 2, 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */
- if (escape_literal) {
- if (safe) {
- size_t new_len;
- char *tmp = (char *)safe_emalloc(len, 2, 1);
- *rp++ = '\'';
- /* PQescapeString does not escape \, but it handles multibyte chars safely.
- This escape is incompatible with PQescapeLiteral. */
- new_len = PQescapeStringConn(conn, tmp, str, len, NULL);
- strncpy(rp, tmp, new_len);
- efree(tmp);
- rp += new_len;
- } else {
- char *encoding;
- size_t tmp_len;
- /* This is compatible with PQescapeLiteral, but it cannot handle multbyte chars
- such as SJIS, BIG5. Raise warning and return NULL by checking
- client_encoding. */
- encoding = (char *) pg_encoding_to_char(PQclientEncoding(conn));
- if (!strncmp(encoding, "SJIS", sizeof("SJIS")-1) ||
- !strncmp(encoding, "SHIFT_JIS_2004", sizeof("SHIFT_JIS_2004")-1) ||
- !strncmp(encoding, "BIG5", sizeof("BIG5")-1) ||
- !strncmp(encoding, "GB18030", sizeof("GB18030")-1) ||
- !strncmp(encoding, "GBK", sizeof("GBK")-1) ||
- !strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) ||
- !strncmp(encoding, "UHC", sizeof("UHC")-1) ) {
- php_error_docref(NULL, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding);
- }
- /* check backslashes */
- tmp_len = strspn(str, "\\");
- if (tmp_len != len) {
- /* add " E" for escaping slashes */
- *rp++ = ' ';
- *rp++ = 'E';
- }
- *rp++ = '\'';
- for (s = (char *)str; s - str < len; ++s) {
- if (*s == '\'' || *s == '\\') {
- *rp++ = *s;
- *rp++ = *s;
- } else {
- *rp++ = *s;
- }
- }
- }
- *rp++ = '\'';
- } else {
- /* Identifier escape. */
- *rp++ = '"';
- for (s = (char *)str; s - str < len; ++s) {
- if (*s == '"') {
- *rp++ = '"';
- *rp++ = '"';
- } else {
- *rp++ = *s;
- }
- }
- *rp++ = '"';
- }
- *rp = '\0';
- return result;
- }
- /* }}} */
- #endif
- /* {{{ _php_pgsql_trim_message */
- static char * _php_pgsql_trim_message(const char *message, size_t *len)
- {
- register size_t i = strlen(message);
- if (i>2 && (message[i-2] == '\r' || message[i-2] == '\n') && message[i-1] == '.') {
- --i;
- }
- while (i>1 && (message[i-1] == '\r' || message[i-1] == '\n')) {
- --i;
- }
- if (len) {
- *len = i;
- }
- return estrndup(message, i);
- }
- /* }}} */
- /* {{{ _php_pgsql_trim_result */
- static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf)
- {
- return *buf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
- }
- /* }}} */
- #define PQErrorMessageTrim(pgsql, buf) _php_pgsql_trim_result(pgsql, buf)
- #define PHP_PQ_ERROR(text, pgsql) { \
- char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \
- php_error_docref(NULL, E_WARNING, text, msgbuf); \
- efree(msgbuf); \
- } \
- /* {{{ php_pgsql_set_default_link
- */
- static void php_pgsql_set_default_link(zend_resource *res)
- {
- GC_ADDREF(res);
- if (PGG(default_link) != NULL) {
- zend_list_delete(PGG(default_link));
- }
- PGG(default_link) = res;
- }
- /* }}} */
- /* {{{ _close_pgsql_link
- */
- static void _close_pgsql_link(zend_resource *rsrc)
- {
- PGconn *link = (PGconn *)rsrc->ptr;
- PGresult *res;
- zval *hash;
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- PQfinish(link);
- PGG(num_links)--;
- /* Remove connection hash for this link */
- hash = zend_hash_index_find(&PGG(hashes), (uintptr_t) link);
- if (hash) {
- zend_hash_index_del(&PGG(hashes), (uintptr_t) link);
- zend_hash_del(&EG(regular_list), Z_STR_P(hash));
- }
- }
- /* }}} */
- /* {{{ _close_pgsql_plink
- */
- static void _close_pgsql_plink(zend_resource *rsrc)
- {
- PGconn *link = (PGconn *)rsrc->ptr;
- PGresult *res;
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- PQfinish(link);
- PGG(num_persistent)--;
- PGG(num_links)--;
- }
- /* }}} */
- /* {{{ _php_pgsql_notice_handler
- */
- static void _php_pgsql_notice_handler(void *resource_id, const char *message)
- {
- zval *notices;
- zval tmp;
- char *trimed_message;
- size_t trimed_message_len;
- if (! PGG(ignore_notices)) {
- notices = zend_hash_index_find(&PGG(notices), (zend_ulong)resource_id);
- if (!notices) {
- array_init(&tmp);
- notices = &tmp;
- zend_hash_index_update(&PGG(notices), (zend_ulong)resource_id, notices);
- }
- trimed_message = _php_pgsql_trim_message(message, &trimed_message_len);
- if (PGG(log_notices)) {
- php_error_docref(NULL, E_NOTICE, "%s", trimed_message);
- }
- add_next_index_stringl(notices, trimed_message, trimed_message_len);
- efree(trimed_message);
- }
- }
- /* }}} */
- /* {{{ _rollback_transactions
- */
- static int _rollback_transactions(zval *el)
- {
- PGconn *link;
- PGresult *res;
- zend_resource *rsrc = Z_RES_P(el);
- if (rsrc->type != le_plink)
- return 0;
- link = (PGconn *) rsrc->ptr;
- if (PQ_SETNONBLOCKING(link, 0)) {
- php_error_docref("ref.pgsql", E_NOTICE, "Cannot set connection to blocking mode");
- return -1;
- }
- while ((res = PQgetResult(link))) {
- PQclear(res);
- }
- #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
- if ((PQprotocolVersion(link) >= 3 && PQtransactionStatus(link) != PQTRANS_IDLE) || PQprotocolVersion(link) < 3)
- #endif
- {
- int orig = PGG(ignore_notices);
- PGG(ignore_notices) = 1;
- #if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
- res = PQexec(link,"ROLLBACK;");
- #else
- res = PQexec(link,"BEGIN;");
- PQclear(res);
- res = PQexec(link,"ROLLBACK;");
- #endif
- PQclear(res);
- PGG(ignore_notices) = orig;
- }
- return 0;
- }
- /* }}} */
- /* {{{ _free_ptr
- */
- static void _free_ptr(zend_resource *rsrc)
- {
- pgLofp *lofp = (pgLofp *)rsrc->ptr;
- efree(lofp);
- }
- /* }}} */
- /* {{{ _free_result
- */
- static void _free_result(zend_resource *rsrc)
- {
- pgsql_result_handle *pg_result = (pgsql_result_handle *)rsrc->ptr;
- PQclear(pg_result->result);
- efree(pg_result);
- }
- /* }}} */
- static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t len) /* {{{ */
- {
- /* Handle edge case. Cannot be a escaped string */
- if (len <= 2) {
- return FAILURE;
- }
- /* Detect double quotes */
- if (identifier[0] == '"' && identifier[len-1] == '"') {
- size_t i;
- /* Detect wrong format of " inside of escaped string */
- for (i = 1; i < len-1; i++) {
- if (identifier[i] == '"' && (identifier[++i] != '"' || i == len-1)) {
- return FAILURE;
- }
- }
- } else {
- return FAILURE;
- }
- /* Escaped properly */
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_INI
- */
- PHP_INI_BEGIN()
- STD_PHP_INI_BOOLEAN( "pgsql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_persistent, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_ENTRY_EX("pgsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_pgsql_globals, pgsql_globals, display_link_numbers)
- STD_PHP_INI_ENTRY_EX("pgsql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_pgsql_globals, pgsql_globals, display_link_numbers)
- STD_PHP_INI_BOOLEAN( "pgsql.auto_reset_persistent", "0", PHP_INI_SYSTEM, OnUpdateBool, auto_reset_persistent, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_BOOLEAN( "pgsql.ignore_notice", "0", PHP_INI_ALL, OnUpdateBool, ignore_notices, zend_pgsql_globals, pgsql_globals)
- STD_PHP_INI_BOOLEAN( "pgsql.log_notice", "0", PHP_INI_ALL, OnUpdateBool, log_notices, zend_pgsql_globals, pgsql_globals)
- PHP_INI_END()
- /* }}} */
- /* {{{ PHP_GINIT_FUNCTION
- */
- static PHP_GINIT_FUNCTION(pgsql)
- {
- #if defined(COMPILE_DL_PGSQL) && defined(ZTS)
- ZEND_TSRMLS_CACHE_UPDATE();
- #endif
- memset(pgsql_globals, 0, sizeof(zend_pgsql_globals));
- /* Initialize notice message hash at MINIT only */
- zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
- zend_hash_init_ex(&pgsql_globals->hashes, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
- }
- /* }}} */
- /* {{{ PHP_MINIT_FUNCTION
- */
- PHP_MINIT_FUNCTION(pgsql)
- {
- REGISTER_INI_ENTRIES();
- le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number);
- le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number);
- le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number);
- le_lofp = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql large object", module_number);
- le_string = zend_register_list_destructors_ex(_free_ptr, NULL, "pgsql string", module_number);
- #if HAVE_PG_CONFIG_H
- /* PG_VERSION - libpq version */
- REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", PG_VERSION, CONST_CS | CONST_PERSISTENT);
- REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", PG_VERSION_STR, CONST_CS | CONST_PERSISTENT);
- #endif
- /* For connection option */
- REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_CS | CONST_PERSISTENT);
- /* For pg_fetch_array() */
- REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT);
- /* For pg_last_notice() */
- REGISTER_LONG_CONSTANT("PGSQL_NOTICE_LAST", PGSQL_NOTICE_LAST, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NOTICE_ALL", PGSQL_NOTICE_ALL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NOTICE_CLEAR", PGSQL_NOTICE_CLEAR, CONST_CS | CONST_PERSISTENT);
- /* For pg_connection_status() */
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_STARTED", CONNECTION_STARTED, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_CS | CONST_PERSISTENT);
- #ifdef CONNECTION_SSL_STARTUP
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_CS | CONST_PERSISTENT);
- #endif
- REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_CS | CONST_PERSISTENT);
- /* For pg_connect_poll() */
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_READING", PGRES_POLLING_READING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_WRITING", PGRES_POLLING_WRITING, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_OK", PGRES_POLLING_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_POLLING_ACTIVE", PGRES_POLLING_ACTIVE, CONST_CS | CONST_PERSISTENT);
- #if HAVE_PGTRANSACTIONSTATUS
- /* For pg_transaction_status() */
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_IDLE", PQTRANS_IDLE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_ACTIVE", PQTRANS_ACTIVE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INTRANS", PQTRANS_INTRANS, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_INERROR", PQTRANS_INERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TRANSACTION_UNKNOWN", PQTRANS_UNKNOWN, CONST_CS | CONST_PERSISTENT);
- #endif
- #if HAVE_PQSETERRORVERBOSITY
- /* For pg_set_error_verbosity() */
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_TERSE", PQERRORS_TERSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_DEFAULT", PQERRORS_DEFAULT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_ERRORS_VERBOSE", PQERRORS_VERBOSE, CONST_CS | CONST_PERSISTENT);
- #endif
- /* For lo_seek() */
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
- /* For pg_result_status() return value type */
- REGISTER_LONG_CONSTANT("PGSQL_STATUS_LONG", PGSQL_STATUS_LONG, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_STATUS_STRING", PGSQL_STATUS_STRING, CONST_CS | CONST_PERSISTENT);
- /* For pg_result_status() return value */
- REGISTER_LONG_CONSTANT("PGSQL_EMPTY_QUERY", PGRES_EMPTY_QUERY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COMMAND_OK", PGRES_COMMAND_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_TUPLES_OK", PGRES_TUPLES_OK, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COPY_OUT", PGRES_COPY_OUT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_COPY_IN", PGRES_COPY_IN, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_BAD_RESPONSE", PGRES_BAD_RESPONSE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_NONFATAL_ERROR", PGRES_NONFATAL_ERROR, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_FATAL_ERROR", PGRES_FATAL_ERROR, CONST_CS | CONST_PERSISTENT);
- #if HAVE_PQRESULTERRORFIELD
- /* For pg_result_error_field() field codes */
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SEVERITY", PG_DIAG_SEVERITY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SQLSTATE", PG_DIAG_SQLSTATE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_PRIMARY", PG_DIAG_MESSAGE_PRIMARY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_DETAIL", PG_DIAG_MESSAGE_DETAIL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_HINT", PG_DIAG_MESSAGE_HINT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_STATEMENT_POSITION", PG_DIAG_STATEMENT_POSITION, CONST_CS | CONST_PERSISTENT);
- #ifdef PG_DIAG_INTERNAL_POSITION
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_POSITION", PG_DIAG_INTERNAL_POSITION, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_INTERNAL_QUERY
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_QUERY", PG_DIAG_INTERNAL_QUERY, CONST_CS | CONST_PERSISTENT);
- #endif
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONTEXT", PG_DIAG_CONTEXT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FILE", PG_DIAG_SOURCE_FILE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_LINE", PG_DIAG_SOURCE_LINE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FUNCTION", PG_DIAG_SOURCE_FUNCTION, CONST_CS | CONST_PERSISTENT);
- #ifdef PG_DIAG_SCHEMA_NAME
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SCHEMA_NAME", PG_DIAG_SCHEMA_NAME, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_TABLE_NAME
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_TABLE_NAME", PG_DIAG_TABLE_NAME, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_COLUMN_NAME
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_COLUMN_NAME", PG_DIAG_COLUMN_NAME, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_DATATYPE_NAME
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_DATATYPE_NAME", PG_DIAG_DATATYPE_NAME, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_CONSTRAINT_NAME
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONSTRAINT_NAME", PG_DIAG_CONSTRAINT_NAME, CONST_CS | CONST_PERSISTENT);
- #endif
- #ifdef PG_DIAG_SEVERITY_NONLOCALIZED
- REGISTER_LONG_CONSTANT("PGSQL_DIAG_SEVERITY_NONLOCALIZED", PG_DIAG_SEVERITY_NONLOCALIZED, CONST_CS | CONST_PERSISTENT);
- #endif
- #endif
- /* pg_convert options */
- REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_DEFAULT", PGSQL_CONV_IGNORE_DEFAULT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONV_FORCE_NULL", PGSQL_CONV_FORCE_NULL, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_NOT_NULL", PGSQL_CONV_IGNORE_NOT_NULL, CONST_CS | CONST_PERSISTENT);
- /* pg_insert/update/delete/select options */
- REGISTER_LONG_CONSTANT("PGSQL_DML_ESCAPE", PGSQL_DML_ESCAPE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_NO_CONV", PGSQL_DML_NO_CONV, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MSHUTDOWN_FUNCTION
- */
- PHP_MSHUTDOWN_FUNCTION(pgsql)
- {
- UNREGISTER_INI_ENTRIES();
- zend_hash_destroy(&PGG(notices));
- zend_hash_destroy(&PGG(hashes));
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_RINIT_FUNCTION
- */
- PHP_RINIT_FUNCTION(pgsql)
- {
- PGG(default_link) = NULL;
- PGG(num_links) = PGG(num_persistent);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_RSHUTDOWN_FUNCTION
- */
- PHP_RSHUTDOWN_FUNCTION(pgsql)
- {
- /* clean up notice messages */
- zend_hash_clean(&PGG(notices));
- zend_hash_clean(&PGG(hashes));
- /* clean up persistent connection */
- zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions);
- return SUCCESS;
- }
- /* }}} */
- /* {{{ PHP_MINFO_FUNCTION
- */
- PHP_MINFO_FUNCTION(pgsql)
- {
- char buf[256];
- php_info_print_table_start();
- php_info_print_table_header(2, "PostgreSQL Support", "enabled");
- #if HAVE_PG_CONFIG_H
- php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION);
- php_info_print_table_row(2, "PostgreSQL(libpq) ", PG_VERSION_STR);
- #ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
- php_info_print_table_row(2, "Multibyte character support", "enabled");
- #else
- php_info_print_table_row(2, "Multibyte character support", "disabled");
- #endif
- #if defined(USE_SSL) || defined(USE_OPENSSL)
- php_info_print_table_row(2, "SSL support", "enabled");
- #else
- php_info_print_table_row(2, "SSL support", "disabled");
- #endif
- #endif /* HAVE_PG_CONFIG_H */
- snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_persistent));
- php_info_print_table_row(2, "Active Persistent Links", buf);
- snprintf(buf, sizeof(buf), ZEND_LONG_FMT, PGG(num_links));
- php_info_print_table_row(2, "Active Links", buf);
- php_info_print_table_end();
- DISPLAY_INI_ENTRIES();
- }
- /* }}} */
- /* {{{ php_pgsql_do_connect
- */
- static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
- {
- char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL;
- PGconn *pgsql;
- smart_str str = {0};
- zval *args;
- uint32_t i;
- int connect_type = 0;
- PGresult *pg_result;
- args = (zval *)safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval), 0);
- if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5
- || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
- efree(args);
- WRONG_PARAM_COUNT;
- }
- smart_str_appends(&str, "pgsql");
- for (i = 0; i < ZEND_NUM_ARGS(); i++) {
- /* make sure that the PGSQL_CONNECT_FORCE_NEW bit is not part of the hash so that subsequent connections
- * can re-use this connection. Bug #39979
- */
- if (i == 1 && ZEND_NUM_ARGS() == 2 && Z_TYPE(args[i]) == IS_LONG) {
- if (Z_LVAL(args[1]) == PGSQL_CONNECT_FORCE_NEW) {
- continue;
- } else if (Z_LVAL(args[1]) & PGSQL_CONNECT_FORCE_NEW) {
- smart_str_append_long(&str, Z_LVAL(args[1]) ^ PGSQL_CONNECT_FORCE_NEW);
- }
- }
- ZVAL_STR(&args[i], zval_get_string(&args[i]));
- smart_str_appendc(&str, '_');
- smart_str_appendl(&str, Z_STRVAL(args[i]), Z_STRLEN(args[i]));
- }
- /* Exception thrown during a string conversion. */
- if (EG(exception)) {
- goto cleanup;
- }
- smart_str_0(&str);
- if (ZEND_NUM_ARGS() == 1) { /* new style, using connection string */
- connstring = Z_STRVAL(args[0]);
- } else if (ZEND_NUM_ARGS() == 2 ) { /* Safe to add conntype_option, since 2 args was illegal */
- connstring = Z_STRVAL(args[0]);
- connect_type = (int)zval_get_long(&args[1]);
- } else {
- host = Z_STRVAL(args[0]);
- port = Z_STRVAL(args[1]);
- dbname = Z_STRVAL(args[ZEND_NUM_ARGS()-1]);
- switch (ZEND_NUM_ARGS()) {
- case 5:
- tty = Z_STRVAL(args[3]);
- /* fall through */
- case 4:
- options = Z_STRVAL(args[2]);
- break;
- }
- }
- if (persistent && PGG(allow_persistent)) {
- zend_resource *le;
- /* try to find if we already have this link in our persistent list */
- if ((le = zend_hash_find_ptr(&EG(persistent_list), str.s)) == NULL) { /* we don't */
- if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) {
- php_error_docref(NULL, E_WARNING,
- "Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links));
- goto err;
- }
- if (PGG(max_persistent) != -1 && PGG(num_persistent) >= PGG(max_persistent)) {
- php_error_docref(NULL, E_WARNING,
- "Cannot create new link. Too many open persistent links (" ZEND_LONG_FMT ")", PGG(num_persistent));
- goto err;
- }
- /* create the link */
- if (connstring) {
- pgsql = PQconnectdb(connstring);
- } else {
- pgsql = PQsetdb(host, port, options, tty, dbname);
- }
- if (pgsql == NULL || PQstatus(pgsql) == CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql)
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- /* hash it up */
- if (zend_register_persistent_resource(ZSTR_VAL(str.s), ZSTR_LEN(str.s), pgsql, le_plink) == NULL) {
- goto err;
- }
- PGG(num_links)++;
- PGG(num_persistent)++;
- } else { /* we do */
- if (le->type != le_plink) {
- goto err;
- }
- /* ensure that the link did not die */
- if (PGG(auto_reset_persistent) & 1) {
- /* need to send & get something from backend to
- make sure we catch CONNECTION_BAD every time */
- PGresult *pg_result;
- pg_result = PQexec(le->ptr, "select 1");
- PQclear(pg_result);
- }
- if (PQstatus(le->ptr) == CONNECTION_BAD) { /* the link died */
- if (le->ptr == NULL) {
- if (connstring) {
- le->ptr = PQconnectdb(connstring);
- } else {
- le->ptr = PQsetdb(host,port,options,tty,dbname);
- }
- }
- else {
- PQreset(le->ptr);
- }
- if (le->ptr == NULL || PQstatus(le->ptr) == CONNECTION_BAD) {
- php_error_docref(NULL, E_WARNING,"PostgreSQL link lost, unable to reconnect");
- zend_hash_del(&EG(persistent_list), str.s);
- goto err;
- }
- }
- pgsql = (PGconn *) le->ptr;
- #if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
- if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 7.2) {
- #else
- if (atof(PG_VERSION) >= 7.2) {
- #endif
- pg_result = PQexec(pgsql, "RESET ALL;");
- PQclear(pg_result);
- }
- }
- RETVAL_RES(zend_register_resource(pgsql, le_plink));
- } else { /* Non persistent connection */
- zend_resource *index_ptr, new_index_ptr;
- /* first we check the hash for the hashed_details key. if it exists,
- * it should point us to the right offset where the actual pgsql link sits.
- * if it doesn't, open a new pgsql link, add it to the resource list,
- * and add a pointer to it with hashed_details as the key.
- */
- if (!(connect_type & PGSQL_CONNECT_FORCE_NEW)
- && (index_ptr = zend_hash_find_ptr(&EG(regular_list), str.s)) != NULL) {
- zend_resource *link;
- if (index_ptr->type != le_index_ptr) {
- goto err;
- }
- link = (zend_resource *)index_ptr->ptr;
- ZEND_ASSERT(link->ptr && (link->type == le_link || link->type == le_plink));
- php_pgsql_set_default_link(link);
- GC_ADDREF(link);
- RETVAL_RES(link);
- goto cleanup;
- }
- if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) {
- php_error_docref(NULL, E_WARNING, "Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links));
- goto err;
- }
- /* Non-blocking connect */
- if (connect_type & PGSQL_CONNECT_ASYNC) {
- if (connstring) {
- pgsql = PQconnectStart(connstring);
- if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql);
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- } else {
- php_error_docref(NULL, E_WARNING, "Connection string required for async connections");
- goto err;
- }
- } else {
- if (connstring) {
- pgsql = PQconnectdb(connstring);
- } else {
- pgsql = PQsetdb(host,port,options,tty,dbname);
- }
- if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
- PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql);
- if (pgsql) {
- PQfinish(pgsql);
- }
- goto err;
- }
- }
- /* add it to the list */
- RETVAL_RES(zend_register_resource(pgsql, le_link));
- /* add it to the hash */
- new_index_ptr.ptr = (void *) Z_RES_P(return_value);
- new_index_ptr.type = le_index_ptr;
- zend_hash_update_mem(&EG(regular_list), str.s, (void *) &new_index_ptr, sizeof(zend_resource));
- /* Keep track of link => hash mapping, so we can remove the hash entry from regular_list
- * when the connection is closed. This uses the address of the connection rather than the
- * zend_resource, because the resource destructor is passed a stack copy of the resource
- * structure. */
- {
- zval tmp;
- ZVAL_STR_COPY(&tmp, str.s);
- zend_hash_index_update(&PGG(hashes), (uintptr_t) pgsql, &tmp);
- }
- PGG(num_links)++;
- }
- /* set notice processor */
- if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) {
- PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void*)(zend_uintptr_t)Z_RES_HANDLE_P(return_value));
- }
- php_pgsql_set_default_link(Z_RES_P(return_value));
- cleanup:
- for (i = 0; i < ZEND_NUM_ARGS(); i++) {
- zval_ptr_dtor(&args[i]);
- }
- efree(args);
- smart_str_free(&str);
- return;
- err:
- for (i = 0; i < ZEND_NUM_ARGS(); i++) {
- zval_ptr_dtor(&args[i]);
- }
- efree(args);
- smart_str_free(&str);
- RETURN_FALSE;
- }
- /* }}} */
- /* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)
- Open a PostgreSQL connection */
- PHP_FUNCTION(pg_connect)
- {
- php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
- }
- /* }}} */
- /* {{{ proto resource pg_connect_poll(resource connection)
- Poll the status of an in-progress async PostgreSQL connection attempt*/
- PHP_FUNCTION(pg_connect_poll)
- {
- zval *pgsql_link;
- PGconn *pgsql;
- int ret;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) {
- RETURN_THROWS();
- }
- if ((pgsql = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "…
Large files files are truncated, but you can click here to view the full file