📄 pgsql.c
字号:
} ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); /* ping connection */ res = PQexec(pgsql, "SELECT 1;"); PQclear(res); /* 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;}/* }}} *//* {{{ proto resource pg_query([resource connection,] string query) Execute a query */PHP_FUNCTION(pg_query){ zval **query, **pgsql_link = NULL; int id = -1; int leftover = 0; PGconn *pgsql; PGresult *pgsql_result; ExecStatusType status; pgsql_result_handle *pg_result; switch(ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &query)==FAILURE) { RETURN_FALSE; } id = PGG(default_link); CHECK_DEFAULT_LINK(id); break; case 2: if (zend_get_parameters_ex(2, &pgsql_link, &query)==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); convert_to_string_ex(query); 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"); } pgsql_result = PQexec(pgsql, Z_STRVAL_PP(query)); if ((PGG(auto_reset_persistent) & 2) && PQstatus(pgsql) != CONNECTION_OK) { PQclear(pgsql_result); PQreset(pgsql); pgsql_result = PQexec(pgsql, Z_STRVAL_PP(query)); } 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; }}/* }}} */#define PHP_PG_NUM_ROWS 1#define PHP_PG_NUM_FIELDS 2#define PHP_PG_CMD_TUPLES 3/* {{{ php_pgsql_get_result_info */static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type){ zval **result; PGresult *pgsql_result; pgsql_result_handle *pg_result; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result)==FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; switch (entry_type) { case PHP_PG_NUM_ROWS: Z_LVAL_P(return_value) = PQntuples(pgsql_result); break; case PHP_PG_NUM_FIELDS: Z_LVAL_P(return_value) = PQnfields(pgsql_result); break; case PHP_PG_CMD_TUPLES:#if HAVE_PQCMDTUPLES Z_LVAL_P(return_value) = atoi(PQcmdTuples(pgsql_result));#else php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported under this build"); Z_LVAL_P(return_value) = 0;#endif break; default: RETURN_FALSE; } Z_TYPE_P(return_value) = IS_LONG;}/* }}} *//* {{{ proto int pg_num_rows(resource result) Return the number of rows in the result */PHP_FUNCTION(pg_num_rows){ php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_ROWS);}/* }}} *//* {{{ proto int pg_num_fields(resource result) Return the number of fields in the result */PHP_FUNCTION(pg_num_fields){ php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_NUM_FIELDS);}/* }}} */#if HAVE_PQCMDTUPLES/* {{{ proto int pg_affected_rows(resource result) Returns the number of affected tuples */PHP_FUNCTION(pg_affected_rows){ php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_CMD_TUPLES);}/* }}} */#endif/* {{{ proto string pg_last_notice(resource connection) Returns the last notice set by the backend */PHP_FUNCTION(pg_last_notice) { zval *pgsql_link; PGconn *pg_link; int id = -1; php_pgsql_notice **notice; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pgsql_link) == FAILURE) { 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 **)¬ice) == FAILURE) { RETURN_FALSE; } RETURN_STRINGL((*notice)->message, (*notice)->len, 1);}/* }}} *//* {{{ get_field_name */static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC){ PGresult *result; smart_str str = {0}; list_entry *field_type; char *ret=NULL; /* try to lookup the type in the resource list */ smart_str_appends(&str, "pgsql_oid_"); smart_str_append_unsigned(&str, oid); smart_str_0(&str); if (zend_hash_find(list,str.c,str.len+1,(void **) &field_type)==SUCCESS) { ret = estrdup((char *)field_type->ptr); } else { /* hash all oid's */ int i,num_rows; int oid_offset,name_offset; char *tmp_oid, *end_ptr, *tmp_name; list_entry new_oid_entry; if ((result = PQexec(pgsql,"select oid,typname from pg_type")) == NULL || PQresultStatus(result) != PGRES_TUPLES_OK) { if (result) { PQclear(result); } smart_str_free(&str); return empty_string; } num_rows = PQntuples(result); oid_offset = PQfnumber(result,"oid"); name_offset = PQfnumber(result,"typname"); for (i=0; i<num_rows; i++) { if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) { continue; } str.len = 0; smart_str_appends(&str, "pgsql_oid_"); smart_str_appends(&str, tmp_oid); smart_str_0(&str); if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) { continue; } Z_TYPE(new_oid_entry) = le_string; new_oid_entry.ptr = estrdup(tmp_name); zend_hash_update(list,str.c,str.len+1,(void *) &new_oid_entry, sizeof(list_entry), NULL); if (!ret && strtoul(tmp_oid, &end_ptr, 10)==oid) { ret = estrdup(tmp_name); } } PQclear(result); } smart_str_free(&str); return ret;}/* }}} */ #define PHP_PG_FIELD_NAME 1#define PHP_PG_FIELD_SIZE 2#define PHP_PG_FIELD_TYPE 3/* {{{ php_pgsql_get_field_info */static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type){ zval **result, **field; PGresult *pgsql_result; pgsql_result_handle *pg_result; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; convert_to_long_ex(field); if (Z_LVAL_PP(field) < 0 || Z_LVAL_PP(field) >= PQnfields(pgsql_result)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } switch (entry_type) { case PHP_PG_FIELD_NAME: Z_STRVAL_P(return_value) = PQfname(pgsql_result, Z_LVAL_PP(field)); 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; break; case PHP_PG_FIELD_SIZE: Z_LVAL_P(return_value) = PQfsize(pgsql_result, Z_LVAL_PP(field)); Z_TYPE_P(return_value) = IS_LONG; break; case PHP_PG_FIELD_TYPE: Z_STRVAL_P(return_value) = get_field_name(pg_result->conn, PQftype(pgsql_result, Z_LVAL_PP(field)), &EG(regular_list) TSRMLS_CC); Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); Z_TYPE_P(return_value) = IS_STRING; break; default: RETURN_FALSE; }}/* }}} *//* {{{ proto string pg_field_name(resource result, int field_number) Returns the name of the field */PHP_FUNCTION(pg_field_name){ php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_NAME);}/* }}} *//* {{{ proto int pg_field_size(resource result, int field_number) Returns the internal size of the field */ PHP_FUNCTION(pg_field_size){ php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_SIZE);}/* }}} *//* {{{ proto string pg_field_type(resource result, int field_number) Returns the type name for the given field */PHP_FUNCTION(pg_field_type){ php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP_PG_FIELD_TYPE);}/* }}} *//* {{{ proto int pg_field_num(resource result, string field_name) Returns the field number of the named field */PHP_FUNCTION(pg_field_num){ zval **result, **field; PGresult *pgsql_result; pgsql_result_handle *pg_result; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; convert_to_string_ex(field); Z_LVAL_P(return_value) = PQfnumber(pgsql_result, Z_STRVAL_PP(field)); Z_TYPE_P(return_value) = IS_LONG;}/* }}} *//* {{{ proto mixed pg_fetch_result(resource result, [int row_number,] mixed field_name) Returns values from a result identifier */PHP_FUNCTION(pg_fetch_result){ zval **result, **row, **field=NULL; PGresult *pgsql_result; pgsql_result_handle *pg_result; int field_offset, pgsql_row; if ((ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &result, &row, &field)==FAILURE) && (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &result, &field)==FAILURE)) { WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; if (ZEND_NUM_ARGS() == 2) { if (pg_result->row < 0) pg_result->row = 0; pgsql_row = pg_result->row; if (pgsql_row >= PQntuples(pgsql_result)) { RETURN_FALSE; } } else { convert_to_long_ex(row); pgsql_row = Z_LVAL_PP(row); if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on PostgreSQL result index %ld", Z_LVAL_PP(row), Z_LVAL_PP(result)); RETURN_FALSE; } } switch(Z_TYPE_PP(field)) { case IS_STRING: field_offset = PQfnumber(pgsql_result, Z_STRVAL_PP(field)); break; default: convert_to_long_ex(field); field_offset = Z_LVAL_PP(field); break; } if (field_offset<0 || field_offset>=PQnfields(pgsql_result)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) { Z_TYPE_P(return_value) = IS_NULL; } else { Z_STRVAL_P(return_value) = PQgetvalue(pgsql_result, pgsql_row, field_offset); Z_STRLEN_P(return_value) = (Z_STRVAL_P(return_value) ? strlen(Z_STRVAL_P(return_value)) : 0); Z_STRVAL_P(return_value) = safe_estrndup(Z_STRVAL_P(return_value),Z_STRLEN_P(return_value)); Z_TYPE_P(return_value) = IS_STRING; }}/* }}} *//* {{{ void php_pgsql_fetch_hash */static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type){ zval **result, **row, **arg3; PGresult *pgsql_result; pgsql_result_handle *pg_result; int i, num_fields, pgsql_row; char *element, *field_name; uint element_len; switch (ZEND_NUM_ARGS()) { case 1: /* pg_fetch_*(result) */ if (zend_get_parameters_ex(1, &result) == FAILURE) { RETURN_FALSE; } break; case 2: /* pg_fetch_*(result, row) */ if (zend_get_parameters_ex(2, &result, &row) == FAILURE) { RETURN_FALSE; } break; case 3: /* pg_fetch_*(result, row, result_type) */ if (zend_get_parameters_ex(3, &result, &row, &arg3) == FAILURE) { RETURN_FALSE; } convert_to_long_ex(arg3); result_type = Z_LVAL_PP(arg3); break; default: WRONG_PARAM_COUNT; break; } if (!(result_type & PGSQL_BOTH)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); RETURN_FALSE; } ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; if (ZEND_NUM_ARGS() == 1) { pgsql_row = pg_result->row; if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { RETURN_FALSE; } pg_result->row++; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -