📄 pgsql.c
字号:
UNREGISTER_INI_ENTRIES(); zend_hash_destroy(&PGG(notices)); return SUCCESS;}/* }}} *//* {{{ PHP_RINIT_FUNCTION */PHP_RINIT_FUNCTION(pgsql){ PGG(default_link)=-1; PGG(num_links) = PGG(num_persistent); return SUCCESS;}/* }}} *//* {{{ PHP_RSHUTDOWN_FUNCTION */PHP_RSHUTDOWN_FUNCTION(pgsql){ /* clean up notice messages */ zend_hash_clean(&PGG(notices)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions TSRMLS_CC); return SUCCESS;}/* }}} *//* {{{ PHP_MINFO_FUNCTION */PHP_MINFO_FUNCTION(pgsql){ char buf[256]; php_info_print_table_start(); php_info_print_table_header(2, "PostgreSQL Support", "enabled");#if HAVE_PG_CONFIG_H php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION);#ifdef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT php_info_print_table_row(2, "Multibyte character support", "enabled");#else php_info_print_table_row(2, "Multibyte character support", "disabled");#endif#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 */ sprintf(buf, "%ld", PGG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); sprintf(buf, "%ld", PGG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_end(); DISPLAY_INI_ENTRIES();}/* }}} *//* {{{ php_pgsql_do_connect */static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){ char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL; PGconn *pgsql; smart_str str = {0}; zval **args[5]; int i, connect_type = 0; if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 5 || zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { WRONG_PARAM_COUNT; } smart_str_appends(&str, "pgsql"); for (i = 0; i < ZEND_NUM_ARGS(); i++) { 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]); } else if (ZEND_NUM_ARGS() == 2 ) { /* Safe to add conntype_option, since 2 args was illegal */ connstring = Z_STRVAL_PP(args[0]); convert_to_long_ex(args[1]); connect_type = Z_LVAL_PP(args[1]); } 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]); break; } } if (persistent && PGG(allow_persistent)) { list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), str.c, str.len+1, (void **) &le)==FAILURE) { /* we don't */ list_entry new_le; if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links)); goto err; } if (PGG(max_persistent)!=-1 && PGG(num_persistent)>=PGG(max_persistent)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open persistent links (%ld)", PGG(num_persistent)); goto err; } /* create the link */ if (connstring) { pgsql=PQconnectdb(connstring); } else { pgsql=PQsetdb(host,port,options,tty,dbname); } if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql) if (pgsql) { PQfinish(pgsql); } goto err; } /* hash it up */ Z_TYPE(new_le) = le_plink; new_le.ptr = pgsql; if (zend_hash_update(&EG(persistent_list), str.c, str.len+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) { goto err; } PGG(num_links)++; PGG(num_persistent)++; } else { /* we do */ if (Z_TYPE_P(le) != le_plink) { RETURN_FALSE; } /* ensure that the link did not die */ if (PGG(auto_reset_persistent) & 1) { /* need to send & get something from backend to make sure we catch CONNECTION_BAD everytime */ PGresult *pg_result; pg_result = PQexec(le->ptr, "select 1"); PQclear(pg_result); } if (PQstatus(le->ptr)==CONNECTION_BAD) { /* the link died */ if (le->ptr == NULL) { if (connstring) { le->ptr=PQconnectdb(connstring); } else { le->ptr=PQsetdb(host,port,options,tty,dbname); } } else { PQreset(le->ptr); } if (le->ptr==NULL || PQstatus(le->ptr)==CONNECTION_BAD) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"PostgreSQL link lost, unable to reconnect"); zend_hash_del(&EG(persistent_list),str.c,str.len+1); goto err; } } pgsql = (PGconn *) le->ptr; } ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink); } else { /* Non persistent connection */ list_entry *index_ptr,new_index_ptr; /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual pgsql link sits. * if it doesn't, open a new pgsql link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (!(connect_type & PGSQL_CONNECT_FORCE_NEW) && zend_hash_find(&EG(regular_list),str.c,str.len+1,(void **) &index_ptr)==SUCCESS) { int type,link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { RETURN_FALSE; } link = (int) index_ptr->ptr; ptr = zend_list_find(link,&type); /* check if the link is still there */ if (ptr && (type==le_link || type==le_plink)) { Z_LVAL_P(return_value) = link; zend_list_addref(link); php_pgsql_set_default_link(link TSRMLS_CC); Z_TYPE_P(return_value) = IS_RESOURCE; goto cleanup; } else { zend_hash_del(&EG(regular_list),str.c,str.len+1); } } if (PGG(max_links)!=-1 && PGG(num_links)>=PGG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create new link. Too many open links (%ld)", PGG(num_links)); goto err; } if (connstring) { pgsql = PQconnectdb(connstring); } else { pgsql = PQsetdb(host,port,options,tty,dbname); } if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); if (pgsql) { PQfinish(pgsql); } goto err; } /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, pgsql, le_link); /* add it to the hash */ new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list),str.c,str.len+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) { goto err; } PGG(num_links)++; } /* set notice processer */ if (! PGG(ignore_notices) && Z_TYPE_P(return_value) == IS_RESOURCE) { PQsetNoticeProcessor(pgsql, _php_pgsql_notice_handler, (void *)Z_RESVAL_P(return_value)); } php_pgsql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC); cleanup: smart_str_free(&str); return; err: smart_str_free(&str); RETURN_FALSE;}/* }}} */#if 0/* {{{ php_pgsql_get_default_link */static int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS){ if (PGG(default_link)==-1) { /* no link opened yet, implicitly open one */ ht = 0; php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); } return PGG(default_link);}/* }}} */#endif/* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database) Open a PostgreSQL connection */PHP_FUNCTION(pg_connect){ php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);}/* }}} *//* {{{ proto resource pg_pconnect(string connection_string | [string host, string port [, string options [, string tty,]]] string database) Open a persistent PostgreSQL connection */PHP_FUNCTION(pg_pconnect){ php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);}/* }}} *//* {{{ proto bool pg_close([resource connection]) Close a PostgreSQL connection */ PHP_FUNCTION(pg_close){ zval **pgsql_link = NULL; int id; PGconn *pgsql; switch (ZEND_NUM_ARGS()) { case 0: id = PGG(default_link); CHECK_DEFAULT_LINK(id); break; case 1: if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) { RETURN_FALSE; } id = -1; break; default: WRONG_PARAM_COUNT; break; } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (id==-1) { /* explicit resource number */ zend_list_delete(Z_RESVAL_PP(pgsql_link)); } if (id!=-1 || (pgsql_link && Z_RESVAL_PP(pgsql_link)==PGG(default_link))) { zend_list_delete(PGG(default_link)); PGG(default_link) = -1; } RETURN_TRUE;}/* }}} */#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/* {{{ php_pgsql_get_link_info */static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type){ zval **pgsql_link = NULL; int id = -1; PGconn *pgsql; char *msgbuf; switch(ZEND_NUM_ARGS()) { case 0: id = PGG(default_link); CHECK_DEFAULT_LINK(id); break; case 1: if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) { RETURN_FALSE; } break; default: WRONG_PARAM_COUNT; break; } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink); switch(entry_type) { case PHP_PG_DBNAME: Z_STRVAL_P(return_value) = PQdb(pgsql); break; case PHP_PG_ERROR_MESSAGE: RETURN_STRING(PQErrorMessageTrim(pgsql, &msgbuf), 0); return; case PHP_PG_OPTIONS: Z_STRVAL_P(return_value) = PQoptions(pgsql); break; case PHP_PG_PORT: Z_STRVAL_P(return_value) = PQport(pgsql); break; case PHP_PG_TTY: Z_STRVAL_P(return_value) = PQtty(pgsql); break; case PHP_PG_HOST: Z_STRVAL_P(return_value) = PQhost(pgsql); break; default: RETURN_FALSE; } 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(""); } Z_TYPE_P(return_value) = IS_STRING;}/* }}} *//* {{{ proto string pg_dbname([resource connection]) Get the database name */ PHP_FUNCTION(pg_dbname){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_DBNAME);}/* }}} *//* {{{ proto string pg_last_error([resource connection]) Get the error message string */PHP_FUNCTION(pg_last_error){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_ERROR_MESSAGE);}/* }}} *//* {{{ proto string pg_options([resource connection]) Get the options associated with the connection */PHP_FUNCTION(pg_options){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_OPTIONS);}/* }}} *//* {{{ proto int pg_port([resource connection]) Return the port number associated with the connection */PHP_FUNCTION(pg_port){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_PORT);}/* }}} *//* {{{ proto string pg_tty([resource connection]) Return the tty name associated with the connection */PHP_FUNCTION(pg_tty){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_TTY);}/* }}} *//* {{{ proto string pg_host([resource connection]) Returns the host name associated with the connection */PHP_FUNCTION(pg_host){ php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_HOST);}/* }}} *//* {{{ proto bool pg_ping(resource connection) Ping database. If connection is bad, try to reconnect. */PHP_FUNCTION(pg_ping){ zval *pgsql_link; int id; PGconn *pgsql; PGresult *res; 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); } if (pgsql_link == NULL && id == -1) { RETURN_FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -