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
69 changes: 31 additions & 38 deletions SeasClick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,6 +99,9 @@ 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)
Expand All @@ -116,31 +120,11 @@ PHP_MINIT_FUNCTION(SeasClick)
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;
}
/* }}} */
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);

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

/* {{{ 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 @@ -167,9 +151,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 @@ -301,26 +285,29 @@ 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 *single_ret = NULL;
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,10 +339,18 @@ 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)
{
Expand All @@ -364,13 +359,11 @@ PHP_METHOD(SEASCLICK_RES_NAME, select)
for (size_t column = 0; column < block.GetColumnCount(); ++column)
{
string column_name = block.GetColumnName(column);
convertToZval(return_tmp, block[column], row, column_name, 0);
convertToZval(return_tmp, block[column], row, column_name, 0, fetch_mode);
}
add_next_index_zval(return_value, return_tmp);
}
}
);

});
}
catch (const std::exception& e)
{
Expand Down
4 changes: 4 additions & 0 deletions php_SeasClick.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ 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 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
200 changes: 200 additions & 0 deletions tests/011.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
--TEST--
SeasClick Single Column Fetch
--SKIPIF--
<?php if (!extension_loaded("SeasClick")) print "skip"; ?>
--FILE--
<?php
$config = [
"host" => "clickhouse",
"port" => "9000",
"compression" => true,
];

$deleteTable = true;
$client = new SeasClick($config);
$client->execute('CREATE DATABASE IF NOT EXISTS test');

$client->execute("CREATE TABLE IF NOT EXISTS test.single_val_fetch (
tuple_c Tuple(id UInt64, name String),
int64_c UInt64,
string_c String,
array_c Array(Int8),
arraynull_c Array(Nullable(String)),
enum8_c Enum8('One8' = 1, 'Two8' = 2),
enum16_c Enum16('One16' = 1, 'Two16' = 2),
fixedstring_c FixedString(50),
int8null_c Nullable(Int8),
stringnull_c Nullable(String),
enumnull_c Nullable(Enum8('One8' = 1, 'Two8' = 2)),
float32null_c Nullable(Float32),
uuidnull_c Nullable(UUID),
int8_c Int8,
int16_c Int16,
uint8_c UInt8,
uint16_c UInt16,
float32_c Float32,
float64_c Float64,
uuid_c UUID,
uuid2_c UUID,
date_c Date,
datetime_c DateTime
) ENGINE = Memory");

$data = [
[
'tuple_c' => [1, 'one'],
'int64_c' => 1,
'string_c' => 'string_one',
'array_c' => [1, 2, 3],
'arraynull_c' => ['str_array'],
'enum8_c' => 1,
'enum16_c' => 'Two16',
'fixedstring_c' => 'fixedstring_c1',
'int8null_c' => 8,
'stringnull_c' => 'string',
'enumnull_c' => 'One8',
'float32null_c' => 7.77,
'uuidnull_c' => '31249a1b7b0542709f37c609b48a9bb2',
'int8_c' => 8,
'int16_c' => 16,
'uint8_c' => 18,
'uint16_c' => 20,
'float32_c' => 32.32,
'float64_c' => 64.64,
'uuid_c' => '31249a1b-7b05-4270-9f37-c609b48a9bb2',
'uuid2_c' => '31249a1b7b0542709f37c609b48a9bb2',
'date_c' => 1548633600,
'datetime_c' => 1548687925,
],
[
'tuple_c' => [2, 'two'],
'int64_c' => 2,
'string_c' => 'string_two',
'array_c' => [2, 3, 4],
'arraynull_c' => [null],
'enum8_c' => 'Two8',
'enum16_c' => 2,
'fixedstring_c' => 'fixedstring_c2',
'int8null_c' => null,
'stringnull_c' => null,
'enumnull_c' => null,
'float32null_c' => null,
'uuidnull_c' => null,
'int8_c' => 28,
'int16_c' => 216,
'uint8_c' => 218,
'uint16_c' => 220,
'float32_c' => 232.32,
'float64_c' => 264.64,
'uuid_c' => '31249a1b-7b05-4270-9f37-c609b48a9bb2',
'uuid2_c' => null,
'date_c' => 1548547200,
'datetime_c' => 1548513600,
],
];

$fields = array_keys(current($data));

$expected = $data;
$expected[0]['uuid_c'] = '31249a1b7b0542709f37c609b48a9bb2';
$expected[0]['enum8_c'] = 'One8';
$expected[1]['enum16_c'] = 'Two16';
$expected[1]['uuid_c'] = '31249a1b7b0542709f37c609b48a9bb2';
$expected[1]['arraynull_c'] = [null];
$expected[1]['uuid2_c'] = '00000000000000000000000000000000';

$client->insert('test.single_val_fetch', $fields, [array_values($data[0]), array_values($data[1])]);

foreach ($fields as $field) {
for ($i = 1; $i < 3; $i++) {
$result = $client->select("SELECT {$field} FROM test.single_val_fetch WHERE int64_c = {i}", ['i' => $i], SeasClick::FETCH_ONE);
$match = $result === $expected[$i-1][$field] ? 'OK' : 'FAIL';
echo $field, ': ', var_export($result, true), ' - ', var_export($expected[$i - 1][$field], true), ' - ', $match, "\n";
}
}

$client->execute('DROP TABLE test.single_val_fetch');
?>
--EXPECT--
tuple_c: array (
0 => 1,
1 => 'one',
) - array (
0 => 1,
1 => 'one',
) - OK
tuple_c: array (
0 => 2,
1 => 'two',
) - array (
0 => 2,
1 => 'two',
) - OK
int64_c: 1 - 1 - OK
int64_c: 2 - 2 - OK
string_c: 'string_one' - 'string_one' - OK
string_c: 'string_two' - 'string_two' - OK
array_c: array (
0 => 1,
1 => 2,
2 => 3,
) - array (
0 => 1,
1 => 2,
2 => 3,
) - OK
array_c: array (
0 => 2,
1 => 3,
2 => 4,
) - array (
0 => 2,
1 => 3,
2 => 4,
) - OK
arraynull_c: array (
0 => 'str_array',
) - array (
0 => 'str_array',
) - OK
arraynull_c: array (
0 => NULL,
) - array (
0 => NULL,
) - OK
enum8_c: 'One8' - 'One8' - OK
enum8_c: 'Two8' - 'Two8' - OK
enum16_c: 'Two16' - 'Two16' - OK
enum16_c: 'Two16' - 'Two16' - OK
fixedstring_c: 'fixedstring_c1' - 'fixedstring_c1' - OK
fixedstring_c: 'fixedstring_c2' - 'fixedstring_c2' - OK
int8null_c: 8 - 8 - OK
int8null_c: NULL - NULL - OK
stringnull_c: 'string' - 'string' - OK
stringnull_c: NULL - NULL - OK
enumnull_c: 'One8' - 'One8' - OK
enumnull_c: NULL - NULL - OK
float32null_c: 7.77 - 7.77 - OK
float32null_c: NULL - NULL - OK
uuidnull_c: '31249a1b7b0542709f37c609b48a9bb2' - '31249a1b7b0542709f37c609b48a9bb2' - OK
uuidnull_c: NULL - NULL - OK
int8_c: 8 - 8 - OK
int8_c: 28 - 28 - OK
int16_c: 16 - 16 - OK
int16_c: 216 - 216 - OK
uint8_c: 18 - 18 - OK
uint8_c: 218 - 218 - OK
uint16_c: 20 - 20 - OK
uint16_c: 220 - 220 - OK
float32_c: 32.32 - 32.32 - OK
float32_c: 232.32 - 232.32 - OK
float64_c: 64.64 - 64.64 - OK
float64_c: 264.64 - 264.64 - OK
uuid_c: '31249a1b7b0542709f37c609b48a9bb2' - '31249a1b7b0542709f37c609b48a9bb2' - OK
uuid_c: '31249a1b7b0542709f37c609b48a9bb2' - '31249a1b7b0542709f37c609b48a9bb2' - OK
uuid2_c: '31249a1b7b0542709f37c609b48a9bb2' - '31249a1b7b0542709f37c609b48a9bb2' - OK
uuid2_c: '00000000000000000000000000000000' - '00000000000000000000000000000000' - OK
date_c: 1548633600 - 1548633600 - OK
date_c: 1548547200 - 1548547200 - OK
datetime_c: 1548687925 - 1548687925 - OK
datetime_c: 1548513600 - 1548513600 - OK
Loading