<commit_before>/*
  +----------------------------------------------------------------------+
  | common con pool                                                      |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 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: <NAME>  <<EMAIL>>                            |
  +----------------------------------------------------------------------+
 */

#include "php_connect_pool.h"
#include <ext/standard/info.h>
#include "zend_interfaces.h"
#include "zend_exceptions.h"
#include <sys/time.h>
#include <Zend/zend_types.h>

#include <Zend/zend.h>

#include <ext/spl/spl_iterators.h>

static HashTable pdo_object_table;
static HashTable redis_object_table;
static zval* pdo_stmt = NULL;
extern zval* pdo_object;

cpServerG ConProxyG;
cpServerGS *ConProxyGS = NULL;
cpWorkerG ConProxyWG;

extern sapi_module_struct sapi_module;

static void cp_destory_client(zend_resource *rsrc TSRMLS_DC);

static void pdo_dispatch(zval *args);
static void pdo_proxy_pdo(zval *args);
static void pdo_proxy_stmt(zval *args);
static void cp_add_fail_into_mem(zval *conf, zval *data_source);

#define CP_VERSION "1.4.5"

#define CP_INTERNAL_ERROR_SEND(send_data)\
                                ({         \
                                CP_INTERNAL_SEND_ROW(send_data,CP_SIGEVENT_EXCEPTION)\
                                 })

#define CP_INTERNAL_NORMAL_SEND(send_data)\
                                ({         \
                                 CP_INTERNAL_SEND_ROW(send_data,CP_SIGEVENT_TURE)\
                                 })
#define CP_SEND_EXCEPTION do{zval *str;CP_SEND_EXCEPTION_ARGS(&str);cp_zval_ptr_dtor(&str);}while(0);
#define CP_INTERNAL_NORMAL_SEND_RETURN(send_data)({CP_INTERNAL_NORMAL_SEND(send_data);return CP_TRUE;})
#define CP_INTERNAL_ERROR_SEND_RETURN(send_data) ({ CP_INTERNAL_ERROR_SEND(send_data);return CP_FALSE;})
#define CP_SEND_EXCEPTION_RETURN do{CP_SEND_EXCEPTION;return CP_FALSE;}while(0);
#define CP_TEST_RETURN_TRUE(flag) ({if(flag==CP_CONNECT_PING)return CP_TRUE;})



const zend_function_entry cp_functions[] = {
    PHP_FE(pool_server_create, NULL)
    PHP_FE(pool_server_shutdown, NULL)
    PHP_FE(pool_server_reload, NULL)
    PHP_FE(pool_server_version, NULL)
    PHP_FE_END /* Must be the last line in cp_functions[] */
};

ZEND_BEGIN_ARG_INFO_EX(__call_args, 0, 0, 2)
ZEND_ARG_INFO(0, function_name)
ZEND_ARG_INFO(0, arguments)
ZEND_END_ARG_INFO()

const zend_function_entry pdo_connect_pool_methods[] = {
    PHP_ME(pdo_connect_pool, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(pdo_connect_pool, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(pdo_connect_pool, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool, release, NULL, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

ZEND_BEGIN_ARG_INFO_EX(arginfo_statement_void, 0, 0, 0)
ZEND_END_ARG_INFO()

const zend_function_entry pdo_connect_pool_PDOStatement_methods[] = {
    PHP_ME(pdo_connect_pool_PDOStatement, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, rewind,      arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, next,        arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, current,     arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, key,         arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, valid,       arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

PHP_METHOD(pdo_connect_pool_PDOStatement, rewind)
{
    zval *object = getThis();
    zval *method_ptr, method, *ret_value = NULL, *pos;
    method_ptr = &method;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(object);
    CP_MAKE_STD_ZVAL(pos);
    ZVAL_LONG(pos, 0);
    CP_ZVAL_STRING(method_ptr, "fetchAll", 0);
    //cp_internal_call_user_function(object, method_ptr, &ret_value, NULL);
    if (cp_call_user_function_ex(EG(function_table), &object, method_ptr, &ret_value, 0, NULL, 0, NULL TSRMLS_CC) == FAILURE)
    {
        return ;
    }
        zend_update_property(ce, object, "pos", sizeof("pos") -1, pos TSRMLS_CC);
        zend_update_property(ce, object, "rs", sizeof("rs") - 1, ret_value TSRMLS_CC);

}

PHP_METHOD(pdo_connect_pool_PDOStatement, current)
{
    zval *pos, *rs, *row;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);
    rs = cp_zend_read_property(ce, getThis(), "rs", sizeof("rs") -1, 0 TSRMLS_DC);
    CP_MAKE_STD_ZVAL(row);

    cp_zend_hash_index_find(Z_ARRVAL_P(rs), Z_LVAL_P(pos), (void**) &row);
    RETVAL_ZVAL(row, 1, 1);
}

PHP_METHOD(pdo_connect_pool_PDOStatement, key)
{
    zval *pos;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(),"pos", sizeof("pos") -1, 0 TSRMLS_DC);
    ZVAL_LONG(return_value, Z_LVAL_P(pos));
}

PHP_METHOD(pdo_connect_pool_PDOStatement, next)
{
    zval *pos, *next;
    CP_MAKE_STD_ZVAL(next);
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);

    ZVAL_LONG(next, ++Z_LVAL_P(pos));
    zend_update_property(ce, getThis(),  "pos", sizeof("pos") -1, next TSRMLS_CC);

}

PHP_METHOD(pdo_connect_pool_PDOStatement, valid)
{
    zval *pos, *rs, *row = NULL;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);
    rs = cp_zend_read_property(ce, getThis(), "rs", sizeof("rs") -1, 0 TSRMLS_DC);
    CP_MAKE_STD_ZVAL(row);

    if (cp_zend_hash_index_find(Z_ARRVAL_P(rs), Z_LVAL_P(pos), (void**) &row) == SUCCESS) {
        RETURN_BOOL(1);
    } else {
        RETURN_BOOL(0);
    }

}
const zend_function_entry redis_connect_pool_methods[] = {
    PHP_ME(redis_connect_pool, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(redis_connect_pool, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(redis_connect_pool, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, release, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, select, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, connect, NULL, ZEND_ACC_PUBLIC)
    PHP_MALIAS(redis_connect_pool, pconnect, connect, NULL, ZEND_ACC_PUBLIC) /* pconnect 别名指向connect */
    PHP_FE_END
};


int le_cp_server;
int le_cli_connect_pool;

zend_class_entry pdo_connect_pool_ce;
zend_class_entry *pdo_connect_pool_class_entry_ptr;
<commit_msg>修复statement迭代器 内存泄露<commit_after>/*
  +----------------------------------------------------------------------+
  | common con pool                                                      |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | <EMAIL>.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: <NAME>  <<EMAIL>>                            |
  +----------------------------------------------------------------------+
 */

#include "php_connect_pool.h"
#include <ext/standard/info.h>
#include "zend_interfaces.h"
#include "zend_exceptions.h"
#include <sys/time.h>
#include <Zend/zend_types.h>

#include <Zend/zend.h>

#include <ext/spl/spl_iterators.h>

static HashTable pdo_object_table;
static HashTable redis_object_table;
static zval* pdo_stmt = NULL;
extern zval* pdo_object;

cpServerG ConProxyG;
cpServerGS *ConProxyGS = NULL;
cpWorkerG ConProxyWG;

extern sapi_module_struct sapi_module;

static void cp_destory_client(zend_resource *rsrc TSRMLS_DC);

static void pdo_dispatch(zval *args);
static void pdo_proxy_pdo(zval *args);
static void pdo_proxy_stmt(zval *args);
static void cp_add_fail_into_mem(zval *conf, zval *data_source);

#define CP_VERSION "1.4.5"

#define CP_INTERNAL_ERROR_SEND(send_data)\
                                ({         \
                                CP_INTERNAL_SEND_ROW(send_data,CP_SIGEVENT_EXCEPTION)\
                                 })

#define CP_INTERNAL_NORMAL_SEND(send_data)\
                                ({         \
                                 CP_INTERNAL_SEND_ROW(send_data,CP_SIGEVENT_TURE)\
                                 })
#define CP_SEND_EXCEPTION do{zval *str;CP_SEND_EXCEPTION_ARGS(&str);cp_zval_ptr_dtor(&str);}while(0);
#define CP_INTERNAL_NORMAL_SEND_RETURN(send_data)({CP_INTERNAL_NORMAL_SEND(send_data);return CP_TRUE;})
#define CP_INTERNAL_ERROR_SEND_RETURN(send_data) ({ CP_INTERNAL_ERROR_SEND(send_data);return CP_FALSE;})
#define CP_SEND_EXCEPTION_RETURN do{CP_SEND_EXCEPTION;return CP_FALSE;}while(0);
#define CP_TEST_RETURN_TRUE(flag) ({if(flag==CP_CONNECT_PING)return CP_TRUE;})



const zend_function_entry cp_functions[] = {
    PHP_FE(pool_server_create, NULL)
    PHP_FE(pool_server_shutdown, NULL)
    PHP_FE(pool_server_reload, NULL)
    PHP_FE(pool_server_version, NULL)
    PHP_FE_END /* Must be the last line in cp_functions[] */
};

ZEND_BEGIN_ARG_INFO_EX(__call_args, 0, 0, 2)
ZEND_ARG_INFO(0, function_name)
ZEND_ARG_INFO(0, arguments)
ZEND_END_ARG_INFO()

const zend_function_entry pdo_connect_pool_methods[] = {
    PHP_ME(pdo_connect_pool, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(pdo_connect_pool, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(pdo_connect_pool, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool, release, NULL, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

ZEND_BEGIN_ARG_INFO_EX(arginfo_statement_void, 0, 0, 0)
ZEND_END_ARG_INFO()

const zend_function_entry pdo_connect_pool_PDOStatement_methods[] = {
    PHP_ME(pdo_connect_pool_PDOStatement, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, rewind,      arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, next,        arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, current,     arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, key,         arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_ME(pdo_connect_pool_PDOStatement, valid,       arginfo_statement_void, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

PHP_METHOD(pdo_connect_pool_PDOStatement, rewind)
{
    zval *object = getThis();
    zval *method_ptr, method, *ret_value = NULL, *pos;
    method_ptr = &method;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(object);
   // CP_MAKE_STD_ZVAL(pos);
   // ZVAL_LONG(pos, 0);
    CP_ZVAL_STRING(method_ptr, "fetchAll", 0);
    if (cp_call_user_function_ex(EG(function_table), &object, method_ptr, &ret_value, 0, NULL, 0, NULL TSRMLS_CC) == FAILURE)
    {
        return ;
    }
        zend_update_property_long(ce, object, "pos", sizeof("pos") -1, 0 TSRMLS_CC);
        zend_update_property(ce, object, "rs", sizeof("rs") - 1, ret_value TSRMLS_CC);
        cp_zval_ptr_dtor(&ret_value);

}

PHP_METHOD(pdo_connect_pool_PDOStatement, current)
{
    zval *pos, *rs, *row;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);
    rs = cp_zend_read_property(ce, getThis(), "rs", sizeof("rs") -1, 0 TSRMLS_DC);
    //CP_MAKE_STD_ZVAL(row);

    cp_zend_hash_index_find(Z_ARRVAL_P(rs), Z_LVAL_P(pos), (void**) &row);
    RETVAL_ZVAL(row, 1, 1);
}

PHP_METHOD(pdo_connect_pool_PDOStatement, key)
{
    zval *pos;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(),"pos", sizeof("pos") -1, 0 TSRMLS_DC);
    ZVAL_LONG(return_value, Z_LVAL_P(pos));
}

PHP_METHOD(pdo_connect_pool_PDOStatement, next)
{
    zval *pos, *next;
    //CP_MAKE_STD_ZVAL(next);
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);

    //ZVAL_LONG(next, ++Z_LVAL_P(pos));
    zend_update_property_long(ce, getThis(),  "pos", sizeof("pos") -1,  ++Z_LVAL_P(pos) TSRMLS_CC);

}

PHP_METHOD(pdo_connect_pool_PDOStatement, valid)
{
    zval *pos, *rs, *row = NULL;
    zend_class_entry *ce;
    ce = Z_OBJCE_P(getThis());
    pos = cp_zend_read_property(ce, getThis(), "pos", sizeof("pos") -1, 0 TSRMLS_DC);
    rs = cp_zend_read_property(ce, getThis(), "rs", sizeof("rs") -1, 0 TSRMLS_DC);
    //CP_MAKE_STD_ZVAL(row);

    if (cp_zend_hash_index_find(Z_ARRVAL_P(rs), Z_LVAL_P(pos), (void**) &row) == SUCCESS) {
        RETURN_BOOL(1);
    } else {
        RETURN_BOOL(0);
    }

}
const zend_function_entry redis_connect_pool_methods[] = {
    PHP_ME(redis_connect_pool, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(redis_connect_pool, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
    PHP_ME(redis_connect_pool, __call, __call_args, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, release, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, select, NULL, ZEND_ACC_PUBLIC)
    PHP_ME(redis_connect_pool, connect, NULL, ZEND_ACC_PUBLIC)
    PHP_MALIAS(redis_connect_pool, pconnect, connect, NULL, ZEND_ACC_PUBLIC) /* pconnect 别名指向connect */
    PHP_FE_END
};


int le_cp_server;
int le_cli_connect_pool;

zend_class_entry pdo_connect_pool_ce;
zend_class_entry *pdo_connect_pool_class_entry_ptr;

{'fraction_non_alphanumeric': 0.14431977559607292, 'fraction_numerical': 0.005960729312762973, 'mean_word_length': 3.3558338423946243, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5781033', 'n_tokens_mistral': 5438, 'n_tokens_neox': 5283, 'n_words': 918}