/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | https://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "ext/pdo/php_pdo.h" #include "ext/pdo/php_pdo_error.h" #include "ext/pdo/php_pdo_driver.h" #include "php_pdo_pgsql.h" #include "php_pdo_pgsql_int.h" #include "pdo_pgsql_arginfo.h" static zend_class_entry *PdoPgsql_ce; /* {{{ pdo_pgsql_deps */ static const zend_module_dep pdo_pgsql_deps[] = { ZEND_MOD_REQUIRED("pdo") ZEND_MOD_END }; /* }}} */ /* {{{ pdo_pgsql_module_entry */ zend_module_entry pdo_pgsql_module_entry = { STANDARD_MODULE_HEADER_EX, NULL, pdo_pgsql_deps, "pdo_pgsql", NULL, PHP_MINIT(pdo_pgsql), PHP_MSHUTDOWN(pdo_pgsql), NULL, NULL, PHP_MINFO(pdo_pgsql), PHP_PDO_PGSQL_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_PDO_PGSQL ZEND_GET_MODULE(pdo_pgsql) #endif /* Escape an identifier for insertion into a text field */ PHP_METHOD(Pdo_Pgsql, escapeIdentifier) { zend_string *from = NULL; char *tmp; pdo_dbh_t *dbh; pdo_pgsql_db_handle *H; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &from) == FAILURE) { RETURN_THROWS(); } dbh = Z_PDO_DBH_P(ZEND_THIS); PDO_CONSTRUCT_CHECK; PDO_DBH_CLEAR_ERR(); /* Obtain db Handle */ H = (pdo_pgsql_db_handle *)dbh->driver_data; if (H->server == NULL) { zend_throw_error(NULL, "PostgreSQL connection has already been closed"); RETURN_THROWS(); } tmp = PQescapeIdentifier(H->server, ZSTR_VAL(from), ZSTR_LEN(from)); if (!tmp) { pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); PDO_HANDLE_DBH_ERR(); RETURN_THROWS(); } RETVAL_STRING(tmp); PQfreemem(tmp); } /* Returns true if the copy worked fine or false if error */ PHP_METHOD(Pdo_Pgsql, copyFromArray) { pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Returns true if the copy worked fine or false if error */ PHP_METHOD(Pdo_Pgsql, copyFromFile) { pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Returns true if the copy worked fine or false if error */ PHP_METHOD(Pdo_Pgsql, copyToFile) { pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Returns true if the copy worked fine or false if error */ PHP_METHOD(Pdo_Pgsql, copyToArray) { pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Creates a new large object, returning its identifier. Must be called inside a transaction. */ PHP_METHOD(Pdo_Pgsql, lobCreate) { pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Opens an existing large object stream. Must be called inside a transaction. */ PHP_METHOD(Pdo_Pgsql, lobOpen) { pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Deletes the large object identified by oid. Must be called inside a transaction. */ PHP_METHOD(Pdo_Pgsql, lobUnlink) { pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Get asynchronous notification */ PHP_METHOD(Pdo_Pgsql, getNotify) { pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Get backend(server) pid */ PHP_METHOD(Pdo_Pgsql, getPid) { pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* Sets a callback to receive DB notices (after client_min_messages has been set */ PHP_METHOD(Pdo_Pgsql, setNoticeCallback) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "F!", &fci, &fcc)) { RETURN_THROWS(); } pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS); PDO_CONSTRUCT_CHECK_WITH_CLEANUP(cleanup); pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; pdo_pgsql_cleanup_notice_callback(H); if (ZEND_FCC_INITIALIZED(fcc)) { H->notice_callback = emalloc(sizeof(zend_fcall_info_cache)); zend_fcc_dup(H->notice_callback, &fcc); } return; cleanup: if (ZEND_FCC_INITIALIZED(fcc)) { zend_fcc_dtor(&fcc); } RETURN_THROWS(); } /* true global environment */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pdo_pgsql) { REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_PREPARES", PDO_PGSQL_ATTR_DISABLE_PREPARES); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_IDLE", (zend_long)PGSQL_TRANSACTION_IDLE); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_ACTIVE", (zend_long)PGSQL_TRANSACTION_ACTIVE); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (zend_long)PGSQL_TRANSACTION_INTRANS); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (zend_long)PGSQL_TRANSACTION_INERROR); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (zend_long)PGSQL_TRANSACTION_UNKNOWN); #ifdef HAVE_PG_RESULT_MEMORY_SIZE REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_RESULT_MEMORY_SIZE", (zend_long)PDO_PGSQL_ATTR_RESULT_MEMORY_SIZE); #endif PdoPgsql_ce = register_class_Pdo_Pgsql(pdo_dbh_ce); PdoPgsql_ce->create_object = pdo_dbh_new; if (php_pdo_register_driver(&pdo_pgsql_driver) == FAILURE) { return FAILURE; } return php_pdo_register_driver_specific_ce(&pdo_pgsql_driver, PdoPgsql_ce); } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(pdo_pgsql) { php_pdo_unregister_driver(&pdo_pgsql_driver); return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(pdo_pgsql) { char buf[16]; php_info_print_table_start(); php_info_print_table_row(2, "PDO Driver for PostgreSQL", "enabled"); pdo_libpq_version(buf, sizeof(buf)); php_info_print_table_row(2, "PostgreSQL(libpq) Version", buf); php_info_print_table_end(); } /* }}} */