Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Support for Fetch Modes #4

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
121 changes: 74 additions & 47 deletions SeasClick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern "C" {
using namespace clickhouse;
using namespace std;

zend_class_entry *SeasClick_ce;
zend_class_entry *SeasClick_ce, *SeasClickException_ce;
map<int, Client*> clientMap;

#ifdef COMPILE_DL_SEASCLICK
Expand All @@ -64,9 +64,10 @@ ZEND_BEGIN_ARG_INFO_EX(SeasCilck_construct, 0, 0, 1)
ZEND_ARG_INFO(0, connectParames)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(SeasCilck_select, 0, 0, 2)
ZEND_BEGIN_ARG_INFO_EX(SeasCilck_select, 0, 0, 3)
ZEND_ARG_INFO(0, sql)
ZEND_ARG_INFO(0, params)
ZEND_ARG_INFO(0, fetch_mode)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(SeasCilck_insert, 0, 0, 3)
Expand Down Expand Up @@ -98,49 +99,38 @@ const zend_function_entry SeasClick_methods[] =
PHP_FE_END
};

#define REGISTER_SC_CLASS_CONST_LONG(const_name, value) \
zend_declare_class_constant_long(SeasClick_ce, const_name, sizeof(const_name)-1, (zend_long)value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do some compatibility tests, such as zend_long type does not support PHP 5 version

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(SeasClick)
{
zend_class_entry SeasClick;
zend_class_entry SeasClick, SeasClickException;
INIT_CLASS_ENTRY(SeasClick, SEASCLICK_RES_NAME, SeasClick_methods);
INIT_CLASS_ENTRY(SeasClickException, "SeasClickException", NULL);

#if PHP_VERSION_ID >= 70000
SeasClick_ce = zend_register_internal_class_ex(&SeasClick, NULL);
SeasClickException_ce = zend_register_internal_class_ex(&SeasClickException, zend_ce_exception);
#else
SeasClick_ce = zend_register_internal_class_ex(&SeasClick, NULL, NULL TSRMLS_CC);
SeasClickException_ce = zend_register_internal_class_ex(&SeasClickException, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
#endif

zend_declare_property_stringl(SeasClick_ce, "host", strlen("host"), "127.0.0.1", sizeof("127.0.0.1") - 1, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_long(SeasClick_ce, "port", strlen("port"), 9000, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_stringl(SeasClick_ce, "database", strlen("database"), "default", sizeof("default") - 1, ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(SeasClick_ce, "user", strlen("user"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_null(SeasClick_ce, "passwd", strlen("passwd"), ZEND_ACC_PROTECTED TSRMLS_CC);
zend_declare_property_bool(SeasClick_ce, "compression", strlen("compression"), false, ZEND_ACC_PROTECTED TSRMLS_CC);

SeasClick_ce->ce_flags = ZEND_ACC_IMPLICIT_PUBLIC;
return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(SeasClick)
{
return SUCCESS;
}
/* }}} */
REGISTER_SC_CLASS_CONST_LONG("FETCH_ONE", (zend_long)SC_FETCH_ONE);
REGISTER_SC_CLASS_CONST_LONG("FETCH_KEY_PAIR", (zend_long)SC_FETCH_KEY_PAIR);
REGISTER_SC_CLASS_CONST_LONG("DATE_AS_STRINGS", (zend_long)SC_FETCH_DATE_AS_STRINGS);
REGISTER_SC_CLASS_CONST_LONG("FETCH_COLUMN", (zend_long)SC_FETCH_COLUMN);

/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(SeasClick)
{
return SUCCESS;
}
/* }}} */

/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(SeasClick)
{
SeasClick_ce->ce_flags = ZEND_ACC_IMPLICIT_PUBLIC;
return SUCCESS;
}
/* }}} */
Expand All @@ -152,7 +142,7 @@ PHP_MINFO_FUNCTION(SeasClick)
php_info_print_table_start();
php_info_print_table_header(2, "SeasClick support", "enabled");
php_info_print_table_row(2, "Version", PHP_SEASCLICK_VERSION);
php_info_print_table_row(2, "Author", "SeasX Group[email: ahhhh.wang@gmail.com]");
php_info_print_table_row(2, "Author", "SeasX Group[email: ahhhh.wang@gmail.com], Ilia Alshanetsky");
php_info_print_table_end();

DISPLAY_INI_ENTRIES();
Expand All @@ -167,9 +157,9 @@ zend_module_entry SeasClick_module_entry =
SEASCLICK_RES_NAME,
SeasClick_functions,
PHP_MINIT(SeasClick),
PHP_MSHUTDOWN(SeasClick),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove shutdown callback?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't do anything, so recommended approach is to not invlude PHP_MSHUT / PHP_MINIT unless they do something

PHP_RINIT(SeasClick),
PHP_RSHUTDOWN(SeasClick),
NULL,
NULL,
NULL,
PHP_MINFO(SeasClick),
PHP_SEASCLICK_VERSION,
STANDARD_MODULE_PROPERTIES
Expand Down Expand Up @@ -264,7 +254,7 @@ PHP_METHOD(SEASCLICK_RES_NAME, __construct)
}
catch (const std::exception& e)
{
sc_zend_throw_exception(NULL, e.what(), 0 TSRMLS_CC);
sc_zend_throw_exception(SeasClickException_ce, e.what(), 0 TSRMLS_CC);
}

RETURN_TRUE;
Expand Down Expand Up @@ -301,26 +291,28 @@ void getInsertSql(string *sql, char *table_name, zval *columns)
*sql = "INSERT INTO " + (string)table_name + " ( " + fields_section.str() + " ) VALUES";
}

/* {{{ proto array select(string sql, array params)
/* {{{ proto array select(string sql, array params, int mode)
*/
PHP_METHOD(SEASCLICK_RES_NAME, select)
{
char *sql = NULL;
size_t l_sql = 0;
zval* params = NULL;
zend_long fetch_mode = 0;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &sql, &l_sql, &params) == FAILURE)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zl", &sql, &l_sql, &params, &fetch_mode) == FAILURE)
{
return;
}
#else
#undef IS_UNDEF
#define IS_UNDEF Z_EXPECTED_LONG
ZEND_PARSE_PARAMETERS_START(1, 2)
ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_STRING(sql, l_sql)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY(params)
Z_PARAM_LONG(fetch_mode)
ZEND_PARSE_PARAMETERS_END();
#undef IS_UNDEF
#define IS_UNDEF 0
Expand Down Expand Up @@ -352,29 +344,64 @@ PHP_METHOD(SEASCLICK_RES_NAME, select)
int key = Z_OBJ_HANDLE(*getThis());
Client *client = clientMap.at(key);

array_init(return_value);
if (!(fetch_mode & SC_FETCH_ONE)) {
array_init(return_value);
}

client->Select(sql_s, [return_value, fetch_mode](const Block &block) {
if (fetch_mode & SC_FETCH_ONE) {
if (block.GetRowCount() > 0 && block.GetColumnCount() > 0) {
convertToZval(return_value, block[0], 0, "", 0, fetch_mode);
}
return;
}

client->Select(sql_s, [return_value](const Block& block)
{
zval *return_tmp;
for (size_t row = 0; row < block.GetRowCount(); ++row)
{
if (fetch_mode & SC_FETCH_KEY_PAIR) {
if (block.GetColumnCount() < 2) {
throw std::runtime_error("Key pair mode requires at least 2 columns to be present");
}
zval *col1, *col2;
SC_MAKE_STD_ZVAL(col1);
SC_MAKE_STD_ZVAL(col2);

convertToZval(col1, block[0], row, "", 0, fetch_mode|SC_FETCH_ONE);
convertToZval(col2, block[1], row, "", 0, fetch_mode|SC_FETCH_ONE);

if (Z_TYPE_P(col1) == IS_LONG) {
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(col1), col2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compatibility

#define zend_hash_index_update(ht, h, pData, nDataSize, pDest) _zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)

This is the definition of PHP 5 version

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

} else {
convert_to_string(col1);
zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(col1), col2);
}
zval_ptr_dtor(col1);
continue;
}

SC_MAKE_STD_ZVAL(return_tmp);
array_init(return_tmp);
if (!(fetch_mode & SC_FETCH_COLUMN)) {
array_init(return_tmp);
}

for (size_t column = 0; column < block.GetColumnCount(); ++column)
{
string column_name = block.GetColumnName(column);
convertToZval(return_tmp, block[column], row, column_name, 0);
if (fetch_mode & SC_FETCH_COLUMN) {
convertToZval(return_tmp, block[0], row, "", 0, fetch_mode|SC_FETCH_ONE);
break;
} else {
convertToZval(return_tmp, block[column], row, column_name, 0, fetch_mode);
}
}
add_next_index_zval(return_value, return_tmp);
}
}
);

});
}
catch (const std::exception& e)
{
sc_zend_throw_exception(NULL, e.what(), 0 TSRMLS_CC);
sc_zend_throw_exception(SeasClickException_ce, e.what(), 0 TSRMLS_CC);
}
}
/* }}} */
Expand Down Expand Up @@ -476,7 +503,7 @@ PHP_METHOD(SEASCLICK_RES_NAME, insert)
}
catch (const std::exception& e)
{
sc_zend_throw_exception(NULL, e.what(), 0 TSRMLS_CC);
sc_zend_throw_exception(SeasClickException_ce, e.what(), 0 TSRMLS_CC);
}
RETURN_TRUE;
}
Expand Down Expand Up @@ -538,7 +565,7 @@ PHP_METHOD(SEASCLICK_RES_NAME, execute)
}
catch (const std::exception& e)
{
sc_zend_throw_exception(NULL, e.what(), 0 TSRMLS_CC);
sc_zend_throw_exception(SeasClickException_ce, e.what(), 0 TSRMLS_CC);
}
RETURN_TRUE;
}
Expand All @@ -558,7 +585,7 @@ PHP_METHOD(SEASCLICK_RES_NAME, __destruct)
}
catch (const std::exception& e)
{
sc_zend_throw_exception(NULL, e.what(), 0 TSRMLS_CC);
sc_zend_throw_exception(SeasClickException_ce, e.what(), 0 TSRMLS_CC);
}
RETURN_TRUE;
}
Expand Down
5 changes: 5 additions & 0 deletions php_SeasClick.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ typedef unsigned long ulong_t;
#define SEASCLICK_G(v) (SeasClick_globals.v)
#endif

#define SC_FETCH_ONE 1
#define SC_FETCH_KEY_PAIR 2
#define SC_FETCH_DATE_AS_STRINGS 4
#define SC_FETCH_COLUMN 8

#define SEASCLICK_RES_NAME "SeasClick"

#endif /* PHP_SEASCLICK_H */
Expand Down
2 changes: 1 addition & 1 deletion tests/002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ array(2) {
}
["arraynull_c"]=>
array(1) {
["array"]=>
[0]=>
string(6) "string"
}
}
Expand Down
Loading