diff options
| author | Xinchen Hui <laruence@gmail.com> | 2013-12-15 16:55:29 +0800 | 
|---|---|---|
| committer | Xinchen Hui <laruence@gmail.com> | 2013-12-15 16:55:29 +0800 | 
| commit | 5eb8d9d70009c0bf9bfbbf511f2713e64dc8ee83 (patch) | |
| tree | 2480a26e79d85b4b7f2eacb5a2187eb13f029094 /ext/pdo_pgsql/pgsql_driver.c | |
| parent | 10964b78548a5878254f5aa75f4cfdcedb0543bc (diff) | |
| parent | 904721189ff949c67795ec418f04b67951cbd57b (diff) | |
| download | php-git-5eb8d9d70009c0bf9bfbbf511f2713e64dc8ee83.tar.gz | |
Merge branch 'PHP-5.6' of https://git.php.net/push/php-src into PHP-5.6
Diffstat (limited to 'ext/pdo_pgsql/pgsql_driver.c')
| -rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 184 | 
1 files changed, 150 insertions, 34 deletions
| diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 50136430a0..cb89809f02 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -27,8 +27,10 @@  #include "php.h"  #include "php_ini.h"  #include "ext/standard/info.h" +#include "main/php_network.h"  #include "pdo/php_pdo.h"  #include "pdo/php_pdo_driver.h" +#include "pdo/php_pdo_error.h"  #include "ext/standard/file.h"  #undef PACKAGE_BUGREPORT @@ -60,7 +62,7 @@ static char * _pdo_pgsql_trim_message(const char *message, int persistent)  	return tmp;  } -int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *file, int line TSRMLS_DC) /* {{{ */ +int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *msg, const char *file, int line TSRMLS_DC) /* {{{ */  {  	pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;  	pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code; @@ -83,7 +85,10 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *  		strcpy(*pdo_err, sqlstate);  	} -	if (errmsg) { +	if (msg) { +		einfo->errmsg = estrdup(msg); +	} +	else if (errmsg) {  		einfo->errmsg = _pdo_pgsql_trim_message(errmsg, dbh->is_persistent);  	} @@ -91,7 +96,7 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *  		zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s",  				*pdo_err, einfo->errcode, einfo->errmsg);  	} -	 +  	return errcode;  }  /* }}} */ @@ -535,11 +540,13 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR(); +	/* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */  	if (pg_fields) { -		spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	} else { -		spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	}  	/* Obtain db Handle */ @@ -583,7 +590,8 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray)  			query[query_len] = '\0';  			if (PQputCopyData(H->server, query, query_len) != 1) {                          	efree(query); -	                        pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed"); +	                        pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +				PDO_HANDLE_DBH_ERR();          	                RETURN_FALSE;                  	}  			zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); @@ -593,22 +601,25 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray)  		}  		if (PQputCopyEnd(H->server, NULL) != 1) { -			pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed"); +			pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +			PDO_HANDLE_DBH_ERR();  			RETURN_FALSE;  		}  		while ((pgsql_result = PQgetResult(H->server))) {  			if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) { -				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));  				command_failed = 1;  			}  			PQclear(pgsql_result);  		} +		PDO_HANDLE_DBH_ERR();  		RETURN_BOOL(!command_failed);  	} else { +		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));  		PQclear(pgsql_result); -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	}  } @@ -637,17 +648,20 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile)  	/* Obtain db Handler */  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR(); -	stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, FG(default_context)); +	stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE, NULL, FG(default_context));  	if (!stream) { -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file"); +		pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file"); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	} +	/* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */  	if (pg_fields) { -		spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	} else { -		spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	}  	H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -674,8 +688,9 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile)  		while ((buf = php_stream_get_line(stream, NULL, 0, &line_len)) != NULL) {  			if (PQputCopyData(H->server, buf, line_len) != 1) {  	                        efree(buf); -        	                pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed"); +        	                pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);  				php_stream_close(stream); +				PDO_HANDLE_DBH_ERR();  				RETURN_FALSE;  			}  			efree(buf); @@ -683,23 +698,26 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile)  		php_stream_close(stream);  		if (PQputCopyEnd(H->server, NULL) != 1) { -			pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed"); +			pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +			PDO_HANDLE_DBH_ERR();  			RETURN_FALSE;  		}  		while ((pgsql_result = PQgetResult(H->server))) {  			if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) { -				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));  				command_failed = 1;  			}  			PQclear(pgsql_result);  		} +		PDO_HANDLE_DBH_ERR();  		RETURN_BOOL(!command_failed);  	} else { -		PQclear(pgsql_result);  		php_stream_close(stream); -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); +		PQclear(pgsql_result); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	}  } @@ -730,12 +748,14 @@ static PHP_METHOD(PDO, pgsqlCopyToFile)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR();  	H = (pdo_pgsql_db_handle *)dbh->driver_data; -	stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, FG(default_context)); +	stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE, NULL, FG(default_context));  	if (!stream) { -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing"); +		pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing"); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	} @@ -743,10 +763,11 @@ static PHP_METHOD(PDO, pgsqlCopyToFile)  		PQclear(pgsql_result);  	} +	/* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */  	if (pg_fields) { -		spprintf(&query, 0, "COPY %s (%s) TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	} else { -		spprintf(&query, 0, "COPY %s TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	}  	pgsql_result = PQexec(H->server, query);  	efree(query); @@ -767,16 +788,18 @@ static PHP_METHOD(PDO, pgsqlCopyToFile)  				break; /* done */  			} else if (ret > 0) {  				if (php_stream_write(stream, csv, ret) != ret) { -					pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to write to file"); +					pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to write to file");  					PQfreemem(csv);  					php_stream_close(stream); +					PDO_HANDLE_DBH_ERR();  					RETURN_FALSE;  				} else {  					PQfreemem(csv);  				}  			} else { -				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed"); +				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);  				php_stream_close(stream); +				PDO_HANDLE_DBH_ERR();  				RETURN_FALSE;  			}  		} @@ -788,8 +811,9 @@ static PHP_METHOD(PDO, pgsqlCopyToFile)  		RETURN_TRUE;  	} else {  		php_stream_close(stream); +		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));  		PQclear(pgsql_result); -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	}  } @@ -817,6 +841,7 @@ static PHP_METHOD(PDO, pgsqlCopyToArray)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR();  	H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -824,10 +849,11 @@ static PHP_METHOD(PDO, pgsqlCopyToArray)  		PQclear(pgsql_result);  	} +	/* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */  	if (pg_fields) { -		spprintf(&query, 0, "COPY %s (%s) TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	} else { -		spprintf(&query, 0, "COPY %s TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); +		spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));  	}  	pgsql_result = PQexec(H->server, query);  	efree(query); @@ -851,7 +877,8 @@ static PHP_METHOD(PDO, pgsqlCopyToArray)  				add_next_index_stringl(return_value, csv, ret, 1);  				PQfreemem(csv);  			} else { -				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed"); +				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +				PDO_HANDLE_DBH_ERR();  				RETURN_FALSE;  			}  		} @@ -860,8 +887,9 @@ static PHP_METHOD(PDO, pgsqlCopyToArray)  			PQclear(pgsql_result);  		}  	} else { +		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result));  		PQclear(pgsql_result); -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); +		PDO_HANDLE_DBH_ERR();  		RETURN_FALSE;  	}  } @@ -878,6 +906,7 @@ static PHP_METHOD(PDO, pgsqlLOBCreate)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR();  	H = (pdo_pgsql_db_handle *)dbh->driver_data;  	lfd = lo_creat(H->server, INV_READ|INV_WRITE); @@ -887,8 +916,9 @@ static PHP_METHOD(PDO, pgsqlLOBCreate)  		spprintf(&buf, 0, "%lu", (long) lfd);  		RETURN_STRING(buf, 0);  	} -	 -	pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + +	pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +	PDO_HANDLE_DBH_ERR();  	RETURN_FALSE;  }  /* }}} */ @@ -924,6 +954,7 @@ static PHP_METHOD(PDO, pgsqlLOBOpen)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR();  	H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -936,8 +967,10 @@ static PHP_METHOD(PDO, pgsqlLOBOpen)  			return;  		}  	} else { -		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); +		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);  	} + +	PDO_HANDLE_DBH_ERR();  	RETURN_FALSE;  }  /* }}} */ @@ -964,17 +997,98 @@ static PHP_METHOD(PDO, pgsqlLOBUnlink)  	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);  	PDO_CONSTRUCT_CHECK; +	PDO_DBH_CLEAR_ERR();  	H = (pdo_pgsql_db_handle *)dbh->driver_data; -	 +  	if (1 == lo_unlink(H->server, oid)) {  		RETURN_TRUE;  	} -	pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + +	pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); +	PDO_HANDLE_DBH_ERR();  	RETURN_FALSE;  }  /* }}} */ +/* {{{ proto mixed PDO::pgsqlGetNotify([ int $result_type = PDO::FETCH_USE_DEFAULT] [, int $ms_timeout = 0 ]]) +   Get asyncronous notification */ +static PHP_METHOD(PDO, pgsqlGetNotify) +{ +	pdo_dbh_t *dbh; +	pdo_pgsql_db_handle *H; +	long result_type = PDO_FETCH_USE_DEFAULT; +	long ms_timeout = 0; +	PGnotify *pgsql_notify; + +	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", +				&result_type, &ms_timeout)) { +		RETURN_FALSE; +	} + +	dbh = zend_object_store_get_object(getThis() TSRMLS_CC); +	PDO_CONSTRUCT_CHECK; + +	if (result_type == PDO_FETCH_USE_DEFAULT) { +		result_type = dbh->default_fetch_type; +	} + +	if (result_type != PDO_FETCH_BOTH && result_type != PDO_FETCH_ASSOC && result_type != PDO_FETCH_NUM) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); + 		RETURN_FALSE; +	} + +	if (ms_timeout < 0) { +		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid timeout"); + 		RETURN_FALSE; +	} + +	H = (pdo_pgsql_db_handle *)dbh->driver_data; + +	PQconsumeInput(H->server); +	pgsql_notify = PQnotifies(H->server); + +	if (ms_timeout && !pgsql_notify) { +		php_pollfd_for_ms(PQsocket(H->server), PHP_POLLREADABLE, ms_timeout); + +		PQconsumeInput(H->server); +		pgsql_notify = PQnotifies(H->server); +	} + +	if (!pgsql_notify) { +		RETURN_FALSE; +	} + +	array_init(return_value); +	if (result_type == PDO_FETCH_NUM || result_type == PDO_FETCH_BOTH) { +		add_index_string(return_value, 0, pgsql_notify->relname, 1); +		add_index_long(return_value, 1, pgsql_notify->be_pid); +	} +	if (result_type == PDO_FETCH_ASSOC || result_type == PDO_FETCH_BOTH) { +		add_assoc_string(return_value, "message", pgsql_notify->relname, 1); +		add_assoc_long(return_value, "pid", pgsql_notify->be_pid); +	} + +	PQfreemem(pgsql_notify); +} +/* }}} */ + +/* {{{ proto int PDO::pgsqlGetPid() +   Get backend(server) pid */ +static PHP_METHOD(PDO, pgsqlGetPid) +{ +	pdo_dbh_t *dbh; +	pdo_pgsql_db_handle *H; + +	dbh = zend_object_store_get_object(getThis() TSRMLS_CC); +	PDO_CONSTRUCT_CHECK; + +	H = (pdo_pgsql_db_handle *)dbh->driver_data; + +	RETURN_LONG(PQbackendPID(H->server)); +} +/* }}} */ +  static const zend_function_entry dbh_methods[] = {  	PHP_ME(PDO, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC) @@ -984,6 +1098,8 @@ static const zend_function_entry dbh_methods[] = {  	PHP_ME(PDO, pgsqlCopyFromFile, NULL, ZEND_ACC_PUBLIC)  	PHP_ME(PDO, pgsqlCopyToArray, NULL, ZEND_ACC_PUBLIC)  	PHP_ME(PDO, pgsqlCopyToFile, NULL, ZEND_ACC_PUBLIC) +        PHP_ME(PDO, pgsqlGetNotify, NULL, ZEND_ACC_PUBLIC) +        PHP_ME(PDO, pgsqlGetPid, NULL, ZEND_ACC_PUBLIC)  	PHP_FE_END  }; | 
