1999-04-22 10:48:28 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| PHP Version 5 |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-12-31 15:17:19 +08:00
| Copyright ( c ) 1997 - 2008 The PHP Group |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 21:13:16 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
1999-07-16 21:13:16 +08:00
| 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 . |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Zeev Suraski < zeev @ zend . com > |
2001-12-17 08:24:59 +08:00
| Jouni Ahto < jouni . ahto @ exdec . fi > |
| Yasuo Ohgaki < yohgaki @ php . net > |
| Youichi Iwakiri < yiwakiri @ st . rim . or . jp > ( pg_copy_ * ) |
2005-03-22 16:51:23 +08:00
| Chris Kings - Lynne < chriskl @ php . net > ( v3 protocol ) |
1999-04-22 10:48:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
# include <stdlib.h>
2000-05-02 13:27:35 +08:00
# define PHP_PGSQL_PRIVATE 1
2001-05-24 18:07:29 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2002-05-11 11:01:08 +08:00
# define SMART_STR_PREALLOC 512
1999-04-22 10:48:28 +08:00
# include "php.h"
2000-02-06 01:26:35 +08:00
# include "php_ini.h"
1999-12-05 03:19:57 +08:00
# include "ext/standard/php_standard.h"
2002-04-21 17:46:29 +08:00
# include "ext/standard/php_smart_str.h"
2007-10-05 23:00:09 +08:00
# include "ext/ereg/php_regex.h"
2005-12-21 05:10:43 +08:00
# undef PACKAGE_BUGREPORT
# undef PACKAGE_NAME
# undef PACKAGE_STRING
# undef PACKAGE_TARNAME
# undef PACKAGE_VERSION
2000-02-06 00:12:23 +08:00
# include "php_pgsql.h"
1999-04-22 10:48:28 +08:00
# include "php_globals.h"
2004-02-12 18:43:27 +08:00
# include "zend_exceptions.h"
1999-04-22 10:48:28 +08:00
# if HAVE_PGSQL
2001-02-20 00:31:17 +08:00
# ifndef InvalidOid
# define InvalidOid ((Oid) 0)
# endif
1999-04-22 10:48:28 +08:00
1999-07-17 01:19:11 +08:00
# define PGSQL_ASSOC 1<<0
# define PGSQL_NUM 1<<1
# define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM)
2002-04-08 08:43:58 +08:00
# define PGSQL_STATUS_LONG 1
# define PGSQL_STATUS_STRING 2
2001-12-17 08:24:59 +08:00
2002-04-20 11:03:42 +08:00
# define PGSQL_MAX_LENGTH_OF_LONG 30
# define PGSQL_MAX_LENGTH_OF_DOUBLE 60
2002-04-21 18:22:31 +08:00
# define PGSQL_RETURN_OID(oid) do { \
if ( oid > LONG_MAX ) { \
smart_str s = { 0 } ; \
smart_str_append_unsigned ( & s , oid ) ; \
smart_str_0 ( & s ) ; \
RETURN_STRINGL ( s . c , s . len , 0 ) ; \
} \
RETURN_LONG ( ( long ) oid ) ; \
} while ( 0 )
2002-04-20 11:03:42 +08:00
2002-03-29 19:24:54 +08:00
# if HAVE_PQSETNONBLOCKING
# define PQ_SETNONBLOCKING(pg_link, flag) PQsetnonblocking(pg_link, flag)
# else
# define PQ_SETNONBLOCKING(pg_link, flag) 0
# endif
2003-07-21 00:00:40 +08:00
# define CHECK_DEFAULT_LINK(x) if ((x) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No PostgreSQL link opened yet"); }
1999-04-22 10:48:28 +08:00
2007-07-02 23:37:43 +08:00
# ifndef HAVE_PQFREEMEM
2007-09-05 21:03:59 +08:00
# define PQfreemem free
2007-07-02 23:37:43 +08:00
# endif
2006-06-16 02:33:09 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( pgsql )
static PHP_GINIT_FUNCTION ( pgsql ) ;
2008-07-02 08:10:54 +08:00
/* {{{ arginfo */
static
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 ( )
static
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 ( )
# if HAVE_PQPARAMETERSTATUS
static
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
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_close , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_dbname , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_last_error , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_options , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_port , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_tty , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_host , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_version , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_ping , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
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
static
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
static
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
static
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
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_num_rows , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_num_fields , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
# if HAVE_PQCMDTUPLES
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_affected_rows , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
# endif
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_last_notice , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
# ifdef HAVE_PQFTABLE
static
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
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_fetch_all , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_free_result , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_last_oid , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_untrace , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_lo_create , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
2008-07-23 08:17:19 +08:00
ZEND_ARG_INFO ( 0 , large_object_id )
2008-07-02 08:10:54 +08:00
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_lo_close , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , large_object )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_lo_read_all , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , large_object )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_lo_import , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_ARG_INFO ( 0 , filename )
2008-07-23 08:17:19 +08:00
ZEND_ARG_INFO ( 0 , large_object_oid )
2008-07-02 08:10:54 +08:00
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_lo_tell , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , large_object )
ZEND_END_ARG_INFO ( )
# if HAVE_PQSETERRORVERBOSITY
static
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
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_client_encoding , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
# endif
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_end_copy , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
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
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_unescape_bytea , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , data )
ZEND_END_ARG_INFO ( )
# endif
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_result_error , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , result )
ZEND_END_ARG_INFO ( )
# if HAVE_PQRESULTERRORFIELD
static
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
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_connection_status , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connnection )
ZEND_END_ARG_INFO ( )
# if HAVE_PGTRANSACTIONSTATUS
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_transaction_status , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connnection )
ZEND_END_ARG_INFO ( )
# endif
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_connection_reset , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_cancel_query , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_connection_busy , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
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
static
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
static
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
static
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
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_get_result , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
ZEND_BEGIN_ARG_INFO_EX ( arginfo_pg_get_pid , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , connection )
ZEND_END_ARG_INFO ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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 ( )
static
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_END_ARG_INFO ( )
/* }}} */
2001-06-05 21:12:10 +08:00
/* {{{ pgsql_functions[]
*/
2007-09-28 02:00:48 +08:00
const zend_function_entry pgsql_functions [ ] = {
2001-12-17 08:24:59 +08:00
/* connection functions */
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_connect , arginfo_pg_connect )
PHP_FE ( pg_pconnect , arginfo_pg_pconnect )
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 )
2003-07-28 00:47:36 +08:00
# if HAVE_PQPARAMETERSTATUS
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_parameter_status , arginfo_pg_parameter_status )
2005-03-19 16:46:56 +08:00
# endif
# if HAVE_PGTRANSACTIONSTATUS
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_transaction_status , arginfo_pg_transaction_status )
2003-07-28 00:47:36 +08:00
# endif
2001-12-17 08:24:59 +08:00
/* query functions */
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_query , arginfo_pg_query )
2005-03-19 16:46:56 +08:00
# if HAVE_PQEXECPARAMS
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_query_params , arginfo_pg_query_params )
2005-03-19 16:46:56 +08:00
# endif
# if HAVE_PQPREPARE
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_prepare , arginfo_pg_prepare )
2005-03-19 16:46:56 +08:00
# endif
# if HAVE_PQEXECPREPARED
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_execute , arginfo_pg_execute )
2005-03-19 16:46:56 +08:00
# endif
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_send_query , arginfo_pg_send_query )
2005-03-19 16:46:56 +08:00
# if HAVE_PQSENDQUERYPARAMS
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_send_query_params , arginfo_pg_send_query_params )
2005-03-19 16:46:56 +08:00
# endif
# if HAVE_PQSENDPREPARE
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_send_prepare , arginfo_pg_send_prepare )
2005-03-19 16:46:56 +08:00
# endif
# if HAVE_PQSENDQUERYPREPARED
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_send_execute , arginfo_pg_send_execute )
2005-03-19 16:46:56 +08:00
# endif
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_cancel_query , arginfo_pg_cancel_query )
2001-12-17 08:24:59 +08:00
/* result functions */
2008-07-02 08:10:54 +08:00
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 )
2005-04-14 05:48:33 +08:00
# if HAVE_PQCMDTUPLES
2008-07-02 08:10:54 +08:00
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 )
2006-09-16 03:47:50 +08:00
# ifdef HAVE_PQFTABLE
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_field_table , arginfo_pg_field_table )
2006-09-16 03:47:50 +08:00
# endif
2002-10-17 15:58:46 +08:00
/* async message function */
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_get_notify , arginfo_pg_get_notify )
PHP_FE ( pg_get_pid , arginfo_pg_get_pid )
2001-12-17 08:24:59 +08:00
/* error message functions */
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_result_error , arginfo_pg_result_error )
2005-03-19 16:46:56 +08:00
# if HAVE_PQRESULTERRORFIELD
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_result_error_field , arginfo_pg_result_error_field )
2005-03-19 16:46:56 +08:00
# endif
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_last_error , arginfo_pg_last_error )
PHP_FE ( pg_last_notice , arginfo_pg_last_notice )
2001-12-17 08:24:59 +08:00
/* copy functions */
2008-07-02 08:10:54 +08:00
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 )
2001-12-17 08:24:59 +08:00
/* debug functions */
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_trace , arginfo_pg_trace )
PHP_FE ( pg_untrace , arginfo_pg_untrace )
2001-12-17 08:24:59 +08:00
/* large object functions */
2008-07-02 08:10:54 +08:00
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 )
2001-12-17 08:24:59 +08:00
/* utility functions */
# if HAVE_PQESCAPE
2008-07-02 08:10:54 +08:00
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 )
2001-12-17 08:24:59 +08:00
# endif
2005-03-22 16:51:23 +08:00
# if HAVE_PQSETERRORVERBOSITY
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_set_error_verbosity , arginfo_pg_set_error_verbosity )
2005-03-22 16:51:23 +08:00
# endif
2002-04-25 15:09:45 +08:00
# if HAVE_PQCLIENTENCODING
2008-07-02 08:10:54 +08:00
PHP_FE ( pg_client_encoding , arginfo_pg_client_encoding )
PHP_FE ( pg_set_client_encoding , arginfo_pg_set_client_encoding )
2002-04-25 15:09:45 +08:00
# endif
2002-04-08 09:37:38 +08:00
/* misc function */
2008-07-02 08:10:54 +08:00
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 )
2001-12-17 08:24:59 +08:00
/* aliases for downwards compatibility */
2008-07-02 08:10:54 +08:00
PHP_FALIAS ( pg_exec , pg_query , arginfo_pg_query )
PHP_FALIAS ( pg_getlastoid , pg_last_oid , arginfo_pg_last_oid )
2005-04-14 06:11:35 +08:00
# if HAVE_PQCMDTUPLES
2008-07-02 08:10:54 +08:00
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 )
2002-04-25 15:09:45 +08:00
# if HAVE_PQCLIENTENCODING
2008-07-02 08:10:54 +08:00
PHP_FALIAS ( pg_clientencoding , pg_client_encoding , arginfo_pg_client_encoding )
PHP_FALIAS ( pg_setclientencoding , pg_set_client_encoding , arginfo_pg_set_client_encoding )
2002-04-25 15:09:45 +08:00
# endif
2002-02-06 15:25:51 +08:00
{ NULL , NULL , NULL }
1999-04-22 10:48:28 +08:00
} ;
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ pgsql_module_entry
*/
1999-12-18 04:55:31 +08:00
zend_module_entry pgsql_module_entry = {
2001-10-12 07:33:59 +08:00
STANDARD_MODULE_HEADER ,
2000-05-24 14:48:04 +08:00
" pgsql " ,
pgsql_functions ,
PHP_MINIT ( pgsql ) ,
PHP_MSHUTDOWN ( pgsql ) ,
PHP_RINIT ( pgsql ) ,
2001-02-14 02:28:24 +08:00
PHP_RSHUTDOWN ( pgsql ) ,
2000-05-24 14:48:04 +08:00
PHP_MINFO ( pgsql ) ,
2002-08-24 04:57:30 +08:00
NO_VERSION_YET ,
2006-06-16 02:33:09 +08:00
PHP_MODULE_GLOBALS ( pgsql ) ,
PHP_GINIT ( pgsql ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
1999-04-22 10:48:28 +08:00
} ;
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2000-05-23 17:33:51 +08:00
# ifdef COMPILE_DL_PGSQL
2000-05-02 08:30:36 +08:00
ZEND_GET_MODULE ( pgsql )
1999-04-22 10:48:28 +08:00
# endif
2000-05-25 15:51:40 +08:00
static int le_link , le_plink , le_result , le_lofp , le_string ;
1999-11-20 09:04:45 +08:00
2003-12-07 05:36:21 +08:00
/* {{{ _php_pgsql_trim_message */
static char * _php_pgsql_trim_message ( const char * message , int * len )
{
register int i = strlen ( message ) - 1 ;
if ( i > 1 & & ( message [ i - 1 ] = = ' \r ' | | message [ i - 1 ] = = ' \n ' ) & & message [ i ] = = ' . ' ) {
- - i ;
}
2004-05-13 00:49:47 +08:00
while ( i > 0 & & ( message [ i ] = = ' \r ' | | message [ i ] = = ' \n ' ) ) {
2003-12-07 05:36:21 +08:00
- - i ;
}
+ + 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 TSRMLS_CC , E_WARNING , text , msgbuf ) ; \
efree ( msgbuf ) ; \
} \
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_set_default_link
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_set_default_link ( int id TSRMLS_DC )
2000-10-11 21:27:21 +08:00
{
2001-05-28 06:54:54 +08:00
zend_list_addref ( id ) ;
2001-04-05 20:29:24 +08:00
2001-05-28 06:54:54 +08:00
if ( PGG ( default_link ) ! = - 1 ) {
zend_list_delete ( PGG ( default_link ) ) ;
}
2001-02-14 00:54:48 +08:00
2001-05-28 06:54:54 +08:00
PGG ( default_link ) = id ;
2000-10-11 21:27:21 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
2000-10-11 21:27:21 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ _close_pgsql_link
*/
2001-07-31 13:44:11 +08:00
static void _close_pgsql_link ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-10-21 02:25:16 +08:00
PGconn * link = ( PGconn * ) rsrc - > ptr ;
2001-12-10 12:02:08 +08:00
PGresult * res ;
1999-11-20 08:30:08 +08:00
2001-12-10 12:02:08 +08:00
while ( ( res = PQgetResult ( link ) ) ) {
PQclear ( res ) ;
}
1999-04-22 10:48:28 +08:00
PQfinish ( link ) ;
1999-11-20 08:30:08 +08:00
PGG ( num_links ) - - ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ _close_pgsql_plink
*/
2001-07-31 13:44:11 +08:00
static void _close_pgsql_plink ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-10-21 02:25:16 +08:00
PGconn * link = ( PGconn * ) rsrc - > ptr ;
2001-12-10 12:02:08 +08:00
PGresult * res ;
1999-11-20 08:30:08 +08:00
2001-12-10 12:02:08 +08:00
while ( ( res = PQgetResult ( link ) ) ) {
PQclear ( res ) ;
}
1999-04-22 10:48:28 +08:00
PQfinish ( link ) ;
1999-11-20 08:30:08 +08:00
PGG ( num_persistent ) - - ;
PGG ( num_links ) - - ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2002-04-06 13:52:52 +08:00
/* {{{ _php_pgsql_notice_handler
2001-06-05 21:12:10 +08:00
*/
2002-04-06 13:52:52 +08:00
static void _php_pgsql_notice_handler ( void * resource_id , const char * message )
2001-02-14 04:13:14 +08:00
{
2002-04-06 13:52:52 +08:00
php_pgsql_notice * notice ;
2001-07-28 19:36:37 +08:00
TSRMLS_FETCH ( ) ;
2001-04-05 05:40:41 +08:00
if ( ! PGG ( ignore_notices ) ) {
2003-05-30 23:42:46 +08:00
notice = ( php_pgsql_notice * ) emalloc ( sizeof ( php_pgsql_notice ) ) ;
2003-07-21 00:00:40 +08:00
notice - > message = _php_pgsql_trim_message ( message , & notice - > len ) ;
2002-04-06 13:52:52 +08:00
if ( PGG ( log_notices ) ) {
2003-05-30 23:42:46 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " %s " , notice - > message ) ;
2001-05-06 09:34:56 +08:00
}
2005-11-07 20:57:49 +08:00
zend_hash_index_update ( & PGG ( notices ) , ( int ) resource_id , ( void * * ) & notice , sizeof ( php_pgsql_notice * ) , NULL ) ;
2001-04-05 05:40:41 +08:00
}
2001-02-14 04:13:14 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
2001-02-14 04:13:14 +08:00
2002-04-06 13:52:52 +08:00
# define PHP_PGSQL_NOTICE_PTR_DTOR (void (*)(void *))_php_pgsql_notice_ptr_dtor
/* {{{ _php_pgsql_notice_dtor
*/
static void _php_pgsql_notice_ptr_dtor ( void * * ptr )
{
php_pgsql_notice * notice = ( php_pgsql_notice * ) * ptr ;
2005-05-04 06:50:00 +08:00
if ( notice ) {
efree ( notice - > message ) ;
efree ( notice ) ;
notice = NULL ;
}
2002-04-06 13:52:52 +08:00
}
/* }}} */
2001-06-05 21:12:10 +08:00
/* {{{ _rollback_transactions
*/
2001-07-31 12:53:54 +08:00
static int _rollback_transactions ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
2001-02-14 02:28:24 +08:00
{
2001-05-28 07:26:58 +08:00
PGconn * link ;
2001-12-10 12:02:08 +08:00
PGresult * res ;
2002-04-06 13:52:52 +08:00
int orig ;
2001-02-14 02:28:24 +08:00
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( rsrc ) ! = le_plink )
2001-05-28 11:30:11 +08:00
return 0 ;
2001-05-28 07:26:58 +08:00
2001-05-28 11:30:11 +08:00
link = ( PGconn * ) rsrc - > ptr ;
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( link , 0 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( " ref.pgsql " TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
2002-03-29 19:24:54 +08:00
return - 1 ;
}
2001-05-28 11:30:11 +08:00
2001-12-10 12:02:08 +08:00
while ( ( res = PQgetResult ( link ) ) ) {
PQclear ( res ) ;
}
2003-07-28 00:45:10 +08:00
# if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
2003-07-28 01:44:20 +08:00
if ( ( PQprotocolVersion ( link ) > = 3 & & PQtransactionStatus ( link ) ! = PQTRANS_IDLE ) | | PQprotocolVersion ( link ) < 3 )
2003-07-28 00:45:10 +08:00
# endif
{
orig = PGG ( ignore_notices ) ;
PGG ( ignore_notices ) = 1 ;
# if HAVE_PGTRANSACTIONSTATUS && HAVE_PQPROTOCOLVERSION
res = PQexec ( link , " ROLLBACK; " ) ;
# else
2003-09-06 23:30:28 +08:00
res = PQexec ( link , " BEGIN; " ) ;
PQclear ( res ) ;
res = PQexec ( link , " ROLLBACK; " ) ;
2003-07-28 00:45:10 +08:00
# endif
PQclear ( res ) ;
PGG ( ignore_notices ) = orig ;
}
2001-02-14 02:28:24 +08:00
return 0 ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2001-02-14 02:28:24 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ _free_ptr
*/
2001-07-31 13:44:11 +08:00
static void _free_ptr ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-10-21 02:25:16 +08:00
pgLofp * lofp = ( pgLofp * ) rsrc - > ptr ;
1999-04-22 10:48:28 +08:00
efree ( lofp ) ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ _free_result
*/
2001-07-31 13:44:11 +08:00
static void _free_result ( zend_rsrc_list_entry * rsrc TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
2000-10-21 02:25:16 +08:00
pgsql_result_handle * pg_result = ( pgsql_result_handle * ) rsrc - > ptr ;
2001-07-31 13:44:11 +08:00
1999-04-22 10:48:28 +08:00
PQclear ( pg_result - > result ) ;
efree ( pg_result ) ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_INI
*/
2000-02-06 01:26:35 +08:00
PHP_INI_BEGIN ( )
2003-05-30 23:07:02 +08:00
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 )
2000-02-06 01:26:35 +08:00
PHP_INI_END ( )
2001-06-05 21:12:10 +08:00
/* }}} */
2000-02-06 01:26:35 +08:00
2006-06-16 02:33:09 +08:00
/* {{{ PHP_GINIT_FUNCTION
2001-06-05 21:12:10 +08:00
*/
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( pgsql )
1999-04-22 10:48:28 +08:00
{
2003-05-30 23:07:02 +08:00
memset ( pgsql_globals , 0 , sizeof ( zend_pgsql_globals ) ) ;
2002-04-06 13:52:52 +08:00
/* Initilize notice message hash at MINIT only */
2003-05-30 23:07:02 +08:00
zend_hash_init_ex ( & pgsql_globals - > notices , 0 , NULL , PHP_PGSQL_NOTICE_PTR_DTOR , 1 , 0 ) ;
1999-11-20 09:04:45 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-11-20 09:04:45 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_MINIT_FUNCTION
*/
1999-11-20 09:04:45 +08:00
PHP_MINIT_FUNCTION ( pgsql )
{
2000-02-06 01:26:35 +08:00
REGISTER_INI_ENTRIES ( ) ;
1999-11-20 09:04:45 +08:00
2000-10-26 01:44:02 +08:00
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 ) ;
2002-10-13 17:37:27 +08:00
/* For connection option */
REGISTER_LONG_CONSTANT ( " PGSQL_CONNECT_FORCE_NEW " , PGSQL_CONNECT_FORCE_NEW , CONST_CS | CONST_PERSISTENT ) ;
2002-03-11 15:19:57 +08:00
/* For pg_fetch_array() */
1999-07-17 01:27:42 +08:00
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 ) ;
2002-03-11 15:19:57 +08:00
/* For pg_connection_status() */
2001-12-10 12:02:08 +08:00
REGISTER_LONG_CONSTANT ( " PGSQL_CONNECTION_BAD " , CONNECTION_BAD , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " PGSQL_CONNECTION_OK " , CONNECTION_OK , CONST_CS | CONST_PERSISTENT ) ;
2005-03-19 16:46:56 +08:00
# 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 ) ;
2005-03-22 16:51:23 +08:00
# 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 ) ;
2005-03-19 16:46:56 +08:00
# endif
2002-03-11 15:19:57 +08:00
/* For lo_seek() */
2001-12-17 08:24:59 +08:00
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 ) ;
2002-04-08 08:43:58 +08:00
/* 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 */
2001-12-17 08:24:59 +08:00
REGISTER_LONG_CONSTANT ( " PGSQL_EMPTY_QUERY " , PGRES_EMPTY_QUERY , CONST_CS | CONST_PERSISTENT ) ;
2002-01-21 08:36:22 +08:00
REGISTER_LONG_CONSTANT ( " PGSQL_COMMAND_OK " , PGRES_COMMAND_OK , CONST_CS | CONST_PERSISTENT ) ;
2001-12-17 08:24:59 +08:00
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 ) ;
2005-03-19 17:21:51 +08:00
# if HAVE_PQRESULTERRORFIELD
2005-03-19 16:46:56 +08:00
/* 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 ) ;
2005-03-20 10:46:02 +08:00
# ifdef PG_DIAG_INTERNAL_POSITION
2005-03-19 16:46:56 +08:00
REGISTER_LONG_CONSTANT ( " PGSQL_DIAG_INTERNAL_POSITION " , PG_DIAG_INTERNAL_POSITION , CONST_CS | CONST_PERSISTENT ) ;
2005-03-20 10:46:02 +08:00
# endif
# ifdef PG_DIAG_INTERNAL_QUERY
2005-03-19 16:46:56 +08:00
REGISTER_LONG_CONSTANT ( " PGSQL_DIAG_INTERNAL_QUERY " , PG_DIAG_INTERNAL_QUERY , CONST_CS | CONST_PERSISTENT ) ;
2005-03-20 10:46:02 +08:00
# endif
2005-03-19 16:46:56 +08:00
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 ) ;
2005-03-19 17:21:51 +08:00
# endif
2002-04-23 11:42:26 +08:00
/* 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_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 ) ;
1999-04-22 10:48:28 +08:00
return SUCCESS ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
2000-02-06 01:26:35 +08:00
PHP_MSHUTDOWN_FUNCTION ( pgsql )
{
UNREGISTER_INI_ENTRIES ( ) ;
2002-12-16 15:46:36 +08:00
zend_hash_destroy ( & PGG ( notices ) ) ;
2000-02-06 01:26:35 +08:00
return SUCCESS ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2000-02-06 01:26:35 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_RINIT_FUNCTION
*/
1999-12-18 19:38:04 +08:00
PHP_RINIT_FUNCTION ( pgsql )
1999-04-22 10:48:28 +08:00
{
1999-11-20 08:30:08 +08:00
PGG ( default_link ) = - 1 ;
PGG ( num_links ) = PGG ( num_persistent ) ;
1999-04-22 10:48:28 +08:00
return SUCCESS ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
2001-02-14 02:28:24 +08:00
PHP_RSHUTDOWN_FUNCTION ( pgsql )
{
2002-04-06 13:52:52 +08:00
/* clean up notice messages */
2002-12-16 15:46:36 +08:00
zend_hash_clean ( & PGG ( notices ) ) ;
2002-04-06 13:52:52 +08:00
/* clean up persistent connection */
2001-07-31 12:53:54 +08:00
zend_hash_apply ( & EG ( persistent_list ) , ( apply_func_t ) _rollback_transactions TSRMLS_CC ) ;
2001-02-14 02:28:24 +08:00
return SUCCESS ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2001-02-14 02:28:24 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ PHP_MINFO_FUNCTION
*/
2000-05-24 14:48:04 +08:00
PHP_MINFO_FUNCTION ( pgsql )
{
2002-04-08 09:37:38 +08:00
char buf [ 256 ] ;
2000-05-24 14:48:04 +08:00
php_info_print_table_start ( ) ;
php_info_print_table_header ( 2 , " PostgreSQL Support " , " enabled " ) ;
2002-03-31 09:45:22 +08:00
# if HAVE_PG_CONFIG_H
2002-03-31 09:18:32 +08:00
php_info_print_table_row ( 2 , " PostgreSQL(libpq) Version " , PG_VERSION ) ;
2002-11-30 01:18:01 +08:00
# ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
2002-12-22 01:48:37 +08:00
php_info_print_table_row ( 2 , " Multibyte character support " , " enabled " ) ;
2002-03-31 09:45:22 +08:00
# else
2002-12-22 01:48:37 +08:00
php_info_print_table_row ( 2 , " Multibyte character support " , " disabled " ) ;
2002-03-31 09:45:22 +08:00
# endif
# ifdef USE_SSL
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 */
2007-02-24 10:17:47 +08:00
snprintf ( buf , sizeof ( buf ) , " %ld " , PGG ( num_persistent ) ) ;
2000-05-24 14:48:04 +08:00
php_info_print_table_row ( 2 , " Active Persistent Links " , buf ) ;
2007-02-24 10:17:47 +08:00
snprintf ( buf , sizeof ( buf ) , " %ld " , PGG ( num_links ) ) ;
2000-05-24 14:48:04 +08:00
php_info_print_table_row ( 2 , " Active Links " , buf ) ;
php_info_print_table_end ( ) ;
DISPLAY_INI_ENTRIES ( ) ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2001-04-05 05:40:41 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_do_connect
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_do_connect ( INTERNAL_FUNCTION_PARAMETERS , int persistent )
1999-04-22 10:48:28 +08:00
{
char * host = NULL , * port = NULL , * options = NULL , * tty = NULL , * dbname = NULL , * connstring = NULL ;
PGconn * pgsql ;
2002-04-21 19:29:17 +08:00
smart_str str = { 0 } ;
zval * * args [ 5 ] ;
2002-10-13 17:37:27 +08:00
int i , connect_type = 0 ;
2003-07-28 00:45:10 +08:00
PGresult * pg_result ;
2002-04-21 19:29:17 +08:00
2002-10-13 17:37:27 +08:00
if ( ZEND_NUM_ARGS ( ) < 1 | | ZEND_NUM_ARGS ( ) > 5
2002-04-21 19:29:17 +08:00
| | zend_get_parameters_array_ex ( ZEND_NUM_ARGS ( ) , args ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
smart_str_appends ( & str , " pgsql " ) ;
1999-04-22 10:48:28 +08:00
2002-04-21 19:29:17 +08:00
for ( i = 0 ; i < ZEND_NUM_ARGS ( ) ; i + + ) {
2007-01-07 12:36:40 +08:00
/* 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_PP ( args [ i ] ) = = IS_LONG ) {
if ( Z_LVAL_PP ( args [ 1 ] ) = = PGSQL_CONNECT_FORCE_NEW ) {
continue ;
} else if ( Z_LVAL_PP ( args [ 1 ] ) & PGSQL_CONNECT_FORCE_NEW ) {
smart_str_append_long ( & str , Z_LVAL_PP ( args [ 1 ] ) ^ PGSQL_CONNECT_FORCE_NEW ) ;
}
}
2002-04-21 19:29:17 +08:00
convert_to_string_ex ( args [ i ] ) ;
smart_str_appendc ( & str , ' _ ' ) ;
smart_str_appendl ( & str , Z_STRVAL_PP ( args [ i ] ) , Z_STRLEN_PP ( args [ i ] ) ) ;
}
smart_str_0 ( & str ) ;
if ( ZEND_NUM_ARGS ( ) = = 1 ) { /* new style, using connection string */
connstring = Z_STRVAL_PP ( args [ 0 ] ) ;
2002-10-13 17:37:27 +08:00
} else if ( ZEND_NUM_ARGS ( ) = = 2 ) { /* Safe to add conntype_option, since 2 args was illegal */
2002-10-13 17:41:35 +08:00
connstring = Z_STRVAL_PP ( args [ 0 ] ) ;
2002-10-13 17:37:27 +08:00
convert_to_long_ex ( args [ 1 ] ) ;
connect_type = Z_LVAL_PP ( args [ 1 ] ) ;
2002-04-21 19:29:17 +08:00
} else {
host = Z_STRVAL_PP ( args [ 0 ] ) ;
port = Z_STRVAL_PP ( args [ 1 ] ) ;
dbname = Z_STRVAL_PP ( args [ ZEND_NUM_ARGS ( ) - 1 ] ) ;
switch ( ZEND_NUM_ARGS ( ) ) {
case 5 :
tty = Z_STRVAL_PP ( args [ 3 ] ) ;
/* fall through */
case 4 :
options = Z_STRVAL_PP ( args [ 2 ] ) ;
1999-04-22 10:48:28 +08:00
break ;
2002-03-11 15:23:07 +08:00
}
1999-04-22 10:48:28 +08:00
}
2001-07-14 01:13:00 +08:00
if ( persistent & & PGG ( allow_persistent ) ) {
2005-12-06 07:38:04 +08:00
zend_rsrc_list_entry * le ;
1999-04-22 10:48:28 +08:00
/* try to find if we already have this link in our persistent list */
2002-04-21 19:29:17 +08:00
if ( zend_hash_find ( & EG ( persistent_list ) , str . c , str . len + 1 , ( void * * ) & le ) = = FAILURE ) { /* we don't */
2005-12-06 07:38:04 +08:00
zend_rsrc_list_entry new_le ;
1999-04-22 10:48:28 +08:00
1999-11-20 08:30:08 +08:00
if ( PGG ( max_links ) ! = - 1 & & PGG ( num_links ) > = PGG ( max_links ) ) {
2002-09-05 06:25:13 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING ,
2003-08-29 07:04:27 +08:00
" Cannot create new link. Too many open links (%ld) " , PGG ( num_links ) ) ;
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
1999-11-20 08:30:08 +08:00
if ( PGG ( max_persistent ) ! = - 1 & & PGG ( num_persistent ) > = PGG ( max_persistent ) ) {
2002-09-05 06:25:13 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING ,
2003-08-29 07:04:27 +08:00
" Cannot create new link. Too many open persistent links (%ld) " , PGG ( num_persistent ) ) ;
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
/* create the link */
if ( connstring ) {
pgsql = PQconnectdb ( connstring ) ;
} else {
pgsql = PQsetdb ( host , port , options , tty , dbname ) ;
}
if ( pgsql = = NULL | | PQstatus ( pgsql ) = = CONNECTION_BAD ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Unable to connect to PostgreSQL server: %s " , pgsql )
2001-04-30 01:33:11 +08:00
if ( pgsql ) {
PQfinish ( pgsql ) ;
}
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
/* hash it up */
2001-09-26 05:58:48 +08:00
Z_TYPE ( new_le ) = le_plink ;
1999-04-22 10:48:28 +08:00
new_le . ptr = pgsql ;
2005-12-06 07:38:04 +08:00
if ( zend_hash_update ( & EG ( persistent_list ) , str . c , str . len + 1 , ( void * ) & new_le , sizeof ( zend_rsrc_list_entry ) , NULL ) = = FAILURE ) {
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
1999-11-20 08:30:08 +08:00
PGG ( num_links ) + + ;
PGG ( num_persistent ) + + ;
1999-04-22 10:48:28 +08:00
} else { /* we do */
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( le ) ! = le_plink ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
/* ensure that the link did not die */
2003-02-09 15:24:18 +08:00
if ( PGG ( auto_reset_persistent ) & 1 ) {
2002-01-24 17:27:43 +08:00
/* need to send & get something from backend to
make sure we catch CONNECTION_BAD everytime */
PGresult * pg_result ;
pg_result = PQexec ( le - > ptr , " select 1 " ) ;
PQclear ( pg_result ) ;
}
1999-04-22 10:48:28 +08:00
if ( PQstatus ( le - > ptr ) = = CONNECTION_BAD ) { /* the link died */
2002-01-24 17:27:43 +08:00
if ( le - > ptr = = NULL ) {
if ( connstring ) {
le - > ptr = PQconnectdb ( connstring ) ;
} else {
le - > ptr = PQsetdb ( host , port , options , tty , dbname ) ;
}
}
else {
PQreset ( le - > ptr ) ;
1999-04-22 10:48:28 +08:00
}
if ( le - > ptr = = NULL | | PQstatus ( le - > ptr ) = = CONNECTION_BAD ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " PostgreSQL link lost, unable to reconnect " ) ;
2002-04-21 19:29:17 +08:00
zend_hash_del ( & EG ( persistent_list ) , str . c , str . len + 1 ) ;
goto err ;
1999-04-22 10:48:28 +08:00
}
}
2003-07-28 00:45:10 +08:00
pgsql = ( PGconn * ) le - > ptr ;
# if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
if ( PQprotocolVersion ( pgsql ) > = 3 & & atof ( PQparameterStatus ( pgsql , " server_version " ) ) > = 7.2 ) {
# else
2003-07-22 04:53:00 +08:00
if ( atof ( PG_VERSION ) > = 7.2 ) {
2003-07-28 00:45:10 +08:00
# endif
pg_result = PQexec ( pgsql , " RESET ALL; " ) ;
2003-07-22 04:53:00 +08:00
PQclear ( pg_result ) ;
}
1999-04-22 10:48:28 +08:00
}
2000-05-25 15:51:40 +08:00
ZEND_REGISTER_RESOURCE ( return_value , pgsql , le_plink ) ;
2003-02-21 05:48:58 +08:00
} else { /* Non persistent connection */
2005-12-06 07:38:04 +08:00
zend_rsrc_list_entry * index_ptr , new_index_ptr ;
1999-04-22 10:48:28 +08:00
/* 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 .
*/
2002-10-13 17:37:27 +08:00
if ( ! ( connect_type & PGSQL_CONNECT_FORCE_NEW )
& & zend_hash_find ( & EG ( regular_list ) , str . c , str . len + 1 , ( void * * ) & index_ptr ) = = SUCCESS ) {
1999-04-22 10:48:28 +08:00
int type , link ;
void * ptr ;
2001-09-26 05:58:48 +08:00
if ( Z_TYPE_P ( index_ptr ) ! = le_index_ptr ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2002-10-13 17:48:18 +08:00
link = ( int ) index_ptr - > ptr ;
1999-12-18 03:51:39 +08:00
ptr = zend_list_find ( link , & type ) ; /* check if the link is still there */
1999-11-20 09:04:45 +08:00
if ( ptr & & ( type = = le_link | | type = = le_plink ) ) {
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = link ;
2001-02-15 10:15:36 +08:00
zend_list_addref ( link ) ;
2002-02-06 15:16:10 +08:00
php_pgsql_set_default_link ( link TSRMLS_CC ) ;
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_RESOURCE ;
2002-04-21 19:29:17 +08:00
goto cleanup ;
1999-04-22 10:48:28 +08:00
} else {
2002-04-21 19:29:17 +08:00
zend_hash_del ( & EG ( regular_list ) , str . c , str . len + 1 ) ;
1999-04-22 10:48:28 +08:00
}
}
1999-11-20 08:30:08 +08:00
if ( PGG ( max_links ) ! = - 1 & & PGG ( num_links ) > = PGG ( max_links ) ) {
2003-08-29 07:04:27 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot create new link. Too many open links (%ld) " , PGG ( num_links ) ) ;
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
if ( connstring ) {
2000-05-25 15:51:40 +08:00
pgsql = PQconnectdb ( connstring ) ;
1999-04-22 10:48:28 +08:00
} else {
2000-05-25 15:51:40 +08:00
pgsql = PQsetdb ( host , port , options , tty , dbname ) ;
1999-04-22 10:48:28 +08:00
}
if ( pgsql = = NULL | | PQstatus ( pgsql ) = = CONNECTION_BAD ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Unable to connect to PostgreSQL server: %s " , pgsql ) ;
2004-01-29 10:54:30 +08:00
if ( pgsql ) {
PQfinish ( pgsql ) ;
}
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
/* add it to the list */
2000-05-25 15:51:40 +08:00
ZEND_REGISTER_RESOURCE ( return_value , pgsql , le_link ) ;
1999-04-22 10:48:28 +08:00
/* add it to the hash */
2001-09-26 05:58:48 +08:00
new_index_ptr . ptr = ( void * ) Z_LVAL_P ( return_value ) ;
Z_TYPE ( new_index_ptr ) = le_index_ptr ;
2005-12-06 07:38:04 +08:00
if ( zend_hash_update ( & EG ( regular_list ) , str . c , str . len + 1 , ( void * ) & new_index_ptr , sizeof ( zend_rsrc_list_entry ) , NULL ) = = FAILURE ) {
2002-04-21 19:29:17 +08:00
goto err ;
1999-04-22 10:48:28 +08:00
}
1999-11-20 08:30:08 +08:00
PGG ( num_links ) + + ;
1999-04-22 10:48:28 +08:00
}
2002-04-06 13:52:52 +08:00
/* set notice processer */
if ( ! PGG ( ignore_notices ) & & Z_TYPE_P ( return_value ) = = IS_RESOURCE ) {
2005-11-07 20:57:49 +08:00
PQsetNoticeProcessor ( pgsql , _php_pgsql_notice_handler , ( void * ) Z_RESVAL_P ( return_value ) ) ;
2002-04-06 13:52:52 +08:00
}
2002-02-06 15:16:10 +08:00
php_pgsql_set_default_link ( Z_LVAL_P ( return_value ) TSRMLS_CC ) ;
2002-04-21 19:29:17 +08:00
cleanup :
smart_str_free ( & str ) ;
return ;
err :
smart_str_free ( & str ) ;
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2002-02-06 15:16:10 +08:00
#if 0
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_get_default_link
*/
2002-02-06 15:16:10 +08:00
static int php_pgsql_get_default_link ( INTERNAL_FUNCTION_PARAMETERS )
1999-04-22 10:48:28 +08:00
{
1999-11-20 08:30:08 +08:00
if ( PGG ( default_link ) = = - 1 ) { /* no link opened yet, implicitly open one */
1999-07-23 07:54:54 +08:00
ht = 0 ;
1999-12-18 19:38:04 +08:00
php_pgsql_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 10:48:28 +08:00
}
1999-11-20 08:30:08 +08:00
return PGG ( default_link ) ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
2002-02-06 15:16:10 +08:00
# endif
1999-07-23 07:54:54 +08:00
2002-10-13 17:37:27 +08:00
/* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database)
1999-04-22 10:48:28 +08:00
Open a PostgreSQL connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_connect )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2002-10-13 17:37:27 +08:00
/* {{{ proto resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database)
1999-04-22 10:48:28 +08:00
Open a persistent PostgreSQL connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_pconnect )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_do_connect ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto bool pg_close([resource connection])
1999-04-22 10:48:28 +08:00
Close a PostgreSQL connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_close )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |r " , & pgsql_link ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
if ( argc = = 0 ) {
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-11-03 10:46:49 +08:00
if ( id = = - 1 ) { /* explicit resource number */
2008-06-30 06:38:55 +08:00
zend_list_delete ( Z_RESVAL_P ( pgsql_link ) ) ;
2000-11-03 10:46:49 +08:00
}
if ( id ! = - 1
2008-06-30 06:38:55 +08:00
| | ( pgsql_link & & Z_RESVAL_P ( pgsql_link ) = = PGG ( default_link ) ) ) {
2001-03-26 16:00:43 +08:00
zend_list_delete ( PGG ( default_link ) ) ;
2000-11-03 10:46:49 +08:00
PGG ( default_link ) = - 1 ;
2000-11-03 08:51:53 +08:00
}
1999-04-22 10:48:28 +08:00
RETURN_TRUE ;
}
/* }}} */
1999-12-18 19:38:04 +08:00
# define PHP_PG_DBNAME 1
# define PHP_PG_ERROR_MESSAGE 2
# define PHP_PG_OPTIONS 3
# define PHP_PG_PORT 4
# define PHP_PG_TTY 5
# define PHP_PG_HOST 6
2003-07-23 07:05:17 +08:00
# define PHP_PG_VERSION 7
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_get_link_info
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAMETERS , int entry_type )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
PGconn * pgsql ;
2003-07-21 00:00:40 +08:00
char * msgbuf ;
1999-11-20 08:30:08 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |r " , & pgsql_link ) = = FAILURE ) {
return ;
}
if ( argc = = 0 ) {
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
switch ( entry_type ) {
1999-12-18 19:38:04 +08:00
case PHP_PG_DBNAME :
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = PQdb ( pgsql ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_ERROR_MESSAGE :
2003-07-21 00:00:40 +08:00
RETURN_STRING ( PQErrorMessageTrim ( pgsql , & msgbuf ) , 0 ) ;
return ;
1999-12-18 19:38:04 +08:00
case PHP_PG_OPTIONS :
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = PQoptions ( pgsql ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_PORT :
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = PQport ( pgsql ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_TTY :
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = PQtty ( pgsql ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_HOST :
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = PQhost ( pgsql ) ;
1999-04-22 10:48:28 +08:00
break ;
2003-07-23 07:05:17 +08:00
case PHP_PG_VERSION :
array_init ( return_value ) ;
add_assoc_string ( return_value , " client " , PG_VERSION , 1 ) ;
# if HAVE_PQPROTOCOLVERSION
add_assoc_long ( return_value , " protocol " , PQprotocolVersion ( pgsql ) ) ;
# if HAVE_PQPARAMETERSTATUS
if ( PQprotocolVersion ( pgsql ) > = 3 ) {
2003-07-28 00:45:10 +08:00
add_assoc_string ( return_value , " server " , ( char * ) PQparameterStatus ( pgsql , " server_version " ) , 1 ) ;
2003-07-23 07:05:17 +08:00
}
# endif
# endif
return ;
1999-04-22 10:48:28 +08:00
default :
RETURN_FALSE ;
}
2003-07-23 06:05:46 +08:00
if ( Z_STRVAL_P ( return_value ) ) {
Z_STRLEN_P ( return_value ) = strlen ( Z_STRVAL_P ( return_value ) ) ;
Z_STRVAL_P ( return_value ) = ( char * ) estrdup ( Z_STRVAL_P ( return_value ) ) ;
} else {
Z_STRLEN_P ( return_value ) = 0 ;
Z_STRVAL_P ( return_value ) = ( char * ) estrdup ( " " ) ;
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_STRING ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_dbname([resource connection])
1999-04-22 10:48:28 +08:00
Get the database name */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_dbname )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_DBNAME ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto string pg_last_error([resource connection])
1999-04-22 10:48:28 +08:00
Get the error message string */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_last_error )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_ERROR_MESSAGE ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_options([resource connection])
1999-04-22 10:48:28 +08:00
Get the options associated with the connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_options )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_OPTIONS ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto int pg_port([resource connection])
1999-04-22 10:48:28 +08:00
Return the port number associated with the connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_port )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_PORT ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_tty([resource connection])
1999-04-22 10:48:28 +08:00
Return the tty name associated with the connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_tty )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_TTY ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_host([resource connection])
1999-04-22 10:48:28 +08:00
Returns the host name associated with the connection */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_host )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_HOST ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2003-07-23 07:05:17 +08:00
/* {{{ proto array pg_version([resource connection])
Returns an array with client , protocol and server version ( when available ) */
PHP_FUNCTION ( pg_version )
{
php_pgsql_get_link_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_VERSION ) ;
}
/* }}} */
2003-07-28 00:47:36 +08:00
# if HAVE_PQPARAMETERSTATUS
/* {{{ proto string|false pg_parameter_status([resource connection,] string param_name)
Returns the value of a server parameter */
PHP_FUNCTION ( pg_parameter_status )
{
zval * pgsql_link ;
int id ;
PGconn * pgsql ;
char * param ;
int len ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & pgsql_link , & param , & len ) = = SUCCESS ) {
id = - 1 ;
} else if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & param , & len ) = = SUCCESS ) {
pgsql_link = NULL ;
id = PGG ( default_link ) ;
} else {
RETURN_FALSE ;
}
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
param = ( char * ) PQparameterStatus ( pgsql , param ) ;
if ( param ) {
RETURN_STRING ( param , 1 ) ;
} else {
RETURN_FALSE ;
}
}
/* }}} */
# endif
2003-07-28 00:45:10 +08:00
/* {{{ proto bool pg_ping([resource connection])
2002-10-02 10:41:21 +08:00
Ping database . If connection is bad , try to reconnect . */
PHP_FUNCTION ( pg_ping )
{
2003-07-28 00:45:10 +08:00
zval * pgsql_link ;
int id ;
2002-10-02 10:41:21 +08:00
PGconn * pgsql ;
2003-06-23 00:46:24 +08:00
PGresult * res ;
2002-10-02 10:41:21 +08:00
2003-07-28 00:45:10 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & pgsql_link ) = = SUCCESS ) {
id = - 1 ;
} else {
pgsql_link = NULL ;
id = PGG ( default_link ) ;
2002-10-02 10:41:21 +08:00
}
2003-07-28 00:45:10 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2002-10-02 10:41:21 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
/* ping connection */
2003-06-23 00:46:24 +08:00
res = PQexec ( pgsql , " SELECT 1; " ) ;
PQclear ( res ) ;
2002-10-02 10:41:21 +08:00
/* check status. */
if ( PQstatus ( pgsql ) = = CONNECTION_OK )
RETURN_TRUE ;
/* reset connection if it's broken */
PQreset ( pgsql ) ;
if ( PQstatus ( pgsql ) = = CONNECTION_OK ) {
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto resource pg_query([resource connection,] string query)
1999-04-22 10:48:28 +08:00
Execute a query */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_query )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
char * query ;
int id = - 1 , query_len , argc = ZEND_NUM_ARGS ( ) ;
2001-12-10 12:02:08 +08:00
int leftover = 0 ;
1999-04-22 10:48:28 +08:00
PGconn * pgsql ;
PGresult * pgsql_result ;
2000-05-25 15:51:40 +08:00
ExecStatusType status ;
1999-04-22 10:48:28 +08:00
pgsql_result_handle * pg_result ;
2003-07-21 00:00:40 +08:00
2008-06-30 06:38:55 +08:00
if ( argc = = 1 ) {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & query , & query_len ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & pgsql_link , & query , & query_len ) = = FAILURE ) {
return ;
}
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
2008-06-30 06:38:55 +08:00
}
2003-05-31 03:12:26 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-05-25 15:51:40 +08:00
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
2002-03-29 19:24:54 +08:00
RETURN_FALSE ;
}
2001-12-10 12:02:08 +08:00
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
leftover = 1 ;
}
if ( leftover ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Found results on this connection. Use pg_get_result() to get these results first " ) ;
2001-12-10 12:02:08 +08:00
}
2008-06-30 06:38:55 +08:00
pgsql_result = PQexec ( pgsql , query ) ;
2003-02-09 15:24:18 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQclear ( pgsql_result ) ;
PQreset ( pgsql ) ;
2008-06-30 06:38:55 +08:00
pgsql_result = PQexec ( pgsql , query ) ;
2003-02-09 15:24:18 +08:00
}
1999-04-22 10:48:28 +08:00
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
switch ( status ) {
case PGRES_EMPTY_QUERY :
case PGRES_BAD_RESPONSE :
case PGRES_NONFATAL_ERROR :
case PGRES_FATAL_ERROR :
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
2003-08-15 01:49:08 +08:00
PQclear ( pgsql_result ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
break ;
case PGRES_COMMAND_OK : /* successful command that did not return rows */
default :
if ( pgsql_result ) {
pg_result = ( pgsql_result_handle * ) emalloc ( sizeof ( pgsql_result_handle ) ) ;
pg_result - > conn = pgsql ;
pg_result - > result = pgsql_result ;
2003-02-09 15:24:18 +08:00
pg_result - > row = 0 ;
2000-05-25 15:51:40 +08:00
ZEND_REGISTER_RESOURCE ( return_value , pg_result , le_result ) ;
1999-04-22 10:48:28 +08:00
} else {
2003-08-15 01:49:08 +08:00
PQclear ( pgsql_result ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
break ;
}
}
/* }}} */
2001-06-05 21:12:10 +08:00
2005-03-19 17:07:20 +08:00
# if HAVE_PQEXECPARAMS || HAVE_PQEXECPREPARED || HAVE_PQSENDQUERYPARAMS || HAVE_PQSENDQUERYPREPARED
2005-03-19 16:46:56 +08:00
/* {{{ _php_pgsql_free_params */
static void _php_pgsql_free_params ( char * * params , int num_params )
{
if ( num_params > 0 ) {
2008-10-02 04:30:23 +08:00
int i ;
for ( i = 0 ; i < num_params ; i + + ) {
efree ( params [ i ] ) ;
}
2005-03-19 16:46:56 +08:00
efree ( params ) ;
}
}
/* }}} */
# endif
# if HAVE_PQEXECPARAMS
/* {{{ proto resource pg_query_params([resource connection,] string query, array params)
Execute a query */
PHP_FUNCTION ( pg_query_params )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
zval * pv_param_arr , * * tmp ;
char * query ;
int query_len , id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2005-03-19 16:46:56 +08:00
int leftover = 0 ;
int num_params = 0 ;
char * * params = NULL ;
PGconn * pgsql ;
PGresult * pgsql_result ;
ExecStatusType status ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " sa " , & query , & query_len , & pv_param_arr ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa " , & pgsql_link , & query , & query_len , & pv_param_arr ) = = FAILURE ) {
return ;
}
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
2005-03-19 16:46:56 +08:00
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
RETURN_FALSE ;
}
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Found results on this connection. Use pg_get_result() to get these results first " ) ;
}
2008-06-30 06:38:55 +08:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( pv_param_arr ) ) ;
num_params = zend_hash_num_elements ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
if ( num_params > 0 ) {
int i = 0 ;
params = ( char * * ) safe_emalloc ( sizeof ( char * ) , num_params , 0 ) ;
for ( i = 0 ; i < num_params ; i + + ) {
2008-06-30 06:38:55 +08:00
if ( zend_hash_get_current_data ( Z_ARRVAL_P ( pv_param_arr ) , ( void * * ) & tmp ) = = FAILURE ) {
2005-03-19 16:46:56 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error getting parameter " ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
2008-10-02 04:30:23 +08:00
if ( Z_TYPE_PP ( tmp ) = = IS_NULL ) {
2005-03-19 16:46:56 +08:00
params [ i ] = NULL ;
2008-10-02 04:30:23 +08:00
} else {
zval tmp_val = * * tmp ;
zval_copy_ctor ( & tmp_val ) ;
convert_to_string ( & tmp_val ) ;
if ( Z_TYPE ( tmp_val ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error converting parameter " ) ;
zval_dtor ( & tmp_val ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
params [ i ] = estrndup ( Z_STRVAL ( tmp_val ) , Z_STRLEN ( tmp_val ) ) ;
zval_dtor ( & tmp_val ) ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
zend_hash_move_forward ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
}
}
2008-06-30 06:38:55 +08:00
pgsql_result = PQexecParams ( pgsql , query , num_params ,
2005-03-19 16:46:56 +08:00
NULL , ( const char * const * ) params , NULL , NULL , 0 ) ;
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQclear ( pgsql_result ) ;
PQreset ( pgsql ) ;
2008-06-30 06:38:55 +08:00
pgsql_result = PQexecParams ( pgsql , query , num_params ,
2005-03-19 16:46:56 +08:00
NULL , ( const char * const * ) params , NULL , NULL , 0 ) ;
}
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
_php_pgsql_free_params ( params , num_params ) ;
switch ( status ) {
case PGRES_EMPTY_QUERY :
case PGRES_BAD_RESPONSE :
case PGRES_NONFATAL_ERROR :
case PGRES_FATAL_ERROR :
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
break ;
case PGRES_COMMAND_OK : /* successful command that did not return rows */
default :
if ( pgsql_result ) {
pg_result = ( pgsql_result_handle * ) emalloc ( sizeof ( pgsql_result_handle ) ) ;
pg_result - > conn = pgsql ;
pg_result - > result = pgsql_result ;
pg_result - > row = 0 ;
ZEND_REGISTER_RESOURCE ( return_value , pg_result , le_result ) ;
} else {
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
}
break ;
}
}
/* }}} */
# endif
# if HAVE_PQPREPARE
/* {{{ proto resource pg_prepare([resource connection,] string stmtname, string query)
Prepare a query for future execution */
PHP_FUNCTION ( pg_prepare )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
char * query , * stmtname ;
int query_len , stmtname_len , id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2005-03-19 16:46:56 +08:00
int leftover = 0 ;
PGconn * pgsql ;
PGresult * pgsql_result ;
ExecStatusType status ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " ss " , & stmtname , & stmtname_len , & query , & query_len ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rss " , & pgsql_link , & stmtname , & stmtname_len , & query , & query_len ) = = FAILURE ) {
return ;
}
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
2005-03-19 16:46:56 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
RETURN_FALSE ;
}
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Found results on this connection. Use pg_get_result() to get these results first " ) ;
}
2008-06-30 06:38:55 +08:00
pgsql_result = PQprepare ( pgsql , stmtname , query , 0 , NULL ) ;
2005-03-19 16:46:56 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQclear ( pgsql_result ) ;
PQreset ( pgsql ) ;
2008-06-30 06:38:55 +08:00
pgsql_result = PQprepare ( pgsql , stmtname , query , 0 , NULL ) ;
2005-03-19 16:46:56 +08:00
}
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
switch ( status ) {
case PGRES_EMPTY_QUERY :
case PGRES_BAD_RESPONSE :
case PGRES_NONFATAL_ERROR :
case PGRES_FATAL_ERROR :
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
break ;
case PGRES_COMMAND_OK : /* successful command that did not return rows */
default :
if ( pgsql_result ) {
pg_result = ( pgsql_result_handle * ) emalloc ( sizeof ( pgsql_result_handle ) ) ;
pg_result - > conn = pgsql ;
pg_result - > result = pgsql_result ;
pg_result - > row = 0 ;
ZEND_REGISTER_RESOURCE ( return_value , pg_result , le_result ) ;
} else {
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
}
break ;
}
}
/* }}} */
# endif
# if HAVE_PQEXECPREPARED
/* {{{ proto resource pg_execute([resource connection,] string stmtname, array params)
Execute a prepared query */
PHP_FUNCTION ( pg_execute )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
zval * pv_param_arr , * * tmp ;
char * stmtname ;
int stmtname_len , id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2005-03-19 16:46:56 +08:00
int leftover = 0 ;
int num_params = 0 ;
char * * params = NULL ;
PGconn * pgsql ;
PGresult * pgsql_result ;
ExecStatusType status ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " sa/ " , & stmtname , & stmtname_len , & pv_param_arr ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa/ " , & pgsql_link , & stmtname , & stmtname_len , & pv_param_arr ) = = FAILURE ) {
return ;
}
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
2005-03-19 16:46:56 +08:00
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
RETURN_FALSE ;
}
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Found results on this connection. Use pg_get_result() to get these results first " ) ;
}
2008-06-30 06:38:55 +08:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( pv_param_arr ) ) ;
num_params = zend_hash_num_elements ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
if ( num_params > 0 ) {
int i = 0 ;
params = ( char * * ) safe_emalloc ( sizeof ( char * ) , num_params , 0 ) ;
for ( i = 0 ; i < num_params ; i + + ) {
2008-06-30 06:38:55 +08:00
if ( zend_hash_get_current_data ( Z_ARRVAL_P ( pv_param_arr ) , ( void * * ) & tmp ) = = FAILURE ) {
2005-03-19 16:46:56 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error getting parameter " ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
2008-10-02 04:30:23 +08:00
if ( Z_TYPE_PP ( tmp ) = = IS_NULL ) {
2005-03-19 16:46:56 +08:00
params [ i ] = NULL ;
2006-11-14 06:10:37 +08:00
} else {
2008-10-02 04:30:23 +08:00
zval tmp_val = * * tmp ;
zval_copy_ctor ( & tmp_val ) ;
convert_to_string ( & tmp_val ) ;
if ( Z_TYPE ( tmp_val ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error converting parameter " ) ;
zval_dtor ( & tmp_val ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
params [ i ] = estrndup ( Z_STRVAL ( tmp_val ) , Z_STRLEN ( tmp_val ) ) ;
zval_dtor ( & tmp_val ) ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
zend_hash_move_forward ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
}
}
2008-06-30 06:38:55 +08:00
pgsql_result = PQexecPrepared ( pgsql , stmtname , num_params ,
2005-03-19 16:46:56 +08:00
( const char * const * ) params , NULL , NULL , 0 ) ;
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQclear ( pgsql_result ) ;
PQreset ( pgsql ) ;
2008-06-30 06:38:55 +08:00
pgsql_result = PQexecPrepared ( pgsql , stmtname , num_params ,
2005-03-19 16:46:56 +08:00
( const char * const * ) params , NULL , NULL , 0 ) ;
}
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
_php_pgsql_free_params ( params , num_params ) ;
switch ( status ) {
case PGRES_EMPTY_QUERY :
case PGRES_BAD_RESPONSE :
case PGRES_NONFATAL_ERROR :
case PGRES_FATAL_ERROR :
2006-03-28 08:28:02 +08:00
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
2005-03-19 16:46:56 +08:00
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
break ;
case PGRES_COMMAND_OK : /* successful command that did not return rows */
default :
if ( pgsql_result ) {
pg_result = ( pgsql_result_handle * ) emalloc ( sizeof ( pgsql_result_handle ) ) ;
pg_result - > conn = pgsql ;
pg_result - > result = pgsql_result ;
pg_result - > row = 0 ;
ZEND_REGISTER_RESOURCE ( return_value , pg_result , le_result ) ;
} else {
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
}
break ;
}
}
/* }}} */
# endif
1999-12-18 19:38:04 +08:00
# define PHP_PG_NUM_ROWS 1
# define PHP_PG_NUM_FIELDS 2
# define PHP_PG_CMD_TUPLES 3
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_get_result_info
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_get_result_info ( INTERNAL_FUNCTION_PARAMETERS , int entry_type )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
1999-11-20 08:30:08 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & result ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2001-12-17 08:24:59 +08:00
1999-04-22 10:48:28 +08:00
switch ( entry_type ) {
1999-12-18 19:38:04 +08:00
case PHP_PG_NUM_ROWS :
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = PQntuples ( pgsql_result ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_NUM_FIELDS :
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = PQnfields ( pgsql_result ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_CMD_TUPLES :
1999-04-22 10:48:28 +08:00
# if HAVE_PQCMDTUPLES
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = atoi ( PQcmdTuples ( pgsql_result ) ) ;
1999-04-22 10:48:28 +08:00
# else
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Not supported under this build " ) ;
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = 0 ;
1999-04-22 10:48:28 +08:00
# endif
break ;
default :
RETURN_FALSE ;
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_num_rows(resource result)
1999-04-22 10:48:28 +08:00
Return the number of rows in the result */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_num_rows )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_result_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_NUM_ROWS ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_num_fields(resource result)
1999-04-22 10:48:28 +08:00
Return the number of fields in the result */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_num_fields )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_result_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_NUM_FIELDS ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2005-04-14 05:48:33 +08:00
# if HAVE_PQCMDTUPLES
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_affected_rows(resource result)
1999-04-22 10:48:28 +08:00
Returns the number of affected tuples */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_affected_rows )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_result_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_CMD_TUPLES ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2005-04-14 05:48:33 +08:00
# endif
1999-04-22 10:48:28 +08:00
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_last_notice(resource connection)
2001-05-06 14:33:48 +08:00
Returns the last notice set by the backend */
2001-06-04 16:06:07 +08:00
PHP_FUNCTION ( pg_last_notice )
{
2002-04-06 13:52:52 +08:00
zval * pgsql_link ;
PGconn * pg_link ;
int id = - 1 ;
php_pgsql_notice * * notice ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & pgsql_link ) = = FAILURE ) {
2002-04-06 13:52:52 +08:00
return ;
}
/* Just to check if user passed valid resoruce */
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( zend_hash_index_find ( & PGG ( notices ) , Z_RESVAL_P ( pgsql_link ) , ( void * * ) & notice ) = = FAILURE ) {
2001-09-27 05:44:48 +08:00
RETURN_FALSE ;
2001-05-06 09:34:56 +08:00
}
2002-04-06 13:52:52 +08:00
RETURN_STRINGL ( ( * notice ) - > message , ( * notice ) - > len , 1 ) ;
2001-05-06 09:34:56 +08:00
}
/* }}} */
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ get_field_name
*/
2002-02-06 15:16:10 +08:00
static char * get_field_name ( PGconn * pgsql , Oid oid , HashTable * list TSRMLS_DC )
1999-04-22 10:48:28 +08:00
{
PGresult * result ;
2002-04-21 17:46:29 +08:00
smart_str str = { 0 } ;
2005-12-06 07:38:04 +08:00
zend_rsrc_list_entry * field_type ;
1999-04-22 10:48:28 +08:00
char * ret = NULL ;
1999-11-20 08:30:08 +08:00
1999-04-22 10:48:28 +08:00
/* try to lookup the type in the resource list */
2002-04-21 17:46:29 +08:00
smart_str_appends ( & str , " pgsql_oid_ " ) ;
smart_str_append_unsigned ( & str , oid ) ;
smart_str_0 ( & str ) ;
1999-04-22 10:48:28 +08:00
2002-04-21 17:46:29 +08:00
if ( zend_hash_find ( list , str . c , str . len + 1 , ( void * * ) & field_type ) = = SUCCESS ) {
1999-04-22 10:48:28 +08:00
ret = estrdup ( ( char * ) field_type - > ptr ) ;
} else { /* hash all oid's */
int i , num_rows ;
int oid_offset , name_offset ;
2002-04-20 10:31:48 +08:00
char * tmp_oid , * end_ptr , * tmp_name ;
2005-12-06 07:38:04 +08:00
zend_rsrc_list_entry new_oid_entry ;
1999-04-22 10:48:28 +08:00
2003-08-28 08:31:36 +08:00
if ( ( result = PQexec ( pgsql , " select oid,typname from pg_type " ) ) = = NULL | | PQresultStatus ( result ) ! = PGRES_TUPLES_OK ) {
if ( result ) {
PQclear ( result ) ;
}
2002-04-21 17:46:29 +08:00
smart_str_free ( & str ) ;
2004-07-19 15:19:50 +08:00
return STR_EMPTY_ALLOC ( ) ;
1999-04-22 10:48:28 +08:00
}
2000-05-25 15:51:40 +08:00
num_rows = PQntuples ( result ) ;
1999-04-22 10:48:28 +08:00
oid_offset = PQfnumber ( result , " oid " ) ;
name_offset = PQfnumber ( result , " typname " ) ;
for ( i = 0 ; i < num_rows ; i + + ) {
2000-05-25 15:51:40 +08:00
if ( ( tmp_oid = PQgetvalue ( result , i , oid_offset ) ) = = NULL ) {
1999-04-22 10:48:28 +08:00
continue ;
}
2002-04-21 17:46:29 +08:00
str . len = 0 ;
smart_str_appends ( & str , " pgsql_oid_ " ) ;
smart_str_appends ( & str , tmp_oid ) ;
smart_str_0 ( & str ) ;
2000-05-25 15:51:40 +08:00
if ( ( tmp_name = PQgetvalue ( result , i , name_offset ) ) = = NULL ) {
1999-04-22 10:48:28 +08:00
continue ;
}
2001-09-26 05:58:48 +08:00
Z_TYPE ( new_oid_entry ) = le_string ;
1999-04-22 10:48:28 +08:00
new_oid_entry . ptr = estrdup ( tmp_name ) ;
2005-12-06 07:38:04 +08:00
zend_hash_update ( list , str . c , str . len + 1 , ( void * ) & new_oid_entry , sizeof ( zend_rsrc_list_entry ) , NULL ) ;
2002-04-20 10:31:48 +08:00
if ( ! ret & & strtoul ( tmp_oid , & end_ptr , 10 ) = = oid ) {
1999-04-22 10:48:28 +08:00
ret = estrdup ( tmp_name ) ;
}
}
2003-08-15 01:49:08 +08:00
PQclear ( result ) ;
1999-04-22 10:48:28 +08:00
}
2002-04-21 17:46:29 +08:00
smart_str_free ( & str ) ;
1999-04-22 10:48:28 +08:00
return ret ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2006-09-16 03:47:50 +08:00
# ifdef HAVE_PQFTABLE
2006-05-07 08:28:32 +08:00
/* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only])
Returns the name of the table field belongs to , or table ' s oid if oid_only is true */
PHP_FUNCTION ( pg_field_table )
{
zval * result ;
pgsql_result_handle * pg_result ;
long fnum = - 1 ;
zend_bool return_oid = 0 ;
Oid oid ;
smart_str hash_key = { 0 } ;
char * table_name ;
zend_rsrc_list_entry * field_table ;
2008-09-08 09:33:08 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl|b " , & result , & fnum , & return_oid ) = = FAILURE ) {
2006-05-07 08:28:32 +08:00
return ;
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
if ( fnum < 0 | | fnum > = PQnfields ( pg_result - > result ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Bad field offset specified " ) ;
RETURN_FALSE ;
}
oid = PQftable ( pg_result - > result , fnum ) ;
if ( InvalidOid = = oid ) {
RETURN_FALSE ;
}
if ( return_oid ) {
if ( oid > LONG_MAX ) {
smart_str oidstr = { 0 } ;
smart_str_append_unsigned ( & oidstr , oid ) ;
smart_str_0 ( & oidstr ) ;
RETURN_STRINGL ( oidstr . c , oidstr . len , 0 ) ;
} else {
RETURN_LONG ( ( long ) oid ) ;
}
}
/* try to lookup the table name in the resource list */
smart_str_appends ( & hash_key , " pgsql_table_oid_ " ) ;
smart_str_append_unsigned ( & hash_key , oid ) ;
smart_str_0 ( & hash_key ) ;
if ( zend_hash_find ( & EG ( regular_list ) , hash_key . c , hash_key . len + 1 , ( void * * ) & field_table ) = = SUCCESS ) {
smart_str_free ( & hash_key ) ;
RETURN_STRING ( ( char * ) field_table - > ptr , 1 ) ;
} else { /* Not found, lookup by querying PostgreSQL system tables */
PGresult * tmp_res ;
smart_str querystr = { 0 } ;
zend_rsrc_list_entry new_field_table ;
smart_str_appends ( & querystr , " select relname from pg_class where oid= " ) ;
smart_str_append_unsigned ( & querystr , oid ) ;
smart_str_0 ( & querystr ) ;
if ( ( tmp_res = PQexec ( pg_result - > conn , querystr . c ) ) = = NULL | | PQresultStatus ( tmp_res ) ! = PGRES_TUPLES_OK ) {
if ( tmp_res ) {
PQclear ( tmp_res ) ;
}
smart_str_free ( & querystr ) ;
smart_str_free ( & hash_key ) ;
RETURN_FALSE ;
}
smart_str_free ( & querystr ) ;
if ( ( table_name = PQgetvalue ( tmp_res , 0 , 0 ) ) = = NULL ) {
PQclear ( tmp_res ) ;
smart_str_free ( & hash_key ) ;
RETURN_FALSE ;
}
Z_TYPE ( new_field_table ) = le_string ;
new_field_table . ptr = estrdup ( table_name ) ;
zend_hash_update ( & EG ( regular_list ) , hash_key . c , hash_key . len + 1 , ( void * ) & new_field_table , sizeof ( zend_rsrc_list_entry ) , NULL ) ;
smart_str_free ( & hash_key ) ;
PQclear ( tmp_res ) ;
RETURN_STRING ( table_name , 1 ) ;
}
}
2006-09-16 03:47:50 +08:00
/* }}} */
# endif
2006-05-07 08:28:32 +08:00
1999-12-18 19:38:04 +08:00
# define PHP_PG_FIELD_NAME 1
# define PHP_PG_FIELD_SIZE 2
# define PHP_PG_FIELD_TYPE 3
2005-02-15 07:36:16 +08:00
# define PHP_PG_FIELD_TYPE_OID 4
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_get_field_info
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_get_field_info ( INTERNAL_FUNCTION_PARAMETERS , int entry_type )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result ;
long field ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2005-02-15 07:36:16 +08:00
Oid oid ;
1999-04-22 10:48:28 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & result , & field ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2008-06-30 06:38:55 +08:00
if ( field < 0 | | field > = PQnfields ( pgsql_result ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Bad field offset specified " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
switch ( entry_type ) {
1999-12-18 19:38:04 +08:00
case PHP_PG_FIELD_NAME :
2008-06-30 06:38:55 +08:00
Z_STRVAL_P ( return_value ) = PQfname ( pgsql_result , field ) ;
2001-09-26 05:58:48 +08:00
Z_STRLEN_P ( return_value ) = strlen ( Z_STRVAL_P ( return_value ) ) ;
Z_STRVAL_P ( return_value ) = estrndup ( Z_STRVAL_P ( return_value ) , Z_STRLEN_P ( return_value ) ) ;
Z_TYPE_P ( return_value ) = IS_STRING ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_FIELD_SIZE :
2008-06-30 06:38:55 +08:00
Z_LVAL_P ( return_value ) = PQfsize ( pgsql_result , field ) ;
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_FIELD_TYPE :
2008-06-30 06:38:55 +08:00
Z_STRVAL_P ( return_value ) = get_field_name ( pg_result - > conn , PQftype ( pgsql_result , field ) , & EG ( regular_list ) TSRMLS_CC ) ;
2001-09-26 05:58:48 +08:00
Z_STRLEN_P ( return_value ) = strlen ( Z_STRVAL_P ( return_value ) ) ;
Z_TYPE_P ( return_value ) = IS_STRING ;
1999-04-22 10:48:28 +08:00
break ;
2005-02-15 07:36:16 +08:00
case PHP_PG_FIELD_TYPE_OID :
2008-06-30 06:38:55 +08:00
oid = PQftype ( pgsql_result , field ) ;
2005-02-15 07:36:16 +08:00
if ( oid > LONG_MAX ) {
smart_str s = { 0 } ;
smart_str_append_unsigned ( & s , oid ) ;
smart_str_0 ( & s ) ;
Z_STRVAL_P ( return_value ) = s . c ;
Z_STRLEN_P ( return_value ) = s . len ;
Z_TYPE_P ( return_value ) = IS_STRING ;
2008-06-30 06:38:55 +08:00
} else {
2005-02-15 07:36:16 +08:00
Z_LVAL_P ( return_value ) = ( long ) oid ;
Z_TYPE_P ( return_value ) = IS_LONG ;
}
break ;
1999-04-22 10:48:28 +08:00
default :
RETURN_FALSE ;
}
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-12-17 08:24:59 +08:00
/* {{{ proto string pg_field_name(resource result, int field_number)
1999-04-22 10:48:28 +08:00
Returns the name of the field */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_name )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_field_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_FIELD_NAME ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_field_size(resource result, int field_number)
1999-04-22 10:48:28 +08:00
Returns the internal size of the field */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_size )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_field_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_FIELD_SIZE ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto string pg_field_type(resource result, int field_number)
1999-04-22 10:48:28 +08:00
Returns the type name for the given field */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_type )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_get_field_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_FIELD_TYPE ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2005-02-15 07:36:16 +08:00
/* {{{ proto string pg_field_type_oid(resource result, int field_number)
Returns the type oid for the given field */
PHP_FUNCTION ( pg_field_type_oid )
{
2005-02-15 07:40:24 +08:00
php_pgsql_get_field_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_FIELD_TYPE_OID ) ;
2005-02-15 07:36:16 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_field_num(resource result, string field_name)
1999-04-22 10:48:28 +08:00
Returns the field number of the named field */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_num )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result ;
char * field ;
int field_len ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
1999-11-20 08:30:08 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & result , & field , & field_len ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2008-06-30 06:38:55 +08:00
Z_LVAL_P ( return_value ) = PQfnumber ( pgsql_result , field ) ;
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 19:53:38 +08:00
/* {{{ proto mixed pg_fetch_result(resource result, [int row_number,] mixed field_name)
1999-04-22 10:48:28 +08:00
Returns values from a result identifier */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_fetch_result )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result , * * field = NULL ;
long row ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
int field_offset , pgsql_row , argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rZ " , & result , & field ) = = FAILURE ) {
return ;
}
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rlZ " , & result , & row , & field ) = = FAILURE ) {
return ;
}
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( pg_result - > row < 0 ) {
2001-06-20 02:10:08 +08:00
pg_result - > row = 0 ;
2008-06-30 06:38:55 +08:00
}
2001-06-20 02:10:08 +08:00
pgsql_row = pg_result - > row ;
if ( pgsql_row > = PQntuples ( pgsql_result ) ) {
RETURN_FALSE ;
}
} else {
2008-06-30 06:38:55 +08:00
pgsql_row = row ;
2001-06-20 02:10:08 +08:00
if ( pgsql_row < 0 | | pgsql_row > = PQntuples ( pgsql_result ) ) {
2003-08-29 05:00:24 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to jump to row %ld on PostgreSQL result index %ld " ,
2008-06-30 06:38:55 +08:00
row , Z_LVAL_P ( result ) ) ;
2001-06-20 02:10:08 +08:00
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
}
2000-05-25 15:51:40 +08:00
switch ( Z_TYPE_PP ( field ) ) {
1999-04-22 10:48:28 +08:00
case IS_STRING :
2000-05-25 15:51:40 +08:00
field_offset = PQfnumber ( pgsql_result , Z_STRVAL_PP ( field ) ) ;
1999-04-22 10:48:28 +08:00
break ;
default :
2000-05-25 15:51:40 +08:00
convert_to_long_ex ( field ) ;
field_offset = Z_LVAL_PP ( field ) ;
1999-04-22 10:48:28 +08:00
break ;
}
if ( field_offset < 0 | | field_offset > = PQnfields ( pgsql_result ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Bad column offset specified " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2001-06-20 02:10:08 +08:00
if ( PQgetisnull ( pgsql_result , pgsql_row , field_offset ) ) {
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_NULL ;
2000-08-16 09:03:20 +08:00
} else {
2008-10-13 21:44:32 +08:00
char * value = PQgetvalue ( pgsql_result , pgsql_row , field_offset ) ;
int value_len = PQgetlength ( pgsql_result , pgsql_row , field_offset ) ;
ZVAL_STRINGL ( return_value , value , value_len , 1 ) ;
2000-08-16 09:03:20 +08:00
}
1999-04-22 10:48:28 +08:00
}
/* }}} */
2002-03-03 03:53:11 +08:00
/* {{{ void php_pgsql_fetch_hash */
2004-02-26 04:16:27 +08:00
static void php_pgsql_fetch_hash ( INTERNAL_FUNCTION_PARAMETERS , long result_type , int into_object )
1999-04-22 10:48:28 +08:00
{
2005-11-06 19:58:34 +08:00
zval * result , * zrow = NULL ;
2003-09-07 02:34:55 +08:00
PGresult * pgsql_result ;
1999-04-22 10:48:28 +08:00
pgsql_result_handle * pg_result ;
2003-09-07 02:34:55 +08:00
int i , num_fields , pgsql_row , use_row ;
2005-10-12 00:19:14 +08:00
long row = - 1 ;
2007-11-22 08:17:28 +08:00
char * field_name ;
2003-09-07 02:34:55 +08:00
zval * ctor_params = NULL ;
zend_class_entry * ce = NULL ;
if ( into_object ) {
char * class_name ;
int class_name_len ;
2005-11-06 19:58:34 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|z!sz " , & result , & zrow , & class_name , & class_name_len , & ctor_params ) = = FAILURE ) {
2003-09-07 02:34:55 +08:00
return ;
2005-10-12 00:19:14 +08:00
}
2004-03-16 04:16:59 +08:00
if ( ZEND_NUM_ARGS ( ) < 3 ) {
2003-09-07 02:34:55 +08:00
ce = zend_standard_class_def ;
} else {
ce = zend_fetch_class ( class_name , class_name_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC ) ;
}
if ( ! ce ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Could not find class '%s' " , class_name ) ;
return ;
}
result_type = PGSQL_ASSOC ;
} else {
2005-11-06 19:58:34 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|z!l " , & result , & zrow , & result_type ) = = FAILURE ) {
2003-09-07 02:34:55 +08:00
return ;
}
2004-03-16 04:16:59 +08:00
}
2005-11-06 19:58:34 +08:00
if ( zrow = = NULL ) {
row = - 1 ;
} else {
convert_to_long ( zrow ) ;
row = Z_LVAL_P ( zrow ) ;
}
2005-10-12 00:19:14 +08:00
use_row = ZEND_NUM_ARGS ( ) > 1 & & row ! = - 1 ;
2003-09-07 02:34:55 +08:00
2002-07-15 18:04:01 +08:00
if ( ! ( result_type & PGSQL_BOTH ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid result type " ) ;
2002-07-15 18:04:01 +08:00
RETURN_FALSE ;
}
2003-09-07 02:34:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2001-06-20 02:10:08 +08:00
2003-09-07 02:34:55 +08:00
if ( use_row ) {
pgsql_row = row ;
pg_result - > row = pgsql_row ;
2001-06-20 02:10:08 +08:00
if ( pgsql_row < 0 | | pgsql_row > = PQntuples ( pgsql_result ) ) {
2003-09-07 02:34:55 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to jump to row %ld on PostgreSQL result index %ld " ,
row , Z_LVAL_P ( result ) ) ;
2001-06-20 02:10:08 +08:00
RETURN_FALSE ;
}
} else {
2003-09-07 02:34:55 +08:00
/* If 2nd param is NULL, use internal row counter to access next row */
pgsql_row = pg_result - > row ;
if ( pgsql_row < 0 | | pgsql_row > = PQntuples ( pgsql_result ) ) {
RETURN_FALSE ;
2001-06-20 02:10:08 +08:00
}
2003-09-07 02:34:55 +08:00
pg_result - > row + + ;
1999-04-22 10:48:28 +08:00
}
2003-09-07 02:34:55 +08:00
1999-04-22 10:48:28 +08:00
array_init ( return_value ) ;
2002-03-03 03:53:11 +08:00
for ( i = 0 , num_fields = PQnfields ( pgsql_result ) ; i < num_fields ; i + + ) {
2001-06-20 02:10:08 +08:00
if ( PQgetisnull ( pgsql_result , pgsql_row , i ) ) {
2000-08-16 09:03:20 +08:00
if ( result_type & PGSQL_NUM ) {
2001-02-01 05:53:30 +08:00
add_index_null ( return_value , i ) ;
2000-09-09 17:40:16 +08:00
}
if ( result_type & PGSQL_ASSOC ) {
2000-08-16 09:03:20 +08:00
field_name = PQfname ( pgsql_result , i ) ;
2001-02-01 05:53:30 +08:00
add_assoc_null ( return_value , field_name ) ;
1999-07-17 01:19:11 +08:00
}
2000-08-16 09:03:20 +08:00
} else {
2007-11-22 08:17:28 +08:00
char * element = PQgetvalue ( pgsql_result , pgsql_row , i ) ;
2000-08-16 09:03:20 +08:00
if ( element ) {
char * data ;
int data_len ;
int should_copy = 0 ;
2007-11-22 08:17:28 +08:00
const uint element_len = strlen ( element ) ;
2000-08-16 09:03:20 +08:00
if ( PG ( magic_quotes_runtime ) ) {
2001-08-06 11:50:52 +08:00
data = php_addslashes ( element , element_len , & data_len , 0 TSRMLS_CC ) ;
2000-08-16 09:03:20 +08:00
} else {
data = safe_estrndup ( element , element_len ) ;
data_len = element_len ;
}
1999-07-17 01:19:11 +08:00
2000-08-16 09:03:20 +08:00
if ( result_type & PGSQL_NUM ) {
add_index_stringl ( return_value , i , data , data_len , should_copy ) ;
should_copy = 1 ;
}
1999-07-17 01:19:11 +08:00
2000-08-16 09:03:20 +08:00
if ( result_type & PGSQL_ASSOC ) {
field_name = PQfname ( pgsql_result , i ) ;
add_assoc_stringl ( return_value , field_name , data , data_len , should_copy ) ;
}
1999-07-17 01:19:11 +08:00
}
2000-08-16 09:03:20 +08:00
}
1999-04-22 10:48:28 +08:00
}
2003-09-07 02:34:55 +08:00
if ( into_object ) {
zval dataset = * return_value ;
zend_fcall_info fci ;
zend_fcall_info_cache fcc ;
zval * retval_ptr ;
object_and_properties_init ( return_value , ce , NULL ) ;
zend_merge_properties ( return_value , Z_ARRVAL ( dataset ) , 1 TSRMLS_CC ) ;
if ( ce - > constructor ) {
fci . size = sizeof ( fci ) ;
fci . function_table = & ce - > function_table ;
fci . function_name = NULL ;
fci . symbol_table = NULL ;
fci . object_pp = & return_value ;
fci . retval_ptr_ptr = & retval_ptr ;
if ( ctor_params & & Z_TYPE_P ( ctor_params ) ! = IS_NULL ) {
if ( Z_TYPE_P ( ctor_params ) = = IS_ARRAY ) {
HashTable * ht = Z_ARRVAL_P ( ctor_params ) ;
Bucket * p ;
fci . param_count = 0 ;
2006-12-26 06:36:57 +08:00
fci . params = safe_emalloc ( sizeof ( zval * ) , ht - > nNumOfElements , 0 ) ;
2003-09-07 02:34:55 +08:00
p = ht - > pListHead ;
while ( p ! = NULL ) {
fci . params [ fci . param_count + + ] = ( zval * * ) p - > pData ;
p = p - > pListNext ;
}
} else {
/* Two problems why we throw exceptions here: PHP is typeless
* and hence passing one argument that ' s not an array could be
* by mistake and the other way round is possible , too . The
* single value is an array . Also we ' d have to make that one
* argument passed by reference .
*/
2006-05-10 08:00:13 +08:00
zend_throw_exception ( zend_exception_get_default ( TSRMLS_C ) , " Parameter ctor_params must be an array " , 0 TSRMLS_CC ) ;
2003-09-07 02:34:55 +08:00
return ;
}
} else {
fci . param_count = 0 ;
fci . params = NULL ;
}
fci . no_separation = 1 ;
fcc . initialized = 1 ;
fcc . function_handler = ce - > constructor ;
fcc . calling_scope = EG ( scope ) ;
2008-07-25 16:23:07 +08:00
fcc . called_scope = Z_OBJCE_P ( return_value ) ;
2003-09-07 02:34:55 +08:00
fcc . object_pp = & return_value ;
if ( zend_call_function ( & fci , & fcc TSRMLS_CC ) = = FAILURE ) {
2006-05-10 08:00:13 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " Could not execute %s::%s() " , ce - > name , ce - > constructor - > common . function_name ) ;
2003-09-07 02:34:55 +08:00
} else {
if ( retval_ptr ) {
zval_ptr_dtor ( & retval_ptr ) ;
}
}
if ( fci . params ) {
efree ( fci . params ) ;
}
} else if ( ctor_params ) {
2006-05-10 08:00:13 +08:00
zend_throw_exception_ex ( zend_exception_get_default ( TSRMLS_C ) , 0 TSRMLS_CC , " Class %s does not have a constructor hence you cannot use ctor_params " , ce - > name ) ;
2003-09-07 02:34:55 +08:00
}
}
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-07-17 01:19:11 +08:00
2002-07-15 18:04:01 +08:00
/* {{{ proto array pg_fetch_row(resource result [, int row [, int result_type]])
1999-07-17 01:26:16 +08:00
Get a row as an enumerated array */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_fetch_row )
1999-07-17 01:26:16 +08:00
{
2003-09-07 02:34:55 +08:00
php_pgsql_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PGSQL_NUM , 0 ) ;
1999-07-17 01:26:16 +08:00
}
/* }}} */
2002-09-30 17:07:57 +08:00
/* {{{ proto array pg_fetch_assoc(resource result [, int row])
Fetch a row as an assoc array */
PHP_FUNCTION ( pg_fetch_assoc )
{
/* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when
there is 3 rd parameter */
if ( ZEND_NUM_ARGS ( ) > 2 )
WRONG_PARAM_COUNT ;
2003-09-07 02:34:55 +08:00
php_pgsql_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PGSQL_ASSOC , 0 ) ;
2002-09-30 17:07:57 +08:00
}
/* }}} */
2002-03-03 03:53:11 +08:00
/* {{{ proto array pg_fetch_array(resource result [, int row [, int result_type]])
1999-04-22 10:48:28 +08:00
Fetch a row as an array */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_fetch_array )
1999-04-22 10:48:28 +08:00
{
2003-09-07 02:34:55 +08:00
php_pgsql_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PGSQL_BOTH , 0 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2004-03-16 04:16:59 +08:00
/* {{{ proto object pg_fetch_object(resource result [, int row [, string class_name [, NULL|array ctor_params]]])
1999-04-22 10:48:28 +08:00
Fetch a row as an object */
1999-12-20 06:44:55 +08:00
PHP_FUNCTION ( pg_fetch_object )
1999-04-22 10:48:28 +08:00
{
2002-09-30 17:07:57 +08:00
/* pg_fetch_object() allowed result_type used to be. 3rd parameter
must be allowed for compatibility */
2003-09-07 02:34:55 +08:00
php_pgsql_fetch_hash ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PGSQL_ASSOC , 1 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2002-07-21 15:25:10 +08:00
/* {{{ proto array pg_fetch_all(resource result)
Fetch all rows into array */
PHP_FUNCTION ( pg_fetch_all )
{
zval * result ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & result ) = = FAILURE ) {
2002-07-21 15:25:10 +08:00
return ;
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
pgsql_result = pg_result - > result ;
array_init ( return_value ) ;
if ( php_pgsql_result2array ( pgsql_result , return_value TSRMLS_CC ) = = FAILURE ) {
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
}
/* }}} */
2005-07-08 08:40:32 +08:00
/* {{{ proto array pg_fetch_all_columns(resource result [, int column_number])
Fetch all rows into array */
PHP_FUNCTION ( pg_fetch_all_columns )
{
zval * result ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
long colno = 0 ;
int pg_numrows , pg_row ;
size_t num_fields ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|l " , & result , & colno ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
pgsql_result = pg_result - > result ;
num_fields = PQnfields ( pgsql_result ) ;
if ( colno > = num_fields | | colno < 0 ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid column number '%ld' " , colno ) ;
RETURN_FALSE ;
}
array_init ( return_value ) ;
if ( ( pg_numrows = PQntuples ( pgsql_result ) ) < = 0 ) {
return ;
}
for ( pg_row = 0 ; pg_row < pg_numrows ; pg_row + + ) {
if ( PQgetisnull ( pgsql_result , pg_row , colno ) ) {
add_next_index_null ( return_value ) ;
} else {
add_next_index_string ( return_value , PQgetvalue ( pgsql_result , pg_row , colno ) , 1 ) ;
}
}
}
/* }}} */
2003-07-20 03:23:34 +08:00
/* {{{ proto bool pg_result_seek(resource result, int offset)
2002-10-02 11:16:35 +08:00
Set internal row offset */
2002-10-03 10:32:09 +08:00
PHP_FUNCTION ( pg_result_seek )
2002-10-02 11:16:35 +08:00
{
zval * result ;
2003-03-07 07:07:28 +08:00
long row ;
2002-10-02 11:16:35 +08:00
pgsql_result_handle * pg_result ;
2003-02-05 02:34:00 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " , & result , & row ) = = FAILURE ) {
2002-10-02 11:16:35 +08:00
return ;
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2003-02-05 02:34:00 +08:00
if ( row < 0 | | row > = PQntuples ( pg_result - > result ) ) {
2002-10-02 11:16:35 +08:00
RETURN_FALSE ;
2003-02-05 02:34:00 +08:00
}
2002-10-02 11:16:35 +08:00
/* seek to offset */
2003-02-09 15:24:18 +08:00
pg_result - > row = row ;
2002-10-02 11:16:35 +08:00
RETURN_TRUE ;
}
/* }}} */
1999-12-18 19:38:04 +08:00
# define PHP_PG_DATA_LENGTH 1
# define PHP_PG_DATA_ISNULL 2
1999-04-22 10:48:28 +08:00
2001-06-05 21:12:10 +08:00
/* {{{ php_pgsql_data_info
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_data_info ( INTERNAL_FUNCTION_PARAMETERS , int entry_type )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result , * * field ;
long row ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
int field_offset , pgsql_row , argc = ZEND_NUM_ARGS ( ) ;
if ( argc = = 2 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rZ " , & result , & field ) = = FAILURE ) {
return ;
}
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rlZ " , & result , & row , & field ) = = FAILURE ) {
return ;
}
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
2000-05-25 15:51:40 +08:00
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2008-06-30 06:38:55 +08:00
if ( argc = = 2 ) {
if ( pg_result - > row < 0 ) {
2001-06-20 02:10:08 +08:00
pg_result - > row = 0 ;
2008-06-30 06:38:55 +08:00
}
2001-06-20 02:10:08 +08:00
pgsql_row = pg_result - > row ;
if ( pgsql_row < 0 | | pgsql_row > = PQntuples ( pgsql_result ) ) {
RETURN_FALSE ;
}
} else {
2008-06-30 06:38:55 +08:00
pgsql_row = row ;
2001-06-20 02:10:08 +08:00
if ( pgsql_row < 0 | | pgsql_row > = PQntuples ( pgsql_result ) ) {
2003-08-29 05:00:24 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to jump to row %ld on PostgreSQL result index %ld " ,
2008-06-30 06:38:55 +08:00
row , Z_LVAL_P ( result ) ) ;
2001-06-20 02:10:08 +08:00
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
}
2001-06-20 02:10:08 +08:00
2000-05-25 15:51:40 +08:00
switch ( Z_TYPE_PP ( field ) ) {
1999-04-22 10:48:28 +08:00
case IS_STRING :
2000-05-25 15:51:40 +08:00
convert_to_string_ex ( field ) ;
field_offset = PQfnumber ( pgsql_result , Z_STRVAL_PP ( field ) ) ;
1999-04-22 10:48:28 +08:00
break ;
default :
2000-05-25 15:51:40 +08:00
convert_to_long_ex ( field ) ;
field_offset = Z_LVAL_PP ( field ) ;
1999-04-22 10:48:28 +08:00
break ;
}
2000-05-25 15:51:40 +08:00
if ( field_offset < 0 | | field_offset > = PQnfields ( pgsql_result ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Bad column offset specified " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
switch ( entry_type ) {
1999-12-18 19:38:04 +08:00
case PHP_PG_DATA_LENGTH :
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = PQgetlength ( pgsql_result , pgsql_row , field_offset ) ;
1999-04-22 10:48:28 +08:00
break ;
1999-12-18 19:38:04 +08:00
case PHP_PG_DATA_ISNULL :
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = PQgetisnull ( pgsql_result , pgsql_row , field_offset ) ;
1999-04-22 10:48:28 +08:00
break ;
}
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 10:48:28 +08:00
}
2001-06-05 21:12:10 +08:00
/* }}} */
1999-04-22 10:48:28 +08:00
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_field_prtlen(resource result, [int row,] mixed field_name_or_number)
1999-04-22 10:48:28 +08:00
Returns the printed length */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_prtlen )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_data_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_DATA_LENGTH ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_field_is_null(resource result, [int row,] mixed field_name_or_number)
1999-04-22 10:48:28 +08:00
Test if a field is NULL */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_field_is_null )
1999-04-22 10:48:28 +08:00
{
1999-12-18 19:38:04 +08:00
php_pgsql_data_info ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_DATA_ISNULL ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_free_result(resource result)
1999-04-22 10:48:28 +08:00
Free result memory */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_free_result )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result ;
1999-04-22 10:48:28 +08:00
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & result ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2000-05-25 15:51:40 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
if ( Z_LVAL_P ( result ) = = 0 ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2008-10-09 07:04:38 +08:00
zend_list_delete ( Z_RESVAL_P ( result ) ) ;
1999-04-22 10:48:28 +08:00
RETURN_TRUE ;
}
/* }}} */
2002-07-11 23:45:35 +08:00
/* {{{ proto string pg_last_oid(resource result)
1999-04-22 10:48:28 +08:00
Returns the last object identifier */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_last_oid )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * result ;
1999-04-22 10:48:28 +08:00
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2002-11-05 22:28:32 +08:00
# ifdef HAVE_PQOIDVALUE
2002-04-20 11:37:01 +08:00
Oid oid ;
2002-11-05 22:28:32 +08:00
# endif
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & result ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
1999-04-22 10:48:28 +08:00
pgsql_result = pg_result - > result ;
2002-03-29 19:24:54 +08:00
# ifdef HAVE_PQOIDVALUE
2002-04-20 11:03:42 +08:00
oid = PQoidValue ( pgsql_result ) ;
if ( oid = = InvalidOid ) {
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
2002-04-21 18:22:31 +08:00
PGSQL_RETURN_OID ( oid ) ;
2001-12-17 08:24:59 +08:00
# else
2001-09-26 05:58:48 +08:00
Z_STRVAL_P ( return_value ) = ( char * ) PQoidStatus ( pgsql_result ) ;
if ( Z_STRVAL_P ( return_value ) ) {
2002-04-21 18:22:31 +08:00
RETURN_STRING ( Z_STRVAL_P ( return_value ) , 1 ) ;
2000-05-23 14:03:34 +08:00
}
2004-07-19 15:19:50 +08:00
RETURN_STRING ( " " , 1 ) ;
2000-05-23 14:03:34 +08:00
# endif
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-06-01 04:40:28 +08:00
/* {{{ proto bool pg_trace(string filename [, string mode [, resource connection]])
2000-06-24 01:09:54 +08:00
Enable tracing a PostgreSQL connection */
2000-06-01 04:40:28 +08:00
PHP_FUNCTION ( pg_trace )
{
2008-06-30 06:38:55 +08:00
char * z_filename , * mode = " w " ;
int z_filename_len , mode_len ;
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2000-06-01 04:40:28 +08:00
PGconn * pgsql ;
2002-04-07 13:21:43 +08:00
FILE * fp = NULL ;
2002-03-16 09:28:57 +08:00
php_stream * stream ;
2000-06-01 04:40:28 +08:00
id = PGG ( default_link ) ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " s|sr " , & z_filename , & z_filename_len , & mode , & mode_len , & pgsql_link ) = = FAILURE ) {
return ;
2000-06-01 04:40:28 +08:00
}
2008-06-30 06:38:55 +08:00
if ( argc < 3 ) {
CHECK_DEFAULT_LINK ( id ) ;
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2002-08-24 04:57:30 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-06-01 04:40:28 +08:00
2008-06-30 06:38:55 +08:00
stream = php_stream_open_wrapper ( z_filename , mode , ENFORCE_SAFE_MODE | REPORT_ERRORS , NULL ) ;
2000-06-01 04:40:28 +08:00
2002-03-16 05:03:08 +08:00
if ( ! stream ) {
2000-06-01 04:40:28 +08:00
RETURN_FALSE ;
}
2002-03-16 05:03:08 +08:00
2006-03-14 06:56:20 +08:00
if ( FAILURE = = php_stream_cast ( stream , PHP_STREAM_AS_STDIO , ( void * * ) & fp , REPORT_ERRORS ) ) {
2002-03-16 05:03:08 +08:00
php_stream_close ( stream ) ;
RETURN_FALSE ;
}
2002-03-20 22:21:30 +08:00
php_stream_auto_cleanup ( stream ) ;
2000-06-01 04:40:28 +08:00
PQtrace ( pgsql , fp ) ;
RETURN_TRUE ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2000-06-01 04:40:28 +08:00
2001-12-10 14:14:03 +08:00
/* {{{ proto bool pg_untrace([resource connection])
2000-06-01 04:40:28 +08:00
Disable tracing of a PostgreSQL connection */
PHP_FUNCTION ( pg_untrace )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2000-06-01 04:40:28 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |r " , & pgsql_link ) = = FAILURE ) {
return ;
}
2000-06-01 04:40:28 +08:00
2008-06-30 06:38:55 +08:00
if ( argc = = 0 ) {
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
2000-06-01 04:40:28 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2000-06-01 04:40:28 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-06-01 04:40:28 +08:00
PQuntrace ( pgsql ) ;
RETURN_TRUE ;
}
2001-06-05 21:12:10 +08:00
/* }}} */
2000-06-01 04:40:28 +08:00
2008-07-23 08:17:19 +08:00
/* {{{ proto mixed pg_lo_create([resource connection],[mixed large_object_oid])
1999-04-22 10:48:28 +08:00
Create a large object */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_create )
1999-04-22 10:48:28 +08:00
{
2008-07-23 08:17:19 +08:00
zval * pgsql_link = NULL , * oid = NULL ;
PGconn * pgsql ;
Oid pgsql_oid , wanted_oid = InvalidOid ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
1999-11-20 08:30:08 +08:00
2008-07-23 08:17:19 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |zz " , & pgsql_link , & oid ) = = FAILURE ) {
2008-06-30 06:38:55 +08:00
return ;
}
2008-07-23 08:17:19 +08:00
if ( ( argc = = 1 ) & & ( Z_TYPE_P ( pgsql_link ) ! = IS_RESOURCE ) ) {
oid = pgsql_link ;
pgsql_link = NULL ;
}
2008-06-30 06:38:55 +08:00
2008-07-23 08:17:19 +08:00
if ( pgsql_link = = NULL ) {
2008-06-30 06:38:55 +08:00
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
2008-07-23 08:17:19 +08:00
if ( id = = - 1 ) {
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
1999-04-22 10:48:28 +08:00
2008-07-23 08:17:19 +08:00
if ( oid ) {
# ifndef HAVE_PG_LO_CREATE
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " OID value passing not supported " ) ;
# else
switch ( Z_TYPE_P ( oid ) ) {
case IS_STRING :
{
char * end_ptr ;
wanted_oid = ( Oid ) strtoul ( Z_STRVAL_P ( oid ) , & end_ptr , 10 ) ;
if ( ( Z_STRVAL_P ( oid ) + Z_STRLEN_P ( oid ) ) ! = end_ptr ) {
/* wrong integer format */
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
}
break ;
case IS_LONG :
if ( Z_LVAL_P ( oid ) < ( long ) InvalidOid ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
wanted_oid = ( Oid ) Z_LVAL_P ( oid ) ;
break ;
default :
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
if ( ( pgsql_oid = lo_create ( pgsql , wanted_oid ) ) = = InvalidOid ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to create PostgreSQL large object " ) ;
RETURN_FALSE ;
}
PGSQL_RETURN_OID ( pgsql_oid ) ;
# endif
}
1999-04-22 10:48:28 +08:00
2002-04-20 11:37:01 +08:00
if ( ( pgsql_oid = lo_creat ( pgsql , INV_READ | INV_WRITE ) ) = = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to create PostgreSQL large object " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2008-07-23 08:17:19 +08:00
2002-04-21 18:22:31 +08:00
PGSQL_RETURN_OID ( pgsql_oid ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2002-07-11 23:45:35 +08:00
/* {{{ proto bool pg_lo_unlink([resource connection,] string large_object_oid)
1999-04-22 10:48:28 +08:00
Delete a large object */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_unlink )
1999-04-22 10:48:28 +08:00
{
2002-04-20 22:06:47 +08:00
zval * pgsql_link = NULL ;
long oid_long ;
char * oid_string , * end_ptr ;
2003-03-11 04:30:33 +08:00
int oid_strlen ;
1999-04-22 10:48:28 +08:00
PGconn * pgsql ;
2002-04-20 22:06:47 +08:00
Oid oid ;
2000-05-25 15:51:40 +08:00
int id = - 1 ;
2002-04-20 22:06:47 +08:00
int argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
2002-04-20 22:06:47 +08:00
/* accept string type since Oid type is unsigned int */
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" rs " , & pgsql_link , & oid_string , & oid_strlen ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" rl " , & pgsql_link , & oid_long ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" s " , & oid_string , & oid_strlen ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" l " , & oid_long ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID is specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Requires 1 or 2 arguments " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
1999-04-22 10:48:28 +08:00
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2002-04-20 22:06:47 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( lo_unlink ( pgsql , oid ) = = - 1 ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to delete PostgreSQL large object %u " , oid ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto resource pg_lo_open([resource connection,] int large_object_oid, string mode)
1999-04-22 10:48:28 +08:00
Open a large object and return fd */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_open )
1999-04-22 10:48:28 +08:00
{
2002-04-20 22:06:47 +08:00
zval * pgsql_link = NULL ;
long oid_long ;
char * oid_string , * end_ptr , * mode_string ;
2003-03-11 04:30:33 +08:00
int oid_strlen , mode_strlen ;
1999-04-22 10:48:28 +08:00
PGconn * pgsql ;
2002-04-20 22:06:47 +08:00
Oid oid ;
2000-05-25 15:51:40 +08:00
int id = - 1 , pgsql_mode = 0 , pgsql_lofd ;
1999-04-22 10:48:28 +08:00
int create = 0 ;
pgLofp * pgsql_lofp ;
2002-04-20 22:06:47 +08:00
int argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
2002-04-20 22:06:47 +08:00
/* accept string type since Oid is unsigned int */
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" rss " , & pgsql_link , & oid_string , & oid_strlen , & mode_string , & mode_strlen ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
1999-04-22 10:48:28 +08:00
}
2002-04-20 22:06:47 +08:00
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" rls " , & pgsql_link , & oid_long , & mode_string , & mode_strlen ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" ss " , & oid_string , & oid_strlen , & mode_string , & mode_strlen ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" ls " , & oid_long , & mode_string , & mode_strlen ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Requires 1 or 2 arguments " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2003-04-18 00:54:43 +08:00
2002-04-20 22:06:47 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
1999-04-22 10:48:28 +08:00
/* r/w/+ is little bit more PHP-like than INV_READ/INV_WRITE and a lot of
faster to type . Unfortunately , doesn ' t behave the same way as fopen ( ) . . .
( Jouni )
2002-03-11 15:23:07 +08:00
*/
1999-04-22 10:48:28 +08:00
2000-05-25 15:51:40 +08:00
if ( strchr ( mode_string , ' r ' ) = = mode_string ) {
1999-04-22 10:48:28 +08:00
pgsql_mode | = INV_READ ;
2000-05-25 15:51:40 +08:00
if ( strchr ( mode_string , ' + ' ) = = mode_string + 1 ) {
1999-04-22 10:48:28 +08:00
pgsql_mode | = INV_WRITE ;
}
}
2000-05-25 15:51:40 +08:00
if ( strchr ( mode_string , ' w ' ) = = mode_string ) {
1999-04-22 10:48:28 +08:00
pgsql_mode | = INV_WRITE ;
create = 1 ;
2000-05-25 15:51:40 +08:00
if ( strchr ( mode_string , ' + ' ) = = mode_string + 1 ) {
1999-04-22 10:48:28 +08:00
pgsql_mode | = INV_READ ;
}
}
pgsql_lofp = ( pgLofp * ) emalloc ( sizeof ( pgLofp ) ) ;
2002-04-20 22:06:47 +08:00
if ( ( pgsql_lofd = lo_open ( pgsql , oid , pgsql_mode ) ) = = - 1 ) {
1999-04-22 10:48:28 +08:00
if ( create ) {
2002-04-20 22:06:47 +08:00
if ( ( oid = lo_creat ( pgsql , INV_READ | INV_WRITE ) ) = = 0 ) {
1999-04-22 10:48:28 +08:00
efree ( pgsql_lofp ) ;
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to create PostgreSQL large object " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
} else {
2002-04-20 22:06:47 +08:00
if ( ( pgsql_lofd = lo_open ( pgsql , oid , pgsql_mode ) ) = = - 1 ) {
if ( lo_unlink ( pgsql , oid ) = = - 1 ) {
1999-04-22 10:48:28 +08:00
efree ( pgsql_lofp ) ;
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Something is really messed up! Your database is badly corrupted in a way NOT related to PHP " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
efree ( pgsql_lofp ) ;
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to open PostgreSQL large object " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
} else {
pgsql_lofp - > conn = pgsql ;
pgsql_lofp - > lofd = pgsql_lofd ;
2001-09-26 05:58:48 +08:00
Z_LVAL_P ( return_value ) = zend_list_insert ( pgsql_lofp , le_lofp ) ;
Z_TYPE_P ( return_value ) = IS_LONG ;
1999-04-22 10:48:28 +08:00
}
}
} else {
efree ( pgsql_lofp ) ;
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to open PostgreSQL large object " ) ;
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
} else {
pgsql_lofp - > conn = pgsql ;
pgsql_lofp - > lofd = pgsql_lofd ;
2000-05-25 15:51:40 +08:00
ZEND_REGISTER_RESOURCE ( return_value , pgsql_lofp , le_lofp ) ;
1999-04-22 10:48:28 +08:00
}
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_lo_close(resource large_object)
1999-04-22 10:48:28 +08:00
Close a large object */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_close )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_lofp ;
1999-04-22 10:48:28 +08:00
pgLofp * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & pgsql_lofp ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_lofp , - 1 , " PostgreSQL large object " , le_lofp ) ;
1999-04-22 10:48:28 +08:00
2000-05-25 15:51:40 +08:00
if ( lo_close ( ( PGconn * ) pgsql - > conn , pgsql - > lofd ) < 0 ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unable to close PostgreSQL large object descriptor %d " , pgsql - > lofd ) ;
1999-04-22 10:48:28 +08:00
RETVAL_FALSE ;
} else {
RETVAL_TRUE ;
}
2000-05-25 15:51:40 +08:00
2008-06-30 06:38:55 +08:00
zend_list_delete ( Z_RESVAL_P ( pgsql_lofp ) ) ;
1999-04-22 10:48:28 +08:00
return ;
}
/* }}} */
2002-05-20 09:02:29 +08:00
# define PGSQL_LO_READ_BUF_SIZE 8192
2001-12-17 08:24:59 +08:00
/* {{{ proto string pg_lo_read(resource large_object [, int len])
1999-04-22 10:48:28 +08:00
Read a large object */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_read )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_id ;
long len ;
int buf_len = PGSQL_LO_READ_BUF_SIZE , nbytes , argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
char * buf ;
pgLofp * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " r|l " , & pgsql_id , & len ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_id , - 1 , " PostgreSQL large object " , le_lofp ) ;
2000-05-25 15:51:40 +08:00
2008-06-30 06:38:55 +08:00
if ( argc > 1 ) {
buf_len = len ;
2001-05-27 09:10:36 +08:00
}
2003-04-26 05:59:58 +08:00
buf = ( char * ) safe_emalloc ( sizeof ( char ) , ( buf_len + 1 ) , 0 ) ;
1999-04-22 10:48:28 +08:00
if ( ( nbytes = lo_read ( ( PGconn * ) pgsql - > conn , pgsql - > lofd , buf , buf_len ) ) < 0 ) {
efree ( buf ) ;
RETURN_FALSE ;
}
2001-05-27 09:10:36 +08:00
2002-04-20 11:37:01 +08:00
buf [ nbytes ] = ' \0 ' ;
2001-05-27 09:10:36 +08:00
RETURN_STRINGL ( buf , nbytes , 0 ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_lo_write(resource large_object, string buf [, int len])
1999-04-22 10:48:28 +08:00
Write a large object */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_write )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_id ;
char * str ;
long z_len ;
int str_len , nbytes ;
2001-05-27 09:10:36 +08:00
int len ;
1999-04-22 10:48:28 +08:00
pgLofp * pgsql ;
2001-05-27 09:10:36 +08:00
int argc = ZEND_NUM_ARGS ( ) ;
1999-04-22 10:48:28 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rs|l " , & pgsql_id , & str , & str_len , & z_len ) = = FAILURE ) {
return ;
2001-05-27 09:10:36 +08:00
}
if ( argc > 2 ) {
2008-06-30 06:38:55 +08:00
if ( z_len > str_len ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot write more than buffer size %d. Tried to write %ld " , str_len , z_len ) ;
2002-05-20 09:40:22 +08:00
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
if ( z_len < 0 ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Buffer size must be larger than 0, but %ld was specified " , z_len ) ;
2002-05-20 09:40:22 +08:00
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
len = z_len ;
2001-05-27 09:10:36 +08:00
}
else {
2008-06-30 06:38:55 +08:00
len = str_len ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_id , - 1 , " PostgreSQL large object " , le_lofp ) ;
2000-05-25 15:51:40 +08:00
2008-06-30 06:38:55 +08:00
if ( ( nbytes = lo_write ( ( PGconn * ) pgsql - > conn , pgsql - > lofd , str , len ) ) = = - 1 ) {
1999-04-22 10:48:28 +08:00
RETURN_FALSE ;
}
2001-05-27 09:10:36 +08:00
RETURN_LONG ( nbytes ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_lo_read_all(resource large_object)
1999-04-22 10:48:28 +08:00
Read a large object and send straight to browser */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_read_all )
1999-04-22 10:48:28 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_id ;
2002-05-20 09:40:22 +08:00
int tbytes ;
1999-04-22 10:48:28 +08:00
volatile int nbytes ;
2002-05-20 09:02:29 +08:00
char buf [ PGSQL_LO_READ_BUF_SIZE ] ;
1999-04-22 10:48:28 +08:00
pgLofp * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & pgsql_id ) = = FAILURE ) {
return ;
1999-04-22 10:48:28 +08:00
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_id , - 1 , " PostgreSQL large object " , le_lofp ) ;
1999-04-22 10:48:28 +08:00
tbytes = 0 ;
2002-05-20 09:02:29 +08:00
while ( ( nbytes = lo_read ( ( PGconn * ) pgsql - > conn , pgsql - > lofd , buf , PGSQL_LO_READ_BUF_SIZE ) ) > 0 ) {
php_body_write ( buf , nbytes TSRMLS_CC ) ;
tbytes + = nbytes ;
1999-04-22 10:48:28 +08:00
}
2001-12-17 08:24:59 +08:00
RETURN_LONG ( tbytes ) ;
1999-04-22 10:48:28 +08:00
}
/* }}} */
2000-06-05 04:24:07 +08:00
2008-07-23 08:17:19 +08:00
/* {{{ proto int pg_lo_import([resource connection, ] string filename [, mixed oid])
2000-06-05 04:24:07 +08:00
Import large object direct from filesystem */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_import )
2000-06-05 04:24:07 +08:00
{
2008-07-23 08:17:19 +08:00
zval * pgsql_link = NULL , * oid = NULL ;
2002-04-21 17:46:29 +08:00
char * file_in ;
2001-12-17 08:24:59 +08:00
int id = - 1 , name_len ;
int argc = ZEND_NUM_ARGS ( ) ;
2000-06-05 04:24:07 +08:00
PGconn * pgsql ;
2008-09-10 09:39:35 +08:00
Oid returned_oid ;
2001-12-17 08:24:59 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2008-07-23 08:17:19 +08:00
" rs|z " , & pgsql_link , & file_in , & name_len , & oid ) = = SUCCESS ) {
2001-12-17 08:24:59 +08:00
;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2008-07-23 08:17:19 +08:00
" s|z " , & file_in , & name_len , & oid ) = = SUCCESS ) {
2001-12-17 08:24:59 +08:00
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
2008-08-03 20:15:55 +08:00
/* old calling convention, deprecated since PHP 4.2 */
2001-12-17 08:24:59 +08:00
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2002-05-20 09:02:29 +08:00
" sr " , & file_in , & name_len , & pgsql_link ) = = SUCCESS ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Old API is used " ) ;
2001-12-17 08:24:59 +08:00
}
else {
WRONG_PARAM_COUNT ;
2000-06-05 04:24:07 +08:00
}
2003-04-18 00:54:43 +08:00
2001-12-17 08:24:59 +08:00
if ( PG ( safe_mode ) & & ( ! php_checkuid ( file_in , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
2000-06-05 04:24:07 +08:00
RETURN_FALSE ;
}
2002-07-17 12:58:58 +08:00
if ( php_check_open_basedir ( file_in TSRMLS_CC ) ) {
RETURN_FALSE ;
}
2000-06-05 04:24:07 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-06-05 04:24:07 +08:00
2008-07-23 08:17:19 +08:00
if ( oid ) {
# ifndef HAVE_PG_LO_IMPORT_WITH_OID
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " OID value passing not supported " ) ;
# else
2008-09-10 09:39:35 +08:00
Oid wanted_oid ;
2008-07-23 08:17:19 +08:00
switch ( Z_TYPE_P ( oid ) ) {
case IS_STRING :
{
char * end_ptr ;
wanted_oid = ( Oid ) strtoul ( Z_STRVAL_P ( oid ) , & end_ptr , 10 ) ;
if ( ( Z_STRVAL_P ( oid ) + Z_STRLEN_P ( oid ) ) ! = end_ptr ) {
/* wrong integer format */
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
}
break ;
case IS_LONG :
if ( Z_LVAL_P ( oid ) < ( long ) InvalidOid ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
wanted_oid = ( Oid ) Z_LVAL_P ( oid ) ;
break ;
default :
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " invalid OID value passed " ) ;
RETURN_FALSE ;
}
returned_oid = lo_import_with_oid ( pgsql , file_in , wanted_oid ) ;
2000-06-05 04:24:07 +08:00
2008-07-23 08:17:19 +08:00
if ( returned_oid = = InvalidOid ) {
RETURN_FALSE ;
}
PGSQL_RETURN_OID ( returned_oid ) ;
# endif
}
returned_oid = lo_import ( pgsql , file_in ) ;
if ( returned_oid = = InvalidOid ) {
2000-06-05 04:24:07 +08:00
RETURN_FALSE ;
}
2008-07-23 08:17:19 +08:00
PGSQL_RETURN_OID ( returned_oid ) ;
2000-06-05 04:24:07 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_lo_export([resource connection, ] int objoid, string filename)
2000-06-19 00:31:52 +08:00
Export large object direct to filesystem */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_lo_export )
2000-06-05 04:24:07 +08:00
{
2001-12-17 08:24:59 +08:00
zval * pgsql_link = NULL ;
2002-04-20 22:06:47 +08:00
char * file_out , * oid_string , * end_ptr ;
2003-03-11 04:30:33 +08:00
int oid_strlen ;
2002-04-20 22:06:47 +08:00
int id = - 1 , name_len ;
long oid_long ;
2000-06-05 04:24:07 +08:00
Oid oid ;
PGconn * pgsql ;
2002-04-20 22:06:47 +08:00
int argc = ZEND_NUM_ARGS ( ) ;
2002-04-20 12:17:17 +08:00
2002-04-20 22:06:47 +08:00
/* allow string to handle large OID value correctly */
2001-12-17 08:24:59 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2002-04-20 22:06:47 +08:00
" rls " , & pgsql_link , & oid_long , & file_out , & name_len ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
2001-12-17 08:24:59 +08:00
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2002-04-20 22:06:47 +08:00
" rss " , & pgsql_link , & oid_string , & oid_strlen , & file_out , & name_len ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" ls " , & oid_long , & file_out , & name_len ) = = SUCCESS ) {
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2003-04-18 00:54:43 +08:00
" ss " , & oid_string , & oid_strlen , & file_out , & name_len ) = = SUCCESS ) {
2002-04-20 22:06:47 +08:00
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
2002-04-20 22:06:47 +08:00
" ssr " , & oid_string , & oid_strlen , & file_out , & name_len , & pgsql_link ) = = SUCCESS ) {
oid = ( Oid ) strtoul ( oid_string , & end_ptr , 10 ) ;
if ( ( oid_string + oid_strlen ) ! = end_ptr ) {
/* wrong integer format */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Wrong OID value passed " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
}
else if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC ,
" lsr " , & oid_long , & file_out , & name_len , & pgsql_link ) = = SUCCESS ) {
2003-08-29 07:04:27 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Old API is used " ) ;
2002-04-20 22:06:47 +08:00
if ( oid_long < = InvalidOid ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid OID specified " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
}
oid = ( Oid ) oid_long ;
2001-12-17 08:24:59 +08:00
}
else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Requires 2 or 3 arguments " ) ;
2002-04-20 22:06:47 +08:00
RETURN_FALSE ;
2000-06-05 04:24:07 +08:00
}
2003-04-18 00:54:43 +08:00
2002-07-17 15:50:32 +08:00
if ( PG ( safe_mode ) & & ( ! php_checkuid ( file_out , NULL , CHECKUID_CHECK_FILE_AND_DIR ) ) ) {
2002-07-17 13:01:58 +08:00
RETURN_FALSE ;
}
2002-07-17 15:50:32 +08:00
if ( php_check_open_basedir ( file_out TSRMLS_CC ) ) {
2002-07-17 13:01:58 +08:00
RETURN_FALSE ;
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-06-05 04:24:07 +08:00
2001-12-17 08:24:59 +08:00
if ( lo_export ( pgsql , oid , file_out ) ) {
2000-06-05 04:24:07 +08:00
RETURN_TRUE ;
2002-04-20 22:06:47 +08:00
}
RETURN_FALSE ;
2000-06-05 04:24:07 +08:00
}
/* }}} */
2001-12-17 20:14:46 +08:00
/* {{{ proto bool pg_lo_seek(resource large_object, int offset [, int whence])
2001-12-17 08:24:59 +08:00
Seeks position of large object */
PHP_FUNCTION ( pg_lo_seek )
{
zval * pgsql_id = NULL ;
2003-03-07 07:07:28 +08:00
long offset = 0 , whence = SEEK_CUR ;
2001-12-17 08:24:59 +08:00
pgLofp * pgsql ;
int argc = ZEND_NUM_ARGS ( ) ;
2000-07-02 16:59:44 +08:00
2001-12-17 08:24:59 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rl|l " , & pgsql_id , & offset , & whence ) = = FAILURE ) {
return ;
}
if ( whence ! = SEEK_SET & & whence ! = SEEK_CUR & & whence ! = SEEK_END ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid whence parameter " ) ;
2001-12-17 08:24:59 +08:00
return ;
}
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_id , - 1 , " PostgreSQL large object " , le_lofp ) ;
2003-04-18 00:54:43 +08:00
if ( lo_lseek ( ( PGconn * ) pgsql - > conn , pgsql - > lofd , offset , whence ) > - 1 ) {
2001-12-17 08:24:59 +08:00
RETURN_TRUE ;
} else {
RETURN_FALSE ;
}
}
/* }}} */
/* {{{ proto int pg_lo_tell(resource large_object)
Returns current position of large object */
PHP_FUNCTION ( pg_lo_tell )
{
zval * pgsql_id = NULL ;
int offset = 0 ;
pgLofp * pgsql ;
int argc = ZEND_NUM_ARGS ( ) ;
if ( zend_parse_parameters ( argc TSRMLS_CC , " r " , & pgsql_id ) = = FAILURE ) {
return ;
}
ZEND_FETCH_RESOURCE ( pgsql , pgLofp * , & pgsql_id , - 1 , " PostgreSQL large object " , le_lofp ) ;
offset = lo_tell ( ( PGconn * ) pgsql - > conn , pgsql - > lofd ) ;
RETURN_LONG ( offset ) ;
}
/* }}} */
2005-03-22 16:51:23 +08:00
# if HAVE_PQSETERRORVERBOSITY
/* {{{ proto int pg_set_error_verbosity([resource connection,] int verbosity)
Set error verbosity */
PHP_FUNCTION ( pg_set_error_verbosity )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
long verbosity ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2005-03-22 16:51:23 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
if ( argc = = 1 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " l " , & verbosity ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rl " , & pgsql_link , & verbosity ) = = FAILURE ) {
return ;
}
2005-03-22 16:51:23 +08:00
}
2008-06-30 06:38:55 +08:00
2005-03-22 16:51:23 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-22 16:51:23 +08:00
2008-06-30 06:38:55 +08:00
if ( verbosity & ( PQERRORS_TERSE | PQERRORS_DEFAULT | PQERRORS_VERBOSE ) ) {
Z_LVAL_P ( return_value ) = PQsetErrorVerbosity ( pgsql , verbosity ) ;
2005-03-22 16:51:23 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
} else {
RETURN_FALSE ;
}
}
/* }}} */
# endif
2002-04-25 15:09:45 +08:00
# ifdef HAVE_PQCLIENTENCODING
2001-12-10 14:14:03 +08:00
/* {{{ proto int pg_set_client_encoding([resource connection,] string encoding)
2000-07-02 16:59:44 +08:00
Set client encoding */
2000-09-13 12:13:36 +08:00
PHP_FUNCTION ( pg_set_client_encoding )
2000-07-02 16:59:44 +08:00
{
2008-06-30 06:38:55 +08:00
char * encoding ;
int encoding_len ;
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2000-07-02 16:59:44 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
if ( argc = = 1 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " s " , & encoding , & encoding_len ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rs " , & pgsql_link , & encoding , & encoding_len ) = = FAILURE ) {
return ;
}
2000-07-02 16:59:44 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-07-02 16:59:44 +08:00
2008-06-30 06:38:55 +08:00
Z_LVAL_P ( return_value ) = PQsetClientEncoding ( pgsql , encoding ) ;
2001-09-26 05:58:48 +08:00
Z_TYPE_P ( return_value ) = IS_LONG ;
2000-07-02 16:59:44 +08:00
}
/* }}} */
2001-12-10 14:14:03 +08:00
/* {{{ proto string pg_client_encoding([resource connection])
2000-07-02 16:59:44 +08:00
Get the current client encoding */
2000-09-13 12:13:36 +08:00
PHP_FUNCTION ( pg_client_encoding )
2000-07-02 16:59:44 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2000-07-02 16:59:44 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |r " , & pgsql_link ) = = FAILURE ) {
return ;
2000-07-02 16:59:44 +08:00
}
2008-06-30 06:38:55 +08:00
if ( argc = = 0 ) {
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
}
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2000-07-02 16:59:44 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2000-07-02 16:59:44 +08:00
2000-07-29 12:24:11 +08:00
/* Just do the same as found in PostgreSQL sources... */
# ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT
# define pg_encoding_to_char(x) "SQL_ASCII"
# endif
2008-06-30 06:38:55 +08:00
Z_STRVAL_P ( return_value ) = ( char * ) pg_encoding_to_char ( PQclientEncoding ( pgsql ) ) ;
2001-09-26 05:58:48 +08:00
Z_STRLEN_P ( return_value ) = strlen ( Z_STRVAL_P ( return_value ) ) ;
Z_STRVAL_P ( return_value ) = ( char * ) estrdup ( Z_STRVAL_P ( return_value ) ) ;
Z_TYPE_P ( return_value ) = IS_STRING ;
2000-07-02 16:59:44 +08:00
}
/* }}} */
2002-04-25 15:09:45 +08:00
# endif
2001-12-10 12:02:08 +08:00
2005-03-22 16:51:23 +08:00
# if !HAVE_PQGETCOPYDATA
2001-12-17 08:24:59 +08:00
# define COPYBUFSIZ 8192
2005-03-22 16:51:23 +08:00
# endif
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_end_copy([resource connection])
Sync with backend . Completes the Copy command */
PHP_FUNCTION ( pg_end_copy )
2001-12-10 12:02:08 +08:00
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link = NULL ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2001-12-10 12:02:08 +08:00
PGconn * pgsql ;
2001-12-17 08:24:59 +08:00
int result = 0 ;
2001-12-10 12:02:08 +08:00
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |r " , & pgsql_link ) = = FAILURE ) {
return ;
}
if ( argc = = 0 ) {
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
2001-12-10 12:02:08 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2001-12-10 12:02:08 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-10 12:02:08 +08:00
2001-12-17 08:24:59 +08:00
result = PQendcopy ( pgsql ) ;
if ( result ! = 0 ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
2002-03-11 15:23:07 +08:00
}
RETURN_TRUE ;
2001-12-17 08:24:59 +08:00
}
2001-12-10 12:02:08 +08:00
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_put_line([resource connection,] string query)
Send null - terminated string to backend server */
PHP_FUNCTION ( pg_put_line )
2001-12-10 12:02:08 +08:00
{
2008-06-30 06:38:55 +08:00
char * query ;
zval * pgsql_link = NULL ;
int query_len , id = - 1 ;
2001-12-10 12:02:08 +08:00
PGconn * pgsql ;
2008-06-30 06:38:55 +08:00
int result = 0 , argc = ZEND_NUM_ARGS ( ) ;
2001-12-10 12:02:08 +08:00
2008-06-30 06:38:55 +08:00
if ( argc = = 1 ) {
if ( zend_parse_parameters ( argc TSRMLS_CC , " s " , & query , & query_len ) = = FAILURE ) {
return ;
}
id = PGG ( default_link ) ;
CHECK_DEFAULT_LINK ( id ) ;
} else {
if ( zend_parse_parameters ( argc TSRMLS_CC , " rs " , & pgsql_link , & query , & query_len ) = = FAILURE ) {
return ;
}
2001-12-10 12:02:08 +08:00
}
2008-06-30 06:38:55 +08:00
2003-05-31 03:12:26 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-17 08:24:59 +08:00
2008-06-30 06:38:55 +08:00
result = PQputline ( pgsql , query ) ;
2001-12-17 08:24:59 +08:00
if ( result = = EOF ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Query failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
2002-09-30 11:51:54 +08:00
/* {{{ proto array pg_copy_to(resource connection, string table_name [, string delimiter [, string null_as]])
2002-01-21 08:36:22 +08:00
Copy table to array */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_copy_to )
{
zval * pgsql_link ;
char * table_name , * pg_delim = NULL , * pg_null_as = NULL ;
int table_name_len , pg_delim_len , pg_null_as_len ;
char * query ;
int id = - 1 ;
PGconn * pgsql ;
PGresult * pgsql_result ;
ExecStatusType status ;
int copydone = 0 ;
2005-03-22 16:51:23 +08:00
# if !HAVE_PQGETCOPYDATA
2001-12-17 08:24:59 +08:00
char copybuf [ COPYBUFSIZ ] ;
2005-03-22 16:51:23 +08:00
# endif
2001-12-17 08:24:59 +08:00
char * csv = ( char * ) NULL ;
int ret ;
int argc = ZEND_NUM_ARGS ( ) ;
if ( zend_parse_parameters ( argc TSRMLS_CC , " rs|ss " ,
& pgsql_link , & table_name , & table_name_len ,
& pg_delim , & pg_delim_len , & pg_null_as , & pg_null_as_len ) = = FAILURE ) {
return ;
}
if ( ! pg_delim ) {
pg_delim = " \t " ;
}
2006-09-06 20:40:56 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-17 08:24:59 +08:00
if ( ! pg_null_as ) {
pg_null_as = safe_estrdup ( " \\ \\ N " ) ;
}
2007-02-23 08:37:36 +08:00
spprintf ( & query , 0 , " COPY \" %s \" TO STDOUT DELIMITERS '%c' WITH NULL AS '%s' " , table_name , * pg_delim , pg_null_as ) ;
2001-12-17 08:24:59 +08:00
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
}
pgsql_result = PQexec ( pgsql , query ) ;
efree ( pg_null_as ) ;
efree ( query ) ;
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
switch ( status ) {
case PGRES_COPY_OUT :
if ( pgsql_result ) {
PQclear ( pgsql_result ) ;
2003-01-19 03:28:10 +08:00
array_init ( return_value ) ;
2005-03-22 16:51:23 +08:00
# if HAVE_PQGETCOPYDATA
while ( ! copydone )
{
ret = PQgetCopyData ( pgsql , & csv , 0 ) ;
switch ( ret ) {
case - 1 :
copydone = 1 ;
break ;
case 0 :
case - 2 :
PHP_PQ_ERROR ( " getline failed: %s " , pgsql ) ;
RETURN_FALSE ;
break ;
default :
add_next_index_string ( return_value , csv , 1 ) ;
2006-11-29 23:45:59 +08:00
PQfreemem ( csv ) ;
2005-03-22 16:51:23 +08:00
break ;
}
}
# else
2001-12-17 08:24:59 +08:00
while ( ! copydone )
{
if ( ( ret = PQgetline ( pgsql , copybuf , COPYBUFSIZ ) ) ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " getline failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
if ( copybuf [ 0 ] = = ' \\ ' & &
copybuf [ 1 ] = = ' . ' & &
copybuf [ 2 ] = = ' \0 ' )
{
copydone = 1 ;
}
else
{
if ( csv = = ( char * ) NULL ) {
csv = estrdup ( copybuf ) ;
} else {
csv = ( char * ) erealloc ( csv , strlen ( csv ) + sizeof ( char ) * ( COPYBUFSIZ + 1 ) ) ;
strcat ( csv , copybuf ) ;
}
switch ( ret )
{
case EOF :
copydone = 1 ;
case 0 :
add_next_index_string ( return_value , csv , 1 ) ;
efree ( csv ) ;
csv = ( char * ) NULL ;
break ;
case 1 :
break ;
}
}
}
if ( PQendcopy ( pgsql ) ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " endcopy failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
2005-03-22 16:51:23 +08:00
# endif
2001-12-17 08:24:59 +08:00
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
}
} else {
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
}
break ;
default :
PQclear ( pgsql_result ) ;
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Copy command failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
break ;
}
}
/* }}} */
2002-09-30 11:51:54 +08:00
/* {{{ proto bool pg_copy_from(resource connection, string table_name , array rows [, string delimiter [, string null_as]])
2002-01-21 08:36:22 +08:00
Copy table from array */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_copy_from )
{
zval * pgsql_link = NULL , * pg_rows ;
zval * * tmp ;
char * table_name , * pg_delim = NULL , * pg_null_as = NULL ;
int table_name_len , pg_delim_len , pg_null_as_len ;
2005-07-05 20:45:39 +08:00
int pg_null_as_free = 0 ;
2001-12-17 08:24:59 +08:00
char * query ;
HashPosition pos ;
int id = - 1 ;
PGconn * pgsql ;
PGresult * pgsql_result ;
ExecStatusType status ;
int argc = ZEND_NUM_ARGS ( ) ;
2008-09-08 09:33:08 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa|ss " ,
2001-12-17 08:24:59 +08:00
& pgsql_link , & table_name , & table_name_len , & pg_rows ,
& pg_delim , & pg_delim_len , & pg_null_as , & pg_null_as_len ) = = FAILURE ) {
return ;
}
if ( ! pg_delim ) {
pg_delim = " \t " ;
}
if ( ! pg_null_as ) {
pg_null_as = safe_estrdup ( " \\ \\ N " ) ;
2005-07-05 20:45:39 +08:00
pg_null_as_free = 1 ;
2001-12-17 08:24:59 +08:00
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2007-02-23 08:37:36 +08:00
spprintf ( & query , 0 , " COPY \" %s \" FROM STDIN DELIMITERS '%c' WITH NULL AS '%s' " , table_name , * pg_delim , pg_null_as ) ;
2001-12-17 08:24:59 +08:00
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
}
pgsql_result = PQexec ( pgsql , query ) ;
2005-07-05 20:45:39 +08:00
if ( pg_null_as_free ) {
efree ( pg_null_as ) ;
}
2001-12-17 08:24:59 +08:00
efree ( query ) ;
if ( pgsql_result ) {
status = PQresultStatus ( pgsql_result ) ;
} else {
status = ( ExecStatusType ) PQstatus ( pgsql ) ;
}
switch ( status ) {
case PGRES_COPY_IN :
if ( pgsql_result ) {
2005-07-05 22:49:22 +08:00
int command_failed = 0 ;
2001-12-17 08:24:59 +08:00
PQclear ( pgsql_result ) ;
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( pg_rows ) , & pos ) ;
2005-03-22 16:51:23 +08:00
# if HAVE_PQPUTCOPYDATA
2001-12-17 08:24:59 +08:00
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( pg_rows ) , ( void * * ) & tmp , & pos ) = = SUCCESS ) {
convert_to_string_ex ( tmp ) ;
2007-01-12 00:45:37 +08:00
query = ( char * ) emalloc ( Z_STRLEN_PP ( tmp ) + 2 ) ;
strlcpy ( query , Z_STRVAL_PP ( tmp ) , Z_STRLEN_PP ( tmp ) + 2 ) ;
if ( Z_STRLEN_PP ( tmp ) > 0 & & * ( query + Z_STRLEN_PP ( tmp ) - 1 ) ! = ' \n ' ) {
strlcat ( query , " \n " , Z_STRLEN_PP ( tmp ) + 2 ) ;
}
2005-03-22 16:51:23 +08:00
if ( PQputCopyData ( pgsql , query , strlen ( query ) ) ! = 1 ) {
efree ( query ) ;
PHP_PQ_ERROR ( " copy failed: %s " , pgsql ) ;
RETURN_FALSE ;
}
efree ( query ) ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( pg_rows ) , & pos ) ;
}
if ( PQputCopyEnd ( pgsql , NULL ) ! = 1 ) {
PHP_PQ_ERROR ( " putcopyend failed: %s " , pgsql ) ;
RETURN_FALSE ;
}
# else
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( pg_rows ) , ( void * * ) & tmp , & pos ) = = SUCCESS ) {
convert_to_string_ex ( tmp ) ;
2007-01-12 00:45:37 +08:00
query = ( char * ) emalloc ( Z_STRLEN_PP ( tmp ) + 2 ) ;
strlcpy ( query , Z_STRVAL_PP ( tmp ) , Z_STRLEN_PP ( tmp ) + 2 ) ;
if ( Z_STRLEN_PP ( tmp ) > 0 & & * ( query + Z_STRLEN_PP ( tmp ) - 1 ) ! = ' \n ' ) {
strlcat ( query , " \n " , Z_STRLEN_PP ( tmp ) + 2 ) ;
}
2005-03-22 16:51:23 +08:00
if ( PQputline ( pgsql , query ) = = EOF ) {
2001-12-17 08:24:59 +08:00
efree ( query ) ;
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " copy failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
efree ( query ) ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( pg_rows ) , & pos ) ;
}
2002-09-30 11:51:54 +08:00
if ( PQputline ( pgsql , " \\ . \n " ) = = EOF ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " putline failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
if ( PQendcopy ( pgsql ) ) {
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " endcopy failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
}
2005-03-22 16:51:23 +08:00
# endif
2001-12-17 08:24:59 +08:00
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
2005-07-05 22:49:22 +08:00
if ( PGRES_COMMAND_OK ! = PQresultStatus ( pgsql_result ) ) {
PHP_PQ_ERROR ( " Copy command failed: %s " , pgsql ) ;
command_failed = 1 ;
}
2001-12-17 08:24:59 +08:00
PQclear ( pgsql_result ) ;
}
2005-07-05 22:49:22 +08:00
if ( command_failed ) {
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
} else {
PQclear ( pgsql_result ) ;
RETURN_FALSE ;
}
RETURN_TRUE ;
break ;
default :
PQclear ( pgsql_result ) ;
2003-12-07 05:36:21 +08:00
PHP_PQ_ERROR ( " Copy command failed: %s " , pgsql ) ;
2001-12-17 08:24:59 +08:00
RETURN_FALSE ;
break ;
}
}
/* }}} */
2002-03-29 19:24:54 +08:00
# ifdef HAVE_PQESCAPE
2006-10-05 07:27:03 +08:00
/* {{{ proto string pg_escape_string([resource connection,] string data)
2001-12-17 08:24:59 +08:00
Escape string for text / char type */
PHP_FUNCTION ( pg_escape_string )
{
char * from = NULL , * to = NULL ;
2006-10-05 07:27:03 +08:00
zval * pgsql_link ;
2006-10-06 00:02:29 +08:00
# ifdef HAVE_PQESCAPE_CONN
2006-10-05 07:27:03 +08:00
PGconn * pgsql ;
2006-10-06 00:02:29 +08:00
# endif
2003-03-11 04:30:33 +08:00
int to_len ;
int from_len ;
2006-10-06 00:02:29 +08:00
int id = - 1 ;
2006-10-05 07:27:03 +08:00
2007-08-23 06:40:29 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & from , & from_len ) = = FAILURE ) {
return ;
}
pgsql_link = NULL ;
id = PGG ( default_link ) ;
break ;
default :
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & pgsql_link , & from , & from_len ) = = FAILURE ) {
return ;
}
break ;
2001-12-17 08:24:59 +08:00
}
2006-10-05 07:27:03 +08:00
to = ( char * ) safe_emalloc ( from_len , 2 , 1 ) ;
# ifdef HAVE_PQESCAPE_CONN
if ( pgsql_link ! = NULL | | id ! = - 1 ) {
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
to_len = ( int ) PQescapeStringConn ( pgsql , to , from , ( size_t ) from_len , NULL ) ;
} else
# endif
to_len = ( int ) PQescapeString ( to , from , ( size_t ) from_len ) ;
2002-04-04 21:54:51 +08:00
RETURN_STRINGL ( to , to_len , 0 ) ;
2001-12-17 08:24:59 +08:00
}
/* }}} */
2006-10-07 05:45:10 +08:00
/* {{{ proto string pg_escape_bytea([resource connection,] string data)
2001-12-17 08:24:59 +08:00
Escape binary for bytea type */
PHP_FUNCTION ( pg_escape_bytea )
{
char * from = NULL , * to = NULL ;
2003-03-07 07:07:28 +08:00
size_t to_len ;
2006-10-07 05:45:10 +08:00
int from_len , id = - 1 ;
# ifdef HAVE_PQESCAPE_BYTEA_CONN
PGconn * pgsql ;
# endif
zval * pgsql_link ;
2007-08-23 06:40:29 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & from , & from_len ) = = FAILURE ) {
return ;
}
pgsql_link = NULL ;
id = PGG ( default_link ) ;
break ;
default :
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " , & pgsql_link , & from , & from_len ) = = FAILURE ) {
return ;
}
break ;
2001-12-17 08:24:59 +08:00
}
2006-10-07 05:45:10 +08:00
# ifdef HAVE_PQESCAPE_BYTEA_CONN
if ( pgsql_link ! = NULL | | id ! = - 1 ) {
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
to = ( char * ) PQescapeByteaConn ( pgsql , from , ( size_t ) from_len , & to_len ) ;
} else
# endif
to = ( char * ) PQescapeBytea ( ( unsigned char * ) from , from_len , & to_len ) ;
2002-04-04 21:54:51 +08:00
RETVAL_STRINGL ( to , to_len - 1 , 1 ) ; /* to_len includes addtional '\0' */
2006-11-29 23:45:59 +08:00
PQfreemem ( to ) ;
2001-12-17 08:24:59 +08:00
}
/* }}} */
2002-10-02 12:03:21 +08:00
2005-03-25 14:26:31 +08:00
# if !HAVE_PQUNESCAPEBYTEA
2002-10-02 12:03:21 +08:00
/* PQunescapeBytea() from PostgreSQL 7.3 to provide bytea unescape feature to 7.2 users.
Renamed to php_pgsql_unescape_bytea ( ) */
/*
* PQunescapeBytea - converts the null terminated string representation
* of a bytea , strtext , into binary , filling a buffer . It returns a
* pointer to the buffer which is NULL on error , and the size of the
* buffer in retbuflen . The pointer may subsequently be used as an
* argument to the function free ( 3 ) . It is the reverse of PQescapeBytea .
*
* The following transformations are reversed :
* ' \0 ' = = ASCII 0 = = \ 000
* ' \' ' = = ASCII 39 = = \ '
* ' \\ ' = = ASCII 92 = = \ \
*
* States :
* 0 normal 0 - > 1 - > 2 - > 3 - > 4
* 1 \ 1 - > 5
* 2 \ 0 1 - > 6
* 3 \ 00
* 4 \ 000
* 5 \ '
* 6 \ \
*/
static unsigned char * php_pgsql_unescape_bytea ( unsigned char * strtext , size_t * retbuflen )
{
size_t buflen ;
unsigned char * buffer ,
* sp ,
* bp ;
unsigned int state = 0 ;
if ( strtext = = NULL )
return NULL ;
buflen = strlen ( strtext ) ; /* will shrink, also we discover if
* strtext */
2002-11-12 17:07:36 +08:00
buffer = ( unsigned char * ) emalloc ( buflen ) ; /* isn't NULL terminated */
2002-10-02 12:03:21 +08:00
for ( bp = buffer , sp = strtext ; * sp ! = ' \0 ' ; bp + + , sp + + )
{
switch ( state )
{
case 0 :
if ( * sp = = ' \\ ' )
state = 1 ;
* bp = * sp ;
break ;
case 1 :
if ( * sp = = ' \' ' ) /* state=5 */
{ /* replace \' with 39 */
bp - - ;
* bp = ' \' ' ;
buflen - - ;
state = 0 ;
}
else if ( * sp = = ' \\ ' ) /* state=6 */
{ /* replace \\ with 92 */
bp - - ;
* bp = ' \\ ' ;
buflen - - ;
state = 0 ;
}
else
{
if ( isdigit ( * sp ) )
state = 2 ;
else
state = 0 ;
* bp = * sp ;
}
break ;
case 2 :
if ( isdigit ( * sp ) )
state = 3 ;
else
state = 0 ;
* bp = * sp ;
break ;
case 3 :
if ( isdigit ( * sp ) ) /* state=4 */
{
2002-11-25 09:38:29 +08:00
unsigned char * start , * end , buf [ 4 ] ; /* 000 + '\0' */
2002-10-02 12:03:21 +08:00
bp - = 3 ;
2002-11-25 09:38:29 +08:00
memcpy ( buf , sp - 2 , 3 ) ;
buf [ 3 ] = ' \0 ' ;
start = buf ;
2002-11-26 10:13:35 +08:00
* bp = ( unsigned char ) strtoul ( start , ( char * * ) & end , 8 ) ;
2002-10-02 12:03:21 +08:00
buflen - = 3 ;
state = 0 ;
}
else
{
* bp = * sp ;
state = 0 ;
}
break ;
}
}
2002-11-24 15:45:26 +08:00
buffer = erealloc ( buffer , buflen + 1 ) ;
2002-11-25 00:23:37 +08:00
buffer [ buflen ] = ' \0 ' ;
2002-10-02 12:03:21 +08:00
* retbuflen = buflen ;
return buffer ;
}
2005-03-25 14:26:31 +08:00
# endif
2002-10-02 12:03:21 +08:00
/* {{{ proto string pg_unescape_bytea(string data)
Unescape binary for bytea type */
PHP_FUNCTION ( pg_unescape_bytea )
{
2005-03-25 14:26:31 +08:00
char * from = NULL , * to = NULL , * tmp = NULL ;
2003-03-07 07:07:28 +08:00
size_t to_len ;
2003-03-11 04:30:33 +08:00
int from_len ;
2002-10-02 12:03:21 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " ,
& from , & from_len ) = = FAILURE ) {
return ;
}
2005-03-25 14:26:31 +08:00
# if HAVE_PQUNESCAPEBYTEA
tmp = ( char * ) PQunescapeBytea ( ( unsigned char * ) from , & to_len ) ;
to = estrndup ( tmp , to_len ) ;
2006-11-29 23:45:59 +08:00
PQfreemem ( tmp ) ;
2005-03-25 14:26:31 +08:00
# else
2002-10-02 14:30:40 +08:00
to = ( char * ) php_pgsql_unescape_bytea ( ( unsigned char * ) from , & to_len ) ;
2005-03-25 14:26:31 +08:00
# endif
2002-10-02 12:03:21 +08:00
if ( ! to ) {
2002-10-02 14:22:52 +08:00
RETURN_FALSE ;
2002-10-02 12:03:21 +08:00
}
2002-11-12 17:07:36 +08:00
RETVAL_STRINGL ( to , to_len , 0 ) ;
2002-10-02 12:03:21 +08:00
}
/* }}} */
2001-12-17 08:24:59 +08:00
# endif
/* {{{ proto string pg_result_error(resource result)
Get error message associated with result */
PHP_FUNCTION ( pg_result_error )
{
zval * result ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2002-03-29 19:24:54 +08:00
char * err = NULL ;
2001-12-17 08:24:59 +08:00
2002-08-25 06:28:28 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& result ) = = FAILURE ) {
RETURN_FALSE ;
2001-12-17 08:24:59 +08:00
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
pgsql_result = pg_result - > result ;
if ( ! pgsql_result ) {
2002-03-11 15:23:07 +08:00
RETURN_FALSE ;
2001-12-17 08:24:59 +08:00
}
2002-03-29 19:24:54 +08:00
err = ( char * ) PQresultErrorMessage ( pgsql_result ) ;
RETURN_STRING ( err , 1 ) ;
2001-12-17 08:24:59 +08:00
}
/* }}} */
2005-03-19 16:46:56 +08:00
# if HAVE_PQRESULTERRORFIELD
/* {{{ proto string pg_result_error_field(resource result, int fieldcode)
Get error message field associated with result */
PHP_FUNCTION ( pg_result_error_field )
{
zval * result ;
long fieldcode ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
char * field = NULL ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " rl " ,
& result , & fieldcode ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
pgsql_result = pg_result - > result ;
if ( ! pgsql_result ) {
RETURN_FALSE ;
}
if ( fieldcode & ( PG_DIAG_SEVERITY | PG_DIAG_SQLSTATE | PG_DIAG_MESSAGE_PRIMARY | PG_DIAG_MESSAGE_DETAIL
2005-03-20 10:46:02 +08:00
| PG_DIAG_MESSAGE_HINT | PG_DIAG_STATEMENT_POSITION
2005-03-22 16:51:23 +08:00
# if PG_DIAG_INTERNAL_POSITION
| PG_DIAG_INTERNAL_POSITION
# endif
# if PG_DIAG_INTERNAL_QUERY
| PG_DIAG_INTERNAL_QUERY
2005-03-20 10:46:02 +08:00
# endif
| PG_DIAG_CONTEXT | PG_DIAG_SOURCE_FILE | PG_DIAG_SOURCE_LINE
2005-03-19 16:46:56 +08:00
| PG_DIAG_SOURCE_FUNCTION ) ) {
field = ( char * ) PQresultErrorField ( pgsql_result , fieldcode ) ;
if ( field = = NULL ) {
RETURN_NULL ( ) ;
} else {
RETURN_STRING ( field , 1 ) ;
}
} else {
RETURN_FALSE ;
}
}
/* }}} */
# endif
2001-12-17 08:24:59 +08:00
/* {{{ proto int pg_connection_status(resource connnection)
Get connection status */
PHP_FUNCTION ( pg_connection_status )
{
zval * pgsql_link = NULL ;
int id = - 1 ;
PGconn * pgsql ;
2002-08-25 06:28:28 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& pgsql_link ) = = FAILURE ) {
RETURN_FALSE ;
2001-12-17 08:24:59 +08:00
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
RETURN_LONG ( PQstatus ( pgsql ) ) ;
}
/* }}} */
2005-03-19 16:46:56 +08:00
# if HAVE_PGTRANSACTIONSTATUS
/* {{{ proto int pg_transaction_status(resource connnection)
Get transaction status */
PHP_FUNCTION ( pg_transaction_status )
{
zval * pgsql_link = NULL ;
int id = - 1 ;
PGconn * pgsql ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& pgsql_link ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
RETURN_LONG ( PQtransactionStatus ( pgsql ) ) ;
}
# endif
/* }}} */
2001-12-17 08:24:59 +08:00
/* {{{ proto bool pg_connection_reset(resource connection)
Reset connection ( reconnect ) */
PHP_FUNCTION ( pg_connection_reset )
{
zval * pgsql_link ;
int id = - 1 ;
PGconn * pgsql ;
2002-08-25 06:28:28 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& pgsql_link ) = = FAILURE ) {
RETURN_FALSE ;
2001-12-17 08:24:59 +08:00
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-10 12:02:08 +08:00
PQreset ( pgsql ) ;
if ( PQstatus ( pgsql ) = = CONNECTION_BAD ) {
RETURN_FALSE ;
}
RETURN_TRUE ;
}
/* }}} */
# define PHP_PG_ASYNC_IS_BUSY 1
# define PHP_PG_ASYNC_REQUEST_CANCEL 2
2002-04-08 09:37:38 +08:00
/* {{{ php_pgsql_flush_query
*/
2002-04-08 10:01:45 +08:00
static int php_pgsql_flush_query ( PGconn * pgsql TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
PGresult * res ;
int leftover = 0 ;
2003-01-04 20:33:46 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
2002-04-08 09:37:38 +08:00
return - 1 ;
}
while ( ( res = PQgetResult ( pgsql ) ) ) {
PQclear ( res ) ;
leftover + + ;
}
2003-01-04 20:33:46 +08:00
PQ_SETNONBLOCKING ( pgsql , 0 ) ;
2002-04-08 09:37:38 +08:00
return leftover ;
}
/* }}} */
2001-12-10 12:02:08 +08:00
/* {{{ php_pgsql_do_async
*/
2002-02-06 15:16:10 +08:00
static void php_pgsql_do_async ( INTERNAL_FUNCTION_PARAMETERS , int entry_type )
2001-12-10 12:02:08 +08:00
{
2001-12-17 08:24:59 +08:00
zval * pgsql_link ;
2001-12-10 12:02:08 +08:00
int id = - 1 ;
PGconn * pgsql ;
PGresult * pgsql_result ;
2002-08-25 06:28:28 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& pgsql_link ) = = FAILURE ) {
RETURN_FALSE ;
2001-12-10 12:02:08 +08:00
}
2001-12-17 08:24:59 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-10 12:02:08 +08:00
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
2001-12-19 13:41:26 +08:00
RETURN_FALSE ;
}
2001-12-10 12:02:08 +08:00
switch ( entry_type ) {
case PHP_PG_ASYNC_IS_BUSY :
PQconsumeInput ( pgsql ) ;
Z_LVAL_P ( return_value ) = PQisBusy ( pgsql ) ;
Z_TYPE_P ( return_value ) = IS_LONG ;
break ;
case PHP_PG_ASYNC_REQUEST_CANCEL :
Z_LVAL_P ( return_value ) = PQrequestCancel ( pgsql ) ;
Z_TYPE_P ( return_value ) = IS_LONG ;
while ( ( pgsql_result = PQgetResult ( pgsql ) ) ) {
PQclear ( pgsql_result ) ;
}
break ;
default :
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " PostgreSQL module error, please report this error " ) ;
2001-12-10 12:02:08 +08:00
break ;
}
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
2001-12-19 13:41:26 +08:00
}
2001-12-10 12:02:08 +08:00
convert_to_boolean_ex ( & return_value ) ;
}
/* }}} */
2001-12-17 19:53:38 +08:00
/* {{{ proto bool pg_cancel_query(resource connection)
2001-12-10 12:02:08 +08:00
Cancel request */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_cancel_query )
2001-12-10 12:02:08 +08:00
{
php_pgsql_do_async ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_ASYNC_REQUEST_CANCEL ) ;
}
/* }}} */
2001-12-17 19:53:38 +08:00
/* {{{ proto bool pg_connection_busy(resource connection)
2001-12-10 12:02:08 +08:00
Get connection is busy or not */
2001-12-17 08:24:59 +08:00
PHP_FUNCTION ( pg_connection_busy )
2001-12-10 12:02:08 +08:00
{
php_pgsql_do_async ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_PG_ASYNC_IS_BUSY ) ;
}
/* }}} */
2005-03-19 16:46:56 +08:00
/* {{{ proto bool pg_send_query(resource connection, string query)
2001-12-10 12:02:08 +08:00
Send asynchronous query */
PHP_FUNCTION ( pg_send_query )
{
2001-12-17 08:24:59 +08:00
zval * pgsql_link ;
char * query ;
int len ;
2001-12-10 12:02:08 +08:00
int id = - 1 ;
PGconn * pgsql ;
PGresult * res ;
int leftover = 0 ;
2001-12-17 08:24:59 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " ,
& pgsql_link , & query , & len ) = = FAILURE ) {
return ;
2001-12-10 12:02:08 +08:00
}
2001-12-17 08:24:59 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
2001-12-10 12:02:08 +08:00
RETURN_FALSE ;
}
while ( ( res = PQgetResult ( pgsql ) ) ) {
PQclear ( res ) ;
leftover = 1 ;
}
if ( leftover ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " There are results on this connection. Call pg_get_result() until it returns FALSE " ) ;
2001-12-10 12:02:08 +08:00
}
2001-12-17 08:24:59 +08:00
if ( ! PQsendQuery ( pgsql , query ) ) {
2003-02-09 15:24:18 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQreset ( pgsql ) ;
}
if ( ! PQsendQuery ( pgsql , query ) ) {
RETURN_FALSE ;
}
2001-12-10 12:02:08 +08:00
}
2002-03-29 19:24:54 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
2001-12-10 12:02:08 +08:00
}
RETURN_TRUE ;
}
/* }}} */
2005-03-19 16:46:56 +08:00
# if HAVE_PQSENDQUERYPARAMS
2008-06-30 06:38:55 +08:00
/* {{{ proto bool pg_send_query_params(resource connection, string query, array params)
2005-03-19 16:46:56 +08:00
Send asynchronous parameterized query */
PHP_FUNCTION ( pg_send_query_params )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link , * pv_param_arr , * * tmp ;
2005-03-19 16:46:56 +08:00
int num_params = 0 ;
char * * params = NULL ;
2008-06-30 06:38:55 +08:00
char * query ;
int query_len , id = - 1 ;
2005-03-19 16:46:56 +08:00
PGconn * pgsql ;
PGresult * res ;
int leftover = 0 ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rsa/ " , & pgsql_link , & query , & query_len , & pv_param_arr ) = = FAILURE ) {
return ;
2005-03-19 16:46:56 +08:00
}
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
RETURN_FALSE ;
}
while ( ( res = PQgetResult ( pgsql ) ) ) {
PQclear ( res ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " There are results on this connection. Call pg_get_result() until it returns FALSE " ) ;
}
2008-06-30 06:38:55 +08:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( pv_param_arr ) ) ;
num_params = zend_hash_num_elements ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
if ( num_params > 0 ) {
int i = 0 ;
params = ( char * * ) safe_emalloc ( sizeof ( char * ) , num_params , 0 ) ;
for ( i = 0 ; i < num_params ; i + + ) {
2008-06-30 06:38:55 +08:00
if ( zend_hash_get_current_data ( Z_ARRVAL_P ( pv_param_arr ) , ( void * * ) & tmp ) = = FAILURE ) {
2005-03-19 16:46:56 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error getting parameter " ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
2008-10-02 04:30:23 +08:00
if ( Z_TYPE_PP ( tmp ) = = IS_NULL ) {
2005-03-19 16:46:56 +08:00
params [ i ] = NULL ;
2008-10-02 04:30:23 +08:00
} else {
zval tmp_val = * * tmp ;
zval_copy_ctor ( & tmp_val ) ;
convert_to_string ( & tmp_val ) ;
if ( Z_TYPE ( tmp_val ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error converting parameter " ) ;
zval_dtor ( & tmp_val ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
params [ i ] = estrndup ( Z_STRVAL ( tmp_val ) , Z_STRLEN ( tmp_val ) ) ;
zval_dtor ( & tmp_val ) ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
zend_hash_move_forward ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
}
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendQueryParams ( pgsql , query , num_params , NULL , ( const char * const * ) params , NULL , NULL , 0 ) ) {
2005-03-19 16:46:56 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQreset ( pgsql ) ;
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendQueryParams ( pgsql , query , num_params , NULL , ( const char * const * ) params , NULL , NULL , 0 ) ) {
2005-03-19 16:46:56 +08:00
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
}
_php_pgsql_free_params ( params , num_params ) ;
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
}
RETURN_TRUE ;
}
/* }}} */
# endif
# if HAVE_PQSENDPREPARE
/* {{{ proto bool pg_send_prepare(resource connection, string stmtname, string query)
Asynchronously prepare a query for future execution */
PHP_FUNCTION ( pg_send_prepare )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link ;
char * query , * stmtname ;
int stmtname_len , query_len , id = - 1 ;
2005-03-19 16:46:56 +08:00
PGconn * pgsql ;
PGresult * res ;
int leftover = 0 ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rss " , & pgsql_link , & stmtname , & stmtname_len , & query , & query_len ) = = FAILURE ) {
return ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
2005-03-19 16:46:56 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
RETURN_FALSE ;
}
while ( ( res = PQgetResult ( pgsql ) ) ) {
PQclear ( res ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " There are results on this connection. Call pg_get_result() until it returns FALSE " ) ;
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendPrepare ( pgsql , stmtname , query , 0 , NULL ) ) {
2005-03-19 16:46:56 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQreset ( pgsql ) ;
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendPrepare ( pgsql , stmtname , query , 0 , NULL ) ) {
2005-03-19 16:46:56 +08:00
RETURN_FALSE ;
}
}
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
}
RETURN_TRUE ;
}
/* }}} */
# endif
# if HAVE_PQSENDQUERYPREPARED
/* {{{ proto bool pg_send_execute(resource connection, string stmtname, array params)
Executes prevriously prepared stmtname asynchronously */
PHP_FUNCTION ( pg_send_execute )
{
2008-06-30 06:38:55 +08:00
zval * pgsql_link ;
zval * pv_param_arr , * * tmp ;
2005-03-19 16:46:56 +08:00
int num_params = 0 ;
char * * params = NULL ;
2008-06-30 06:38:55 +08:00
char * stmtname ;
int stmtname_len , id = - 1 ;
2005-03-19 16:46:56 +08:00
PGconn * pgsql ;
PGresult * res ;
int leftover = 0 ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rsa " , & pgsql_link , & stmtname , & stmtname_len , & pv_param_arr ) = = FAILURE ) {
return ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
if ( pgsql_link = = NULL & & id = = - 1 ) {
2005-03-19 16:46:56 +08:00
RETURN_FALSE ;
}
2008-06-30 06:38:55 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-03-19 16:46:56 +08:00
if ( PQ_SETNONBLOCKING ( pgsql , 1 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to nonblocking mode " ) ;
RETURN_FALSE ;
}
while ( ( res = PQgetResult ( pgsql ) ) ) {
PQclear ( res ) ;
leftover = 1 ;
}
if ( leftover ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " There are results on this connection. Call pg_get_result() until it returns FALSE " ) ;
}
2008-06-30 06:38:55 +08:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( pv_param_arr ) ) ;
num_params = zend_hash_num_elements ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
if ( num_params > 0 ) {
int i = 0 ;
params = ( char * * ) safe_emalloc ( sizeof ( char * ) , num_params , 0 ) ;
for ( i = 0 ; i < num_params ; i + + ) {
2008-06-30 06:38:55 +08:00
if ( zend_hash_get_current_data ( Z_ARRVAL_P ( pv_param_arr ) , ( void * * ) & tmp ) = = FAILURE ) {
2005-03-19 16:46:56 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error getting parameter " ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
2008-10-02 04:30:23 +08:00
if ( Z_TYPE_PP ( tmp ) = = IS_NULL ) {
2005-03-19 16:46:56 +08:00
params [ i ] = NULL ;
2008-10-02 04:30:23 +08:00
} else {
zval tmp_val = * * tmp ;
zval_copy_ctor ( & tmp_val ) ;
convert_to_string ( & tmp_val ) ;
if ( Z_TYPE ( tmp_val ) ! = IS_STRING ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Error converting parameter " ) ;
zval_dtor ( & tmp_val ) ;
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
params [ i ] = estrndup ( Z_STRVAL ( tmp_val ) , Z_STRLEN ( tmp_val ) ) ;
zval_dtor ( & tmp_val ) ;
2005-03-19 16:46:56 +08:00
}
2008-06-30 06:38:55 +08:00
zend_hash_move_forward ( Z_ARRVAL_P ( pv_param_arr ) ) ;
2005-03-19 16:46:56 +08:00
}
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendQueryPrepared ( pgsql , stmtname , num_params , ( const char * const * ) params , NULL , NULL , 0 ) ) {
2005-03-19 16:46:56 +08:00
if ( ( PGG ( auto_reset_persistent ) & 2 ) & & PQstatus ( pgsql ) ! = CONNECTION_OK ) {
PQreset ( pgsql ) ;
}
2008-06-30 06:38:55 +08:00
if ( ! PQsendQueryPrepared ( pgsql , stmtname , num_params , ( const char * const * ) params , NULL , NULL , 0 ) ) {
2005-03-19 16:46:56 +08:00
_php_pgsql_free_params ( params , num_params ) ;
RETURN_FALSE ;
}
}
_php_pgsql_free_params ( params , num_params ) ;
if ( PQ_SETNONBLOCKING ( pgsql , 0 ) ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Cannot set connection to blocking mode " ) ;
}
RETURN_TRUE ;
}
/* }}} */
# endif
2001-12-10 12:02:08 +08:00
2003-01-15 18:21:15 +08:00
/* {{{ proto resource pg_get_result(resource connection)
2001-12-10 12:02:08 +08:00
Get asynchronous query result */
PHP_FUNCTION ( pg_get_result )
{
2001-12-17 08:24:59 +08:00
zval * pgsql_link ;
2001-12-10 12:02:08 +08:00
int id = - 1 ;
PGconn * pgsql ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2008-06-30 06:38:55 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " , & pgsql_link ) = = FAILURE ) {
2002-08-25 06:28:28 +08:00
RETURN_FALSE ;
2001-12-10 12:02:08 +08:00
}
2001-12-17 08:24:59 +08:00
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2001-12-10 12:02:08 +08:00
pgsql_result = PQgetResult ( pgsql ) ;
if ( ! pgsql_result ) {
/* no result */
RETURN_FALSE ;
}
pg_result = ( pgsql_result_handle * ) emalloc ( sizeof ( pgsql_result_handle ) ) ;
pg_result - > conn = pgsql ;
pg_result - > result = pgsql_result ;
2003-02-09 15:50:16 +08:00
pg_result - > row = 0 ;
2001-12-10 12:02:08 +08:00
ZEND_REGISTER_RESOURCE ( return_value , pg_result , le_result ) ;
}
/* }}} */
2003-07-20 03:23:34 +08:00
/* {{{ proto mixed pg_result_status(resource result[, long result_type])
2001-12-17 08:24:59 +08:00
Get status of query result */
PHP_FUNCTION ( pg_result_status )
{
zval * result ;
2002-04-08 08:43:58 +08:00
long result_type = PGSQL_STATUS_LONG ;
2001-12-17 08:24:59 +08:00
ExecStatusType status ;
PGresult * pgsql_result ;
pgsql_result_handle * pg_result ;
2002-08-24 15:18:15 +08:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|l " ,
2002-08-25 06:28:28 +08:00
& result , & result_type ) = = FAILURE ) {
2002-08-24 15:18:15 +08:00
RETURN_FALSE ;
2001-12-17 08:24:59 +08:00
}
ZEND_FETCH_RESOURCE ( pg_result , pgsql_result_handle * , & result , - 1 , " PostgreSQL result " , le_result ) ;
pgsql_result = pg_result - > result ;
2002-04-08 08:43:58 +08:00
if ( result_type = = PGSQL_STATUS_LONG ) {
status = PQresultStatus ( pgsql_result ) ;
RETURN_LONG ( ( int ) status ) ;
}
2002-04-08 08:50:44 +08:00
else if ( result_type = = PGSQL_STATUS_STRING ) {
RETURN_STRING ( PQcmdStatus ( pgsql_result ) , 1 ) ;
}
2002-04-08 08:43:58 +08:00
else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Optional 2nd parameter should be PGSQL_STATUS_LONG or PGSQL_STATUS_STRING " ) ;
2002-04-08 08:43:58 +08:00
RETURN_FALSE ;
}
2001-12-17 08:24:59 +08:00
}
/* }}} */
2002-10-17 15:58:46 +08:00
2003-07-20 03:23:34 +08:00
/* {{{ proto array pg_get_notify([resource connection[, result_type]])
2002-10-17 15:58:46 +08:00
Get asynchronous notification */
PHP_FUNCTION ( pg_get_notify )
{
zval * pgsql_link ;
2004-02-26 04:16:27 +08:00
int id = - 1 ;
long result_type = PGSQL_ASSOC ;
2002-10-17 15:58:46 +08:00
PGconn * pgsql ;
PGnotify * pgsql_notify ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r|l " ,
2004-02-26 04:16:27 +08:00
& pgsql_link , & result_type ) = = FAILURE ) {
2002-10-17 15:58:46 +08:00
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
2005-05-11 07:12:31 +08:00
if ( ! ( result_type & PGSQL_BOTH ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid result type " ) ;
RETURN_FALSE ;
}
2002-10-17 15:58:46 +08:00
PQconsumeInput ( pgsql ) ;
pgsql_notify = PQnotifies ( pgsql ) ;
if ( ! pgsql_notify ) {
/* no notify message */
RETURN_FALSE ;
}
array_init ( return_value ) ;
2005-05-11 07:12:31 +08:00
if ( result_type & PGSQL_NUM ) {
2002-10-17 15:58:46 +08:00
add_index_string ( return_value , 0 , pgsql_notify - > relname , 1 ) ;
add_index_long ( return_value , 1 , pgsql_notify - > be_pid ) ;
}
2005-05-11 07:12:31 +08:00
if ( result_type & PGSQL_ASSOC ) {
2002-10-17 15:58:46 +08:00
add_assoc_string ( return_value , " message " , pgsql_notify - > relname , 1 ) ;
add_assoc_long ( return_value , " pid " , pgsql_notify - > be_pid ) ;
}
2006-11-29 23:45:59 +08:00
PQfreemem ( pgsql_notify ) ;
2002-10-17 15:58:46 +08:00
}
/* }}} */
2003-07-20 03:23:34 +08:00
/* {{{ proto int pg_get_pid([resource connection)
2002-10-18 07:41:34 +08:00
Get backend ( server ) pid */
PHP_FUNCTION ( pg_get_pid )
{
zval * pgsql_link ;
2002-10-25 03:15:40 +08:00
int id = - 1 ;
2002-10-18 07:41:34 +08:00
PGconn * pgsql ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " r " ,
& pgsql_link ) = = FAILURE ) {
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
RETURN_LONG ( PQbackendPID ( pgsql ) ) ;
}
/* }}} */
2002-10-17 15:58:46 +08:00
2002-10-02 10:11:27 +08:00
/* {{{ php_pgsql_meta_data
* TODO : Add meta_data cache for better performance
2002-04-08 09:37:38 +08:00
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_meta_data ( PGconn * pg_link , const char * table_name , zval * meta TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
PGresult * pg_result ;
2002-04-21 19:29:17 +08:00
char * tmp_name ;
smart_str querystr = { 0 } ;
2003-03-11 04:30:33 +08:00
int new_len ;
2002-04-08 09:37:38 +08:00
int i , num_rows ;
zval * elem ;
2002-04-21 19:29:17 +08:00
smart_str_appends ( & querystr ,
2003-08-27 08:04:19 +08:00
" SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims "
2002-04-21 19:29:17 +08:00
" FROM pg_class as c, pg_attribute a, pg_type t "
" WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = ' " ) ;
2002-04-08 09:37:38 +08:00
tmp_name = php_addslashes ( ( char * ) table_name , strlen ( table_name ) , & new_len , 0 TSRMLS_CC ) ;
2002-04-21 19:29:17 +08:00
smart_str_appendl ( & querystr , tmp_name , new_len ) ;
2002-04-08 09:37:38 +08:00
efree ( tmp_name ) ;
2002-04-21 19:29:17 +08:00
smart_str_appends ( & querystr , " ' AND a.atttypid = t.oid ORDER BY a.attnum; " ) ;
smart_str_0 ( & querystr ) ;
pg_result = PQexec ( pg_link , querystr . c ) ;
2002-04-08 09:37:38 +08:00
if ( PQresultStatus ( pg_result ) ! = PGRES_TUPLES_OK | | ( num_rows = PQntuples ( pg_result ) ) = = 0 ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Failed to query meta_data for '%s' table %s " , table_name , querystr . c ) ;
2002-04-21 19:29:17 +08:00
smart_str_free ( & querystr ) ;
2002-04-08 09:37:38 +08:00
PQclear ( pg_result ) ;
return FAILURE ;
}
2002-04-21 19:29:17 +08:00
smart_str_free ( & querystr ) ;
2002-04-08 09:37:38 +08:00
for ( i = 0 ; i < num_rows ; i + + ) {
char * name ;
MAKE_STD_ZVAL ( elem ) ;
array_init ( elem ) ;
add_assoc_long ( elem , " num " , atoi ( PQgetvalue ( pg_result , i , 1 ) ) ) ;
add_assoc_string ( elem , " type " , PQgetvalue ( pg_result , i , 2 ) , 1 ) ;
add_assoc_long ( elem , " len " , atoi ( PQgetvalue ( pg_result , i , 3 ) ) ) ;
if ( ! strcmp ( PQgetvalue ( pg_result , i , 4 ) , " t " ) ) {
add_assoc_bool ( elem , " not null " , 1 ) ;
}
else {
add_assoc_bool ( elem , " not null " , 0 ) ;
}
if ( ! strcmp ( PQgetvalue ( pg_result , i , 5 ) , " t " ) ) {
2002-04-19 20:19:29 +08:00
add_assoc_bool ( elem , " has default " , 1 ) ;
2002-04-08 09:37:38 +08:00
}
else {
2002-04-19 20:19:29 +08:00
add_assoc_bool ( elem , " has default " , 0 ) ;
2002-04-08 09:37:38 +08:00
}
2003-08-27 08:04:19 +08:00
add_assoc_long ( elem , " array dims " , atoi ( PQgetvalue ( pg_result , i , 6 ) ) ) ;
2002-04-08 09:37:38 +08:00
name = PQgetvalue ( pg_result , i , 0 ) ;
add_assoc_zval ( meta , name , elem ) ;
}
2003-08-15 01:49:08 +08:00
PQclear ( pg_result ) ;
2002-04-08 09:37:38 +08:00
return SUCCESS ;
}
/* }}} */
2002-10-02 10:11:27 +08:00
/* {{{ proto array pg_meta_data(resource db, string table)
Get meta_data */
PHP_FUNCTION ( pg_meta_data )
2002-04-08 09:37:38 +08:00
{
zval * pgsql_link ;
char * table_name ;
uint table_name_len ;
PGconn * pgsql ;
int id = - 1 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " rs " ,
& pgsql_link , & table_name , & table_name_len ) = = FAILURE ) {
return ;
}
ZEND_FETCH_RESOURCE2 ( pgsql , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
array_init ( return_value ) ;
2002-10-02 10:11:27 +08:00
if ( php_pgsql_meta_data ( pgsql , table_name , return_value TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( return_value ) ; /* destroy array */
RETURN_FALSE ;
}
}
/* }}} */
/* {{{ php_pgsql_get_data_type
*/
static php_pgsql_data_type php_pgsql_get_data_type ( const char * type_name , size_t len )
{
/* This is stupid way to do. I'll fix it when I decied how to support
user defined types . ( Yasuo ) */
/* boolean */
2002-07-20 15:24:15 +08:00
if ( ! strcmp ( type_name , " bool " ) | | ! strcmp ( type_name , " boolean " ) )
2002-04-08 09:37:38 +08:00
return PG_BOOL ;
/* object id */
if ( ! strcmp ( type_name , " oid " ) )
return PG_OID ;
/* integer */
if ( ! strcmp ( type_name , " int2 " ) | | ! strcmp ( type_name , " smallint " ) )
return PG_INT2 ;
if ( ! strcmp ( type_name , " int4 " ) | | ! strcmp ( type_name , " integer " ) )
return PG_INT4 ;
if ( ! strcmp ( type_name , " int8 " ) | | ! strcmp ( type_name , " bigint " ) )
return PG_INT8 ;
/* real and other */
if ( ! strcmp ( type_name , " float4 " ) | | ! strcmp ( type_name , " real " ) )
return PG_FLOAT4 ;
if ( ! strcmp ( type_name , " float8 " ) | | ! strcmp ( type_name , " double precision " ) )
return PG_FLOAT8 ;
if ( ! strcmp ( type_name , " numeric " ) )
return PG_NUMERIC ;
if ( ! strcmp ( type_name , " money " ) )
return PG_MONEY ;
/* character */
if ( ! strcmp ( type_name , " text " ) )
return PG_TEXT ;
if ( ! strcmp ( type_name , " bpchar " ) | | ! strcmp ( type_name , " character " ) )
return PG_CHAR ;
if ( ! strcmp ( type_name , " varchar " ) | | ! strcmp ( type_name , " character varying " ) )
return PG_VARCHAR ;
/* time and interval */
if ( ! strcmp ( type_name , " abstime " ) )
return PG_UNIX_TIME ;
if ( ! strcmp ( type_name , " reltime " ) )
return PG_UNIX_TIME_INTERVAL ;
if ( ! strcmp ( type_name , " tinterval " ) )
return PG_UNIX_TIME_INTERVAL ;
if ( ! strcmp ( type_name , " date " ) )
return PG_DATE ;
if ( ! strcmp ( type_name , " time " ) )
return PG_TIME ;
2003-04-02 07:34:11 +08:00
if ( ! strcmp ( type_name , " time with time zone " ) | | ! strcmp ( type_name , " timetz " ) )
2002-04-08 09:37:38 +08:00
return PG_TIME_WITH_TIMEZONE ;
2003-04-02 07:56:16 +08:00
if ( ! strcmp ( type_name , " timestamp without time zone " ) | | ! strcmp ( type_name , " timestamp " ) )
return PG_TIMESTAMP ;
2003-04-02 07:26:10 +08:00
if ( ! strcmp ( type_name , " timestamp with time zone " ) | | ! strcmp ( type_name , " timestamptz " ) )
2002-04-08 09:37:38 +08:00
return PG_TIMESTAMP_WITH_TIMEZONE ;
if ( ! strcmp ( type_name , " interval " ) )
return PG_INTERVAL ;
/* binary */
if ( ! strcmp ( type_name , " bytea " ) )
return PG_BYTEA ;
/* network */
if ( ! strcmp ( type_name , " cidr " ) )
return PG_CIDR ;
if ( ! strcmp ( type_name , " inet " ) )
return PG_INET ;
if ( ! strcmp ( type_name , " macaddr " ) )
return PG_MACADDR ;
/* bit */
if ( ! strcmp ( type_name , " bit " ) )
return PG_BIT ;
if ( ! strcmp ( type_name , " bit varying " ) )
return PG_VARBIT ;
2002-04-21 18:37:40 +08:00
/* geometric */
2002-04-08 09:37:38 +08:00
if ( ! strcmp ( type_name , " line " ) )
return PG_LINE ;
if ( ! strcmp ( type_name , " lseg " ) )
return PG_LSEG ;
if ( ! strcmp ( type_name , " box " ) )
return PG_BOX ;
if ( ! strcmp ( type_name , " path " ) )
return PG_PATH ;
if ( ! strcmp ( type_name , " point " ) )
return PG_POINT ;
if ( ! strcmp ( type_name , " polygon " ) )
return PG_POLYGON ;
if ( ! strcmp ( type_name , " circle " ) )
return PG_CIRCLE ;
return PG_UNKNOWN ;
}
/* }}} */
/* {{{ php_pgsql_convert_match
* test field value with regular expression specified .
*/
static int php_pgsql_convert_match ( const char * str , const char * regex , int icase TSRMLS_DC )
{
regex_t re ;
regmatch_t * subs ;
int regopt = REG_EXTENDED ;
int regerr , ret = SUCCESS ;
if ( icase ) {
regopt | = REG_ICASE ;
}
regerr = regcomp ( & re , regex , regopt ) ;
if ( regerr ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot compile regex " ) ;
2002-04-08 09:37:38 +08:00
regfree ( & re ) ;
return FAILURE ;
}
subs = ( regmatch_t * ) ecalloc ( sizeof ( regmatch_t ) , re . re_nsub + 1 ) ;
2003-01-19 03:28:10 +08:00
2002-04-08 09:37:38 +08:00
regerr = regexec ( & re , str , re . re_nsub + 1 , subs , 0 ) ;
if ( regerr = = REG_NOMATCH ) {
# ifdef PHP_DEBUG
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " '%s' does not match with '%s' " , str , regex ) ;
2002-04-08 09:37:38 +08:00
# endif
ret = FAILURE ;
}
else if ( regerr ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot exec regex " ) ;
2002-04-08 09:37:38 +08:00
ret = FAILURE ;
}
regfree ( & re ) ;
efree ( subs ) ;
return ret ;
}
/* }}} */
2002-04-19 20:19:29 +08:00
/* {{{ php_pgsql_add_quote
2002-04-08 09:37:38 +08:00
* add quotes around string .
*/
2002-04-08 10:01:45 +08:00
static int php_pgsql_add_quotes ( zval * src , zend_bool should_free TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
2002-04-21 19:29:17 +08:00
smart_str str = { 0 } ;
2002-04-08 09:37:38 +08:00
assert ( Z_TYPE_P ( src ) = = IS_STRING ) ;
assert ( should_free = = 1 | | should_free = = 0 ) ;
2002-04-21 19:29:17 +08:00
smart_str_appendc ( & str , ' \' ' ) ;
smart_str_appendl ( & str , Z_STRVAL_P ( src ) , Z_STRLEN_P ( src ) ) ;
smart_str_appendc ( & str , ' \' ' ) ;
smart_str_0 ( & str ) ;
2002-04-08 09:37:38 +08:00
if ( should_free ) {
efree ( Z_STRVAL_P ( src ) ) ;
}
2002-04-21 19:29:17 +08:00
Z_STRVAL_P ( src ) = str . c ;
Z_STRLEN_P ( src ) = str . len ;
2002-04-08 09:37:38 +08:00
return SUCCESS ;
}
/* }}} */
2002-04-23 11:42:26 +08:00
# define PGSQL_CONV_CHECK_IGNORE() \
2002-07-20 14:45:35 +08:00
if ( ! err & & Z_TYPE_P ( new_val ) = = IS_STRING & & ! strcmp ( Z_STRVAL_P ( new_val ) , " NULL " ) ) { \
2002-09-30 15:24:41 +08:00
/* if new_value is string "NULL" and field has default value, remove element to use default value */ \
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_CONV_IGNORE_DEFAULT ) & & Z_BVAL_PP ( has_default ) ) { \
zval_dtor ( new_val ) ; \
FREE_ZVAL ( new_val ) ; \
skip_field = 1 ; \
} \
2002-09-30 15:24:41 +08:00
/* raise error if it's not null and cannot be ignored */ \
else if ( ! ( opt & PGSQL_CONV_IGNORE_NOT_NULL ) & & Z_BVAL_PP ( not_null ) ) { \
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected NULL for 'NOT NULL' field '%s' " , field ) ; \
2002-04-23 11:42:26 +08:00
err = 1 ; \
} \
}
2002-04-08 09:37:38 +08:00
/* {{{ php_pgsql_convert
* check and convert array values ( fieldname = > vlaue pair ) for sql
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_convert ( PGconn * pg_link , const char * table_name , const zval * values , zval * result , ulong opt TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
HashPosition pos ;
char * field = NULL ;
uint field_len = - 1 ;
ulong num_idx = - 1 ;
2002-04-19 20:24:14 +08:00
zval * meta , * * def , * * type , * * not_null , * * has_default , * * val , * new_val ;
int new_len , key_type , err = 0 , skip_field ;
2002-04-08 09:37:38 +08:00
assert ( pg_link ! = NULL ) ;
assert ( Z_TYPE_P ( values ) = = IS_ARRAY ) ;
assert ( Z_TYPE_P ( result ) = = IS_ARRAY ) ;
2002-04-23 11:42:26 +08:00
assert ( ! ( opt & ~ PGSQL_CONV_OPTS ) ) ;
2002-04-08 09:37:38 +08:00
if ( ! table_name ) {
return FAILURE ;
}
MAKE_STD_ZVAL ( meta ) ;
2003-01-19 03:28:10 +08:00
array_init ( meta ) ;
2002-10-02 10:11:27 +08:00
if ( php_pgsql_meta_data ( pg_link , table_name , meta TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( meta ) ;
FREE_ZVAL ( meta ) ;
return FAILURE ;
}
for ( zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( values ) , & pos ) ;
zend_hash_get_current_data_ex ( Z_ARRVAL_P ( values ) , ( void * * ) & val , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( values ) , & pos ) ) {
2002-04-19 20:24:14 +08:00
skip_field = 0 ;
2006-04-11 03:51:55 +08:00
new_val = NULL ;
2002-10-19 12:46:19 +08:00
2002-04-21 18:37:40 +08:00
if ( ( key_type = zend_hash_get_current_key_ex ( Z_ARRVAL_P ( values ) , & field , & field_len , & num_idx , 0 , & pos ) ) = = HASH_KEY_NON_EXISTANT ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to get array key type " ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
if ( ! err & & key_type = = HASH_KEY_IS_LONG ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Accepts only string key for values " ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
if ( ! err & & key_type = = HASH_KEY_NON_EXISTANT ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Accepts only string key for values " ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
if ( ! err & & zend_hash_find ( Z_ARRVAL_P ( meta ) , field , field_len , ( void * * ) & def ) = = FAILURE ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Invalid field name (%s) in values " , field ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
2002-04-19 20:24:14 +08:00
if ( ! err & & zend_hash_find ( Z_ARRVAL_PP ( def ) , " type " , sizeof ( " type " ) , ( void * * ) & type ) = = FAILURE ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected broken meta data. Missing 'type' " ) ;
2002-04-19 20:24:14 +08:00
err = 1 ;
}
if ( ! err & & zend_hash_find ( Z_ARRVAL_PP ( def ) , " not null " , sizeof ( " not null " ) , ( void * * ) & not_null ) = = FAILURE ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected broken meta data. Missing 'not null' " ) ;
2002-04-19 20:24:14 +08:00
err = 1 ;
}
if ( ! err & & zend_hash_find ( Z_ARRVAL_PP ( def ) , " has default " , sizeof ( " has default " ) , ( void * * ) & has_default ) = = FAILURE ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected broken meta data. Missing 'has default' " ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
if ( ! err & & ( Z_TYPE_PP ( val ) = = IS_ARRAY | |
Z_TYPE_PP ( val ) = = IS_OBJECT | |
Z_TYPE_PP ( val ) = = IS_CONSTANT_ARRAY ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects scaler values as field values " ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
if ( err ) {
2002-10-19 14:05:16 +08:00
break ; /* break out for() */
2002-04-08 09:37:38 +08:00
}
2006-04-11 03:51:55 +08:00
ALLOC_INIT_ZVAL ( new_val ) ;
2002-04-08 09:37:38 +08:00
switch ( php_pgsql_get_data_type ( Z_STRVAL_PP ( type ) , Z_STRLEN_PP ( type ) ) )
{
case PG_BOOL :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
if ( ! strcmp ( Z_STRVAL_PP ( val ) , " t " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " T " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " y " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " Y " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " true " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " True " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " yes " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " Yes " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " 1 " ) ) {
2002-07-20 15:45:01 +08:00
ZVAL_STRING ( new_val , " 't' " , 1 ) ;
2002-04-08 09:37:38 +08:00
}
else if ( ! strcmp ( Z_STRVAL_PP ( val ) , " f " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " F " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " n " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " N " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " false " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " False " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " no " ) | | ! strcmp ( Z_STRVAL_PP ( val ) , " No " ) | |
! strcmp ( Z_STRVAL_PP ( val ) , " 0 " ) ) {
2002-07-20 15:45:01 +08:00
ZVAL_STRING ( new_val , " 'f' " , 1 ) ;
2002-04-08 09:37:38 +08:00
}
else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected invalid value (%s) for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( val ) , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
}
}
break ;
case IS_LONG :
case IS_BOOL :
if ( Z_LVAL_PP ( val ) ) {
2002-07-20 15:45:01 +08:00
ZVAL_STRING ( new_val , " 't' " , 1 ) ;
2002-04-08 09:37:38 +08:00
}
else {
2002-07-20 15:45:01 +08:00
ZVAL_STRING ( new_val , " 'f' " , 1 ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects string, null, long or boolelan value for PostgreSQL '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_OID :
case PG_INT2 :
case PG_INT4 :
case PG_INT8 :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([+-]{0,1}[0-9]+)$ " , 0 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
}
}
break ;
case IS_DOUBLE :
ZVAL_DOUBLE ( new_val , Z_DVAL_PP ( val ) ) ;
convert_to_long_ex ( & new_val ) ;
break ;
case IS_LONG :
ZVAL_LONG ( new_val , Z_LVAL_PP ( val ) ) ;
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL, string, long or double value for pgsql '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_NUMERIC :
case PG_MONEY :
case PG_FLOAT4 :
case PG_FLOAT8 :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([+-]{0,1}[0-9]+)|([+-]{0,1}[0-9]*[ \\ .][0-9]+)|([+-]{0,1}[0-9]+[ \\ .][0-9]*)$ " , 0 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
}
}
break ;
case IS_LONG :
2002-04-20 10:31:48 +08:00
ZVAL_LONG ( new_val , Z_LVAL_PP ( val ) ) ;
2002-04-08 09:37:38 +08:00
break ;
case IS_DOUBLE :
ZVAL_DOUBLE ( new_val , Z_DVAL_PP ( val ) ) ;
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL, string, long or double value for PostgreSQL '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_TEXT :
case PG_CHAR :
case PG_VARCHAR :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
2002-09-30 15:35:41 +08:00
if ( opt & PGSQL_CONV_FORCE_NULL ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
2003-12-22 23:56:51 +08:00
} else {
ZVAL_STRING ( new_val , " '' " , 1 ) ;
2002-09-30 15:35:41 +08:00
}
2002-04-08 09:37:38 +08:00
}
else {
Z_TYPE_P ( new_val ) = IS_STRING ;
# if HAVE_PQESCAPE
{
char * tmp ;
2003-04-26 05:59:58 +08:00
tmp = ( char * ) safe_emalloc ( Z_STRLEN_PP ( val ) , 2 , 1 ) ;
2002-04-08 09:37:38 +08:00
Z_STRLEN_P ( new_val ) = ( int ) PQescapeString ( tmp , Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) ) ;
Z_STRVAL_P ( new_val ) = tmp ;
}
# else
Z_STRVAL_P ( new_val ) = php_addslashes ( Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) , & Z_STRLEN_P ( new_val ) , 0 TSRMLS_CC ) ;
# endif
2003-12-16 09:00:34 +08:00
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case IS_LONG :
ZVAL_LONG ( new_val , Z_LVAL_PP ( val ) ) ;
convert_to_string_ex ( & new_val ) ;
break ;
case IS_DOUBLE :
ZVAL_DOUBLE ( new_val , Z_DVAL_PP ( val ) ) ;
convert_to_string_ex ( & new_val ) ;
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL, string, long or double value for PostgreSQL '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_UNIX_TIME :
case PG_UNIX_TIME_INTERVAL :
/* these are the actallay a integer */
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: Better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^[0-9]+$ " , 0 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
convert_to_long_ex ( & new_val ) ;
}
}
break ;
case IS_DOUBLE :
ZVAL_DOUBLE ( new_val , Z_DVAL_PP ( val ) ) ;
convert_to_long_ex ( & new_val ) ;
break ;
case IS_LONG :
ZVAL_LONG ( new_val , Z_LVAL_PP ( val ) ) ;
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL, string, long or double value for '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_CIDR :
case PG_INET :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: Better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([0-9]{1,3} \\ .){3}[0-9]{1,3}(/[0-9]{1,2}){0,1}$ " , 0 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
}
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
2002-04-19 20:24:14 +08:00
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_TIME_WITH_TIMEZONE :
2003-04-02 07:56:16 +08:00
case PG_TIMESTAMP :
2002-04-08 09:37:38 +08:00
case PG_TIMESTAMP_WITH_TIMEZONE :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
2006-12-29 08:34:30 +08:00
ZVAL_STRINGL ( new_val , " NULL " , sizeof ( " NULL " ) - 1 , 1 ) ;
} else if ( ! strcasecmp ( Z_STRVAL_PP ( val ) , " now() " ) ) {
ZVAL_STRINGL ( new_val , " NOW() " , sizeof ( " NOW() " ) - 1 , 1 ) ;
} else {
2002-04-08 09:37:38 +08:00
/* FIXME: better regex must be used */
2008-05-19 23:16:47 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\ t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}( \\ .[0-9]+){0,1}([ \\ t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$ " , 1 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
2006-12-29 08:34:30 +08:00
} else {
2002-04-08 09:37:38 +08:00
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
}
break ;
case IS_NULL :
2006-12-29 08:34:30 +08:00
ZVAL_STRINGL ( new_val , " NULL " , sizeof ( " NULL " ) - 1 , 1 ) ;
2002-04-08 09:37:38 +08:00
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_DATE :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$ " , 1 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
}
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_TIME :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
/* FIXME: better regex must be used */
2002-04-08 10:01:45 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$ " , 1 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
}
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
case PG_INTERVAL :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
2004-03-18 09:34:58 +08:00
/* From the Postgres docs:
interval values can be written with the following syntax :
[ @ ] quantity unit [ quantity unit . . . ] [ direction ]
Where : quantity is a number ( possibly signed ) ; unit is second , minute , hour ,
day , week , month , year , decade , century , millennium , or abbreviations or
plurals of these units [ note not * all * abbreviations ] ; direction can be
ago or empty . The at sign ( @ ) is optional noise .
. . .
Quantities of days , hours , minutes , and seconds can be specified without explicit
unit markings . For example , ' 1 12 : 59 : 10 ' is read the same as ' 1 day 12 hours 59 min 10
sec ' .
*/
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) ,
" ^(@?[ \\ t]+)?( "
/* Textual time units and their abbreviations: */
" (([-+]?[ \\ t]+)? "
" [0-9]+( \\ .[0-9]*)?[ \\ t]* "
" (millenniums|millennia|millennium|mil|mils| "
" centuries|century|cent|c| "
" decades|decade|dec|decs| "
" years|year|y| "
" months|month|mon| "
" weeks|week|w| "
" days|day|d| "
" hours|hour|hr|hrs|h| "
" minutes|minute|mins|min|m| "
" seconds|second|secs|sec|s))+| "
/* Textual time units plus (dd)* hh[:mm[:ss]] */
" ((([-+]?[ \\ t]+)? "
" [0-9]+( \\ .[0-9]*)?[ \\ t]* "
" (millenniums|millennia|millennium|mil|mils| "
" centuries|century|cent|c| "
" decades|decade|dec|decs| "
" years|year|y| "
" months|month|mon| "
" weeks|week|w| "
" days|day|d))+ "
" ([-+]?[ \\ t]+ "
" ([0-9]+[ \\ t]+)+ " /* dd */
" (([0-9]{1,2}:){0,2}[0-9]{0,2}) " /* hh:[mm:[ss]] */
" )?)) "
" ([ \\ t]+ago)?$ " ,
1 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
2004-03-18 09:34:58 +08:00
}
2002-04-08 09:37:38 +08:00
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
# ifdef HAVE_PQESCAPE
case PG_BYTEA :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
unsigned char * tmp ;
size_t to_len ;
2006-10-07 05:45:10 +08:00
# ifdef HAVE_PQESCAPE_BYTEA_CONN
tmp = PQescapeByteaConn ( pg_link , Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) , & to_len ) ;
# else
2002-04-08 09:37:38 +08:00
tmp = PQescapeBytea ( Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) , & to_len ) ;
2006-10-07 05:45:10 +08:00
# endif
2002-04-08 09:37:38 +08:00
Z_TYPE_P ( new_val ) = IS_STRING ;
Z_STRLEN_P ( new_val ) = to_len - 1 ; /* PQescapeBytea's to_len includes additional '\0' */
Z_STRVAL_P ( new_val ) = emalloc ( to_len ) ;
memcpy ( Z_STRVAL_P ( new_val ) , tmp , to_len ) ;
2006-11-29 23:45:59 +08:00
PQfreemem ( tmp ) ;
2002-04-08 09:37:38 +08:00
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
break ;
case IS_LONG :
ZVAL_LONG ( new_val , Z_LVAL_PP ( val ) ) ;
convert_to_string_ex ( & new_val ) ;
break ;
case IS_DOUBLE :
ZVAL_DOUBLE ( new_val , Z_DVAL_PP ( val ) ) ;
convert_to_string_ex ( & new_val ) ;
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL, string, long or double value for PostgreSQL '%s' (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
# endif
case PG_MACADDR :
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
if ( Z_STRLEN_PP ( val ) = = 0 ) {
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
}
else {
2002-04-19 20:24:14 +08:00
if ( php_pgsql_convert_match ( Z_STRVAL_PP ( val ) , " ^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$ " , 1 TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
err = 1 ;
}
else {
ZVAL_STRING ( new_val , Z_STRVAL_PP ( val ) , 1 ) ;
php_pgsql_add_quotes ( new_val , 1 TSRMLS_CC ) ;
}
}
break ;
case IS_NULL :
ZVAL_STRING ( new_val , " NULL " , 1 ) ;
break ;
default :
err = 1 ;
}
2002-04-23 11:42:26 +08:00
PGSQL_CONV_CHECK_IGNORE ( ) ;
2002-04-08 09:37:38 +08:00
if ( err ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects NULL or string for PostgreSQL %s field (%s) " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
}
break ;
/* bit */
case PG_BIT :
case PG_VARBIT :
2002-04-21 18:37:40 +08:00
/* geometric */
2002-04-08 09:37:38 +08:00
case PG_LINE :
case PG_LSEG :
case PG_POINT :
case PG_BOX :
case PG_PATH :
case PG_POLYGON :
case PG_CIRCLE :
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " PostgreSQL '%s' type (%s) is not supported " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
break ;
case PG_UNKNOWN :
default :
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Unknown or system data type '%s' for '%s' " , Z_STRVAL_PP ( type ) , field ) ;
2002-04-08 09:37:38 +08:00
err = 1 ;
break ;
} /* switch */
if ( err ) {
zval_dtor ( new_val ) ;
FREE_ZVAL ( new_val ) ;
2002-10-19 14:05:16 +08:00
break ; /* break out for() */
2002-04-08 09:37:38 +08:00
}
2002-04-19 20:24:14 +08:00
if ( ! skip_field ) {
/* If field is NULL and HAS DEFAULT, should be skipped */
field = php_addslashes ( field , strlen ( field ) , & new_len , 0 TSRMLS_CC ) ;
add_assoc_zval ( result , field , new_val ) ;
efree ( field ) ;
}
2002-04-08 09:37:38 +08:00
} /* for */
zval_dtor ( meta ) ;
FREE_ZVAL ( meta ) ;
if ( err ) {
/* shouldn't destroy & free zval here */
return FAILURE ;
}
return SUCCESS ;
}
/* }}} */
2002-04-23 11:42:26 +08:00
/* {{{ proto array pg_convert(resource db, string table, array values[, int options])
2002-04-08 09:37:38 +08:00
Check and convert values for PostgreSQL SQL statement */
PHP_FUNCTION ( pg_convert )
{
zval * pgsql_link , * values ;
char * table_name ;
2003-03-07 07:07:28 +08:00
int table_name_len ;
2002-04-23 11:42:26 +08:00
ulong option = 0 ;
2002-04-08 09:37:38 +08:00
PGconn * pg_link ;
int id = - 1 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC ,
2002-04-23 11:42:26 +08:00
" rsa|l " , & pgsql_link , & table_name , & table_name_len , & values , & option ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
return ;
}
2002-04-23 11:42:26 +08:00
if ( option & ~ PGSQL_CONV_OPTS ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid option is specified " ) ;
2002-04-23 11:42:26 +08:00
RETURN_FALSE ;
}
2002-04-08 09:37:38 +08:00
if ( ! table_name_len ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Table name is invalid " ) ;
2002-04-08 09:37:38 +08:00
RETURN_FALSE ;
}
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( php_pgsql_flush_query ( pg_link TSRMLS_CC ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected unhandled result(s) in connection " ) ;
2002-04-08 09:37:38 +08:00
}
array_init ( return_value ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table_name , values , return_value , option TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
}
/* }}} */
2002-04-23 11:42:26 +08:00
static int do_exec ( smart_str * querystr , int expect , PGconn * pg_link , ulong opt TSRMLS_DC )
2002-04-21 17:46:29 +08:00
{
2002-04-23 11:42:26 +08:00
if ( opt & PGSQL_DML_ASYNC ) {
2002-04-21 17:46:29 +08:00
if ( PQsendQuery ( pg_link , querystr - > c ) ) {
return 0 ;
}
}
else {
PGresult * pg_result ;
pg_result = PQexec ( pg_link , querystr - > c ) ;
if ( PQresultStatus ( pg_result ) = = expect ) {
2003-08-15 01:49:08 +08:00
PQclear ( pg_result ) ;
2002-04-21 17:46:29 +08:00
return 0 ;
} else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Failed to execute '%s' " , querystr - > c ) ;
2002-04-21 17:46:29 +08:00
PQclear ( pg_result ) ;
}
}
return - 1 ;
}
2002-04-08 09:37:38 +08:00
/* {{{ php_pgsql_insert
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_insert ( PGconn * pg_link , const char * table , zval * var_array , ulong opt , char * * sql TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
2002-04-08 10:01:45 +08:00
zval * * val , * converted = NULL ;
2002-04-21 17:46:29 +08:00
char buf [ 256 ] ;
char * fld ;
smart_str querystr = { 0 } ;
2003-03-11 04:30:33 +08:00
int key_type , ret = FAILURE ;
uint fld_len ;
2002-04-08 09:37:38 +08:00
ulong num_idx ;
HashPosition pos ;
assert ( pg_link ! = NULL ) ;
assert ( table ! = NULL ) ;
assert ( Z_TYPE_P ( var_array ) = = IS_ARRAY ) ;
2002-04-21 18:44:31 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( var_array ) ) = = 0 ) {
2007-10-04 07:30:46 +08:00
smart_str_appends ( & querystr , " INSERT INTO " ) ;
smart_str_appends ( & querystr , table ) ;
smart_str_appends ( & querystr , " DEFAULT VALUES " ) ;
goto no_values ;
2002-04-21 18:44:31 +08:00
}
2002-04-08 09:37:38 +08:00
/* convert input array if needed */
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-08 09:37:38 +08:00
MAKE_STD_ZVAL ( converted ) ;
array_init ( converted ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table , var_array , converted , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = FAILURE ) {
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
var_array = converted ;
}
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " INSERT INTO " ) ;
smart_str_appends ( & querystr , table ) ;
smart_str_appends ( & querystr , " ( " ) ;
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( var_array ) , & pos ) ;
while ( ( key_type = zend_hash_get_current_key_ex ( Z_ARRVAL_P ( var_array ) , & fld ,
& fld_len , & num_idx , 0 , & pos ) ) ! = HASH_KEY_NON_EXISTANT ) {
2002-04-08 09:37:38 +08:00
if ( key_type = = HASH_KEY_IS_LONG ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects associative array for values to be inserted " ) ;
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
2002-04-22 16:18:19 +08:00
smart_str_appendl ( & querystr , fld , fld_len - 1 ) ;
smart_str_appendc ( & querystr , ' , ' ) ;
2002-04-21 17:46:29 +08:00
zend_hash_move_forward_ex ( Z_ARRVAL_P ( var_array ) , & pos ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-22 16:18:19 +08:00
querystr . len - - ;
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " ) VALUES ( " ) ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
/* make values string */
2002-04-08 09:37:38 +08:00
for ( zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( var_array ) , & pos ) ;
zend_hash_get_current_data_ex ( Z_ARRVAL_P ( var_array ) , ( void * * ) & val , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( var_array ) , & pos ) ) {
2002-04-21 17:46:29 +08:00
/* we can avoid the key_type check here, because we tested it in the other loop */
2002-04-08 09:37:38 +08:00
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
2002-04-21 17:46:29 +08:00
smart_str_appendl ( & querystr , Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) ) ;
2002-04-08 09:37:38 +08:00
break ;
case IS_LONG :
2002-04-21 17:46:29 +08:00
smart_str_append_long ( & querystr , Z_LVAL_PP ( val ) ) ;
2002-04-08 09:37:38 +08:00
break ;
case IS_DOUBLE :
2007-01-05 23:06:55 +08:00
smart_str_appendl ( & querystr , buf , snprintf ( buf , sizeof ( buf ) , " %F " , Z_DVAL_PP ( val ) ) ) ;
2002-04-08 09:37:38 +08:00
break ;
default :
/* should not happen */
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Report this error to php-dev@lists.php.net, type = %d " , Z_TYPE_PP ( val ) ) ;
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
break ;
}
2002-04-21 17:46:29 +08:00
smart_str_appendc ( & querystr , ' , ' ) ;
}
/* Remove the trailing "," */
querystr . len - - ;
smart_str_appends ( & querystr , " ); " ) ;
2007-10-04 07:30:46 +08:00
no_values :
2002-04-21 17:46:29 +08:00
smart_str_0 ( & querystr ) ;
2002-04-23 11:42:26 +08:00
if ( ( opt & ( PGSQL_DML_EXEC | PGSQL_DML_ASYNC ) ) & &
do_exec ( & querystr , PGRES_COMMAND_OK , pg_link , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = 0 ) {
2002-04-21 17:46:29 +08:00
ret = SUCCESS ;
2002-04-23 11:42:26 +08:00
}
else if ( opt & PGSQL_DML_STRING ) {
ret = SUCCESS ;
}
2002-04-21 17:46:29 +08:00
cleanup :
2007-10-04 07:30:46 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) & & converted ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( converted ) ;
FREE_ZVAL ( converted ) ;
}
2002-04-23 11:42:26 +08:00
if ( ret = = SUCCESS & & ( opt & PGSQL_DML_STRING ) ) {
* sql = querystr . c ;
}
else {
smart_str_free ( & querystr ) ;
}
2002-04-08 09:37:38 +08:00
return ret ;
}
/* }}} */
2002-09-30 17:07:57 +08:00
/* {{{ proto mixed pg_insert(resource db, string table, array values[, int options])
2002-04-08 09:37:38 +08:00
Insert values ( filed = > value ) to table */
PHP_FUNCTION ( pg_insert )
{
zval * pgsql_link , * values ;
2002-04-23 11:42:26 +08:00
char * table , * sql = NULL ;
2003-03-07 07:07:28 +08:00
int table_len ;
2002-04-23 11:42:26 +08:00
ulong option = PGSQL_DML_EXEC ;
2002-04-08 09:37:38 +08:00
PGconn * pg_link ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2002-04-23 11:42:26 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa|l " ,
& pgsql_link , & table , & table_len , & values , & option ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
return ;
}
2002-04-23 11:42:26 +08:00
if ( option & ~ ( PGSQL_CONV_OPTS | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_ASYNC | PGSQL_DML_STRING ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid option is specified " ) ;
2002-04-23 11:42:26 +08:00
RETURN_FALSE ;
}
2002-04-08 09:37:38 +08:00
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( php_pgsql_flush_query ( pg_link TSRMLS_CC ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected unhandled result(s) in connection " ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-23 11:42:26 +08:00
if ( php_pgsql_insert ( pg_link , table , values , option , & sql TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
RETURN_FALSE ;
}
2002-04-23 11:42:26 +08:00
if ( option & PGSQL_DML_STRING ) {
RETURN_STRING ( sql , 0 ) ;
}
2002-04-08 09:37:38 +08:00
RETURN_TRUE ;
}
/* }}} */
2002-04-21 17:46:29 +08:00
static inline int build_assignment_string ( smart_str * querystr , HashTable * ht , const char * pad , int pad_len TSRMLS_DC )
{
HashPosition pos ;
2003-03-11 04:30:33 +08:00
uint fld_len ;
2002-04-21 17:46:29 +08:00
int key_type ;
ulong num_idx ;
char * fld ;
char buf [ 256 ] ;
zval * * val ;
for ( zend_hash_internal_pointer_reset_ex ( ht , & pos ) ;
zend_hash_get_current_data_ex ( ht , ( void * * ) & val , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( ht , & pos ) ) {
key_type = zend_hash_get_current_key_ex ( ht , & fld , & fld_len , & num_idx , 0 , & pos ) ;
if ( key_type = = HASH_KEY_IS_LONG ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects associative array for values to be inserted " ) ;
2002-04-21 17:46:29 +08:00
return - 1 ;
}
2002-04-22 16:18:19 +08:00
smart_str_appendl ( querystr , fld , fld_len - 1 ) ;
2002-04-21 17:46:29 +08:00
smart_str_appendc ( querystr , ' = ' ) ;
switch ( Z_TYPE_PP ( val ) ) {
case IS_STRING :
smart_str_appendl ( querystr , Z_STRVAL_PP ( val ) , Z_STRLEN_PP ( val ) ) ;
break ;
case IS_LONG :
smart_str_append_long ( querystr , Z_LVAL_PP ( val ) ) ;
break ;
case IS_DOUBLE :
2007-01-05 23:06:55 +08:00
smart_str_appendl ( querystr , buf , MIN ( snprintf ( buf , sizeof ( buf ) , " %F " , Z_DVAL_PP ( val ) ) , sizeof ( buf ) - 1 ) ) ;
2002-04-21 17:46:29 +08:00
break ;
default :
/* should not happen */
2002-10-19 20:58:41 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Expects scaler values other than NULL. Need to convert? " ) ;
2002-04-21 17:46:29 +08:00
return - 1 ;
}
smart_str_appendl ( querystr , pad , pad_len ) ;
}
querystr - > len - = pad_len ;
return 0 ;
}
2002-04-08 09:37:38 +08:00
/* {{{ php_pgsql_update
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_update ( PGconn * pg_link , const char * table , zval * var_array , zval * ids_array , ulong opt , char * * sql TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
2002-04-21 17:46:29 +08:00
zval * var_converted = NULL , * ids_converted = NULL ;
smart_str querystr = { 0 } ;
2002-04-21 18:28:01 +08:00
int ret = FAILURE ;
2002-04-08 09:37:38 +08:00
assert ( pg_link ! = NULL ) ;
assert ( table ! = NULL ) ;
assert ( Z_TYPE_P ( var_array ) = = IS_ARRAY ) ;
assert ( Z_TYPE_P ( ids_array ) = = IS_ARRAY ) ;
2002-04-23 11:42:26 +08:00
assert ( ! ( opt & ~ ( PGSQL_CONV_OPTS | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_STRING ) ) ) ;
2002-04-08 09:37:38 +08:00
2002-04-21 18:44:31 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( var_array ) ) = = 0
| | zend_hash_num_elements ( Z_ARRVAL_P ( ids_array ) ) = = 0 ) {
return FAILURE ;
}
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-08 09:37:38 +08:00
MAKE_STD_ZVAL ( var_converted ) ;
array_init ( var_converted ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table , var_array , var_converted , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = FAILURE ) {
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
var_array = var_converted ;
MAKE_STD_ZVAL ( ids_converted ) ;
array_init ( ids_converted ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table , ids_array , ids_converted , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = FAILURE ) {
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
ids_array = ids_converted ;
}
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " UPDATE " ) ;
smart_str_appends ( & querystr , table ) ;
smart_str_appends ( & querystr , " SET " ) ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
if ( build_assignment_string ( & querystr , Z_ARRVAL_P ( var_array ) , " , " , 1 TSRMLS_CC ) )
goto cleanup ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " WHERE " ) ;
if ( build_assignment_string ( & querystr , Z_ARRVAL_P ( ids_array ) , " AND " , sizeof ( " AND " ) - 1 TSRMLS_CC ) )
goto cleanup ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
smart_str_appendc ( & querystr , ' ; ' ) ;
smart_str_0 ( & querystr ) ;
2002-04-08 09:37:38 +08:00
2004-01-12 05:18:19 +08:00
if ( ( opt & PGSQL_DML_EXEC ) & & do_exec ( & querystr , PGRES_COMMAND_OK , pg_link , opt TSRMLS_CC ) = = 0 ) {
2002-04-21 17:46:29 +08:00
ret = SUCCESS ;
2004-01-12 05:18:19 +08:00
} else if ( opt & PGSQL_DML_STRING ) {
ret = SUCCESS ;
}
2002-04-21 17:46:29 +08:00
cleanup :
if ( var_converted ) {
zval_dtor ( var_converted ) ;
FREE_ZVAL ( var_converted ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-21 17:46:29 +08:00
if ( ids_converted ) {
zval_dtor ( ids_converted ) ;
FREE_ZVAL ( ids_converted ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-23 11:42:26 +08:00
if ( ret = = SUCCESS & & ( opt & PGSQL_DML_STRING ) ) {
* sql = querystr . c ;
}
else {
smart_str_free ( & querystr ) ;
}
2002-04-08 09:37:38 +08:00
return ret ;
}
/* }}} */
2002-09-30 17:07:57 +08:00
/* {{{ proto mixed pg_update(resource db, string table, array fields, array ids[, int options])
2002-04-08 09:37:38 +08:00
Update table using values ( field = > value ) and ids ( id = > value ) */
PHP_FUNCTION ( pg_update )
{
zval * pgsql_link , * values , * ids ;
2002-04-23 11:42:26 +08:00
char * table , * sql = NULL ;
2003-03-07 07:07:28 +08:00
int table_len ;
2002-04-23 11:42:26 +08:00
ulong option = PGSQL_DML_EXEC ;
2002-04-08 09:37:38 +08:00
PGconn * pg_link ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2002-04-23 11:42:26 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsaa|l " ,
& pgsql_link , & table , & table_len , & values , & ids , & option ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
return ;
}
2002-04-23 11:42:26 +08:00
if ( option & ~ ( PGSQL_CONV_OPTS | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_STRING ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid option is specified " ) ;
2002-04-23 11:42:26 +08:00
RETURN_FALSE ;
}
2002-04-08 09:37:38 +08:00
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( php_pgsql_flush_query ( pg_link TSRMLS_CC ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected unhandled result(s) in connection " ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-23 11:42:26 +08:00
if ( php_pgsql_update ( pg_link , table , values , ids , option , & sql TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
RETURN_FALSE ;
}
2002-04-23 11:42:26 +08:00
if ( option & PGSQL_DML_STRING ) {
RETURN_STRING ( sql , 0 ) ;
}
2002-04-08 09:37:38 +08:00
RETURN_TRUE ;
}
/* }}} */
/* {{{ php_pgsql_delete
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_delete ( PGconn * pg_link , const char * table , zval * ids_array , ulong opt , char * * sql TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
2002-04-21 17:46:29 +08:00
zval * ids_converted = NULL ;
smart_str querystr = { 0 } ;
int ret = FAILURE ;
2002-04-08 09:37:38 +08:00
assert ( pg_link ! = NULL ) ;
assert ( table ! = NULL ) ;
assert ( Z_TYPE_P ( ids_array ) = = IS_ARRAY ) ;
2002-04-23 11:42:26 +08:00
assert ( ! ( opt & ~ ( PGSQL_CONV_FORCE_NULL | PGSQL_DML_EXEC | PGSQL_DML_STRING ) ) ) ;
2002-04-21 18:44:31 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( ids_array ) ) = = 0 ) {
return FAILURE ;
}
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-08 09:37:38 +08:00
MAKE_STD_ZVAL ( ids_converted ) ;
array_init ( ids_converted ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table , ids_array , ids_converted , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = FAILURE ) {
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
ids_array = ids_converted ;
}
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " DELETE FROM " ) ;
smart_str_appends ( & querystr , table ) ;
smart_str_appends ( & querystr , " WHERE " ) ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
if ( build_assignment_string ( & querystr , Z_ARRVAL_P ( ids_array ) , " AND " , sizeof ( " AND " ) - 1 TSRMLS_CC ) )
goto cleanup ;
2002-04-21 18:22:31 +08:00
smart_str_appendc ( & querystr , ' ; ' ) ;
smart_str_0 ( & querystr ) ;
2002-04-21 17:46:29 +08:00
2004-01-12 05:18:19 +08:00
if ( ( opt & PGSQL_DML_EXEC ) & & do_exec ( & querystr , PGRES_COMMAND_OK , pg_link , opt TSRMLS_CC ) = = 0 ) {
2002-04-21 17:46:29 +08:00
ret = SUCCESS ;
2004-01-12 05:18:19 +08:00
} else if ( opt & PGSQL_DML_STRING ) {
ret = SUCCESS ;
}
2002-04-21 17:46:29 +08:00
cleanup :
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( ids_converted ) ;
FREE_ZVAL ( ids_converted ) ;
}
2002-04-23 11:42:26 +08:00
if ( ret = = SUCCESS & & ( opt & PGSQL_DML_STRING ) ) {
* sql = estrdup ( querystr . c ) ;
}
else {
smart_str_free ( & querystr ) ;
}
2002-04-08 09:37:38 +08:00
return ret ;
}
/* }}} */
2002-09-30 17:07:57 +08:00
/* {{{ proto mixed pg_delete(resource db, string table, array ids[, int options])
2002-04-08 09:37:38 +08:00
Delete records has ids ( id = > value ) */
PHP_FUNCTION ( pg_delete )
{
zval * pgsql_link , * ids ;
2002-04-23 11:42:26 +08:00
char * table , * sql = NULL ;
2003-03-07 07:07:28 +08:00
int table_len ;
ulong option = PGSQL_DML_EXEC ;
2002-04-08 09:37:38 +08:00
PGconn * pg_link ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2002-04-23 11:42:26 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa|l " ,
& pgsql_link , & table , & table_len , & ids , & option ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
return ;
}
2002-04-23 11:42:26 +08:00
if ( option & ~ ( PGSQL_CONV_FORCE_NULL | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_STRING ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid option is specified " ) ;
2002-04-23 11:42:26 +08:00
RETURN_FALSE ;
}
2002-04-08 09:37:38 +08:00
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( php_pgsql_flush_query ( pg_link TSRMLS_CC ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected unhandled result(s) in connection " ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-23 11:42:26 +08:00
if ( php_pgsql_delete ( pg_link , table , ids , option , & sql TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
RETURN_FALSE ;
}
2002-04-23 11:42:26 +08:00
if ( option & PGSQL_DML_STRING ) {
RETURN_STRING ( sql , 0 ) ;
}
2002-04-08 09:37:38 +08:00
RETURN_TRUE ;
}
/* }}} */
/* {{{ php_pgsql_result2array
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_result2array ( PGresult * pg_result , zval * ret_array TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
zval * row ;
2007-11-22 08:17:28 +08:00
char * field_name ;
size_t num_fields ;
2002-04-20 10:31:48 +08:00
int pg_numrows , pg_row ;
uint i ;
2002-04-08 09:37:38 +08:00
assert ( Z_TYPE_P ( ret_array ) = = IS_ARRAY ) ;
if ( ( pg_numrows = PQntuples ( pg_result ) ) < = 0 ) {
return FAILURE ;
}
for ( pg_row = 0 ; pg_row < pg_numrows ; pg_row + + ) {
MAKE_STD_ZVAL ( row ) ;
array_init ( row ) ;
add_index_zval ( ret_array , pg_row , row ) ;
for ( i = 0 , num_fields = PQnfields ( pg_result ) ; i < num_fields ; i + + ) {
if ( PQgetisnull ( pg_result , pg_row , i ) ) {
field_name = PQfname ( pg_result , i ) ;
add_assoc_null ( row , field_name ) ;
} else {
2007-11-22 08:17:28 +08:00
char * element = PQgetvalue ( pg_result , pg_row , i ) ;
2002-04-08 09:37:38 +08:00
if ( element ) {
2007-11-22 08:17:28 +08:00
char * data ;
size_t data_len ;
const size_t element_len = strlen ( element ) ;
2002-04-08 09:37:38 +08:00
if ( PG ( magic_quotes_runtime ) ) {
data = php_addslashes ( element , element_len , & data_len , 0 TSRMLS_CC ) ;
} else {
data = safe_estrndup ( element , element_len ) ;
data_len = element_len ;
}
field_name = PQfname ( pg_result , i ) ;
add_assoc_stringl ( row , field_name , data , data_len , 0 ) ;
}
}
}
}
return SUCCESS ;
}
/* }}} */
/* {{{ php_pgsql_select
*/
2003-12-05 09:03:35 +08:00
PHP_PGSQL_API int php_pgsql_select ( PGconn * pg_link , const char * table , zval * ids_array , zval * ret_array , ulong opt , char * * sql TSRMLS_DC )
2002-04-08 09:37:38 +08:00
{
2002-04-21 17:46:29 +08:00
zval * ids_converted = NULL ;
smart_str querystr = { 0 } ;
int ret = FAILURE ;
2002-04-08 09:37:38 +08:00
PGresult * pg_result ;
assert ( pg_link ! = NULL ) ;
assert ( table ! = NULL ) ;
assert ( Z_TYPE_P ( ids_array ) = = IS_ARRAY ) ;
assert ( Z_TYPE_P ( ret_array ) = = IS_ARRAY ) ;
2002-04-23 11:42:26 +08:00
assert ( ! ( opt & ~ ( PGSQL_CONV_OPTS | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_ASYNC | PGSQL_DML_STRING ) ) ) ;
2002-04-21 18:44:31 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( ids_array ) ) = = 0 ) {
return FAILURE ;
}
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-08 09:37:38 +08:00
MAKE_STD_ZVAL ( ids_converted ) ;
array_init ( ids_converted ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_convert ( pg_link , table , ids_array , ids_converted , ( opt & PGSQL_CONV_OPTS ) TSRMLS_CC ) = = FAILURE ) {
2002-04-21 17:46:29 +08:00
goto cleanup ;
2002-04-08 09:37:38 +08:00
}
ids_array = ids_converted ;
}
2002-04-21 17:46:29 +08:00
smart_str_appends ( & querystr , " SELECT * FROM " ) ;
smart_str_appends ( & querystr , table ) ;
smart_str_appends ( & querystr , " WHERE " ) ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
if ( build_assignment_string ( & querystr , Z_ARRVAL_P ( ids_array ) , " AND " , sizeof ( " AND " ) - 1 TSRMLS_CC ) )
goto cleanup ;
2002-04-08 09:37:38 +08:00
2002-04-21 17:46:29 +08:00
smart_str_appendc ( & querystr , ' ; ' ) ;
2002-04-21 18:22:31 +08:00
smart_str_0 ( & querystr ) ;
2002-04-21 17:46:29 +08:00
pg_result = PQexec ( pg_link , querystr . c ) ;
if ( PQresultStatus ( pg_result ) = = PGRES_TUPLES_OK ) {
ret = php_pgsql_result2array ( pg_result , ret_array TSRMLS_CC ) ;
} else {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Failed to execute '%s' " , querystr . c ) ;
2002-04-08 09:37:38 +08:00
}
2003-08-15 01:49:08 +08:00
PQclear ( pg_result ) ;
2002-04-21 17:46:29 +08:00
cleanup :
2002-04-23 11:42:26 +08:00
if ( ! ( opt & PGSQL_DML_NO_CONV ) ) {
2002-04-21 17:46:29 +08:00
zval_dtor ( ids_converted ) ;
FREE_ZVAL ( ids_converted ) ;
2002-04-08 09:37:38 +08:00
}
2002-04-23 11:42:26 +08:00
if ( ret = = SUCCESS & & ( opt & PGSQL_DML_STRING ) ) {
* sql = querystr . c ;
}
else {
smart_str_free ( & querystr ) ;
}
2002-04-08 09:37:38 +08:00
return ret ;
}
/* }}} */
2002-09-30 17:07:57 +08:00
/* {{{ proto mixed pg_select(resource db, string table, array ids[, int options])
2002-04-08 09:37:38 +08:00
Select records that has ids ( id = > value ) */
PHP_FUNCTION ( pg_select )
{
zval * pgsql_link , * ids ;
2002-04-23 11:42:26 +08:00
char * table , * sql = NULL ;
2003-03-07 07:07:28 +08:00
int table_len ;
ulong option = PGSQL_DML_EXEC ;
2002-04-08 09:37:38 +08:00
PGconn * pg_link ;
int id = - 1 , argc = ZEND_NUM_ARGS ( ) ;
2002-04-23 11:42:26 +08:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " rsa|l " ,
& pgsql_link , & table , & table_len , & ids , & option ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
return ;
}
2002-04-23 11:42:26 +08:00
if ( option & ~ ( PGSQL_CONV_FORCE_NULL | PGSQL_DML_NO_CONV | PGSQL_DML_EXEC | PGSQL_DML_ASYNC | PGSQL_DML_STRING ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Invalid option is specified " ) ;
2002-04-23 11:42:26 +08:00
RETURN_FALSE ;
}
2002-04-08 09:37:38 +08:00
ZEND_FETCH_RESOURCE2 ( pg_link , PGconn * , & pgsql_link , id , " PostgreSQL link " , le_link , le_plink ) ;
if ( php_pgsql_flush_query ( pg_link TSRMLS_CC ) ) {
2003-07-21 00:00:40 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Detected unhandled result(s) in connection " ) ;
2002-04-08 09:37:38 +08:00
}
array_init ( return_value ) ;
2002-04-23 11:42:26 +08:00
if ( php_pgsql_select ( pg_link , table , ids , return_value , option , & sql TSRMLS_CC ) = = FAILURE ) {
2002-04-08 09:37:38 +08:00
zval_dtor ( return_value ) ;
RETURN_FALSE ;
}
2002-04-23 11:42:26 +08:00
if ( option & PGSQL_DML_STRING ) {
zval_dtor ( return_value ) ;
RETURN_STRING ( sql , 0 ) ;
}
2002-04-08 09:37:38 +08:00
return ;
}
/* }}} */
1999-04-22 10:48:28 +08:00
# endif
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 21:29:31 +08:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
1999-04-22 10:48:28 +08:00
*/