/** * Check whether internal resource has rows to fetch * * @return boolean */ PHP_METHOD(Phalcon_Mvc_Model_Resultset_Complex, valid){ zval *type = NULL, *result, *row = NULL, *rows, *hydrate_mode, *underscore; zval *empty_str, *active_row = NULL, *columns_types; zval *dirty_state, *column = NULL, *alias = NULL, *source = NULL, *attributes = NULL; zval *column_map = NULL, *row_model = NULL, *attribute = NULL, *column_alias = NULL; zval *column_value = NULL, *keep_snapshots = NULL, *instance = NULL; zval *value = NULL, *sql_alias = NULL, *n_alias = NULL; HashTable *ah0, *ah1; HashPosition hp0, hp1; zval **hd; PHALCON_MM_GROW(); PHALCON_OBS_VAR(type); phalcon_read_property_this(&type, this_ptr, SL("_type"), PH_NOISY_CC); if (zend_is_true(type)) { /** * The result is bigger than 32 rows so it's retrieved one by one */ PHALCON_OBS_VAR(result); phalcon_read_property_this(&result, this_ptr, SL("_result"), PH_NOISY_CC); if (PHALCON_IS_NOT_FALSE(result)) { PHALCON_INIT_VAR(row); PHALCON_CALL_METHOD_PARAMS_1(row, result, "fetch", result); } else { PHALCON_INIT_NVAR(row); ZVAL_BOOL(row, 0); } } else { /** * The full rows are dumped in this_ptr->rows */ PHALCON_OBS_VAR(rows); phalcon_read_property_this(&rows, this_ptr, SL("_rows"), PH_NOISY_CC); if (Z_TYPE_P(rows) == IS_ARRAY) { PHALCON_INIT_NVAR(row); phalcon_array_get_current(row, rows TSRMLS_CC); if (Z_TYPE_P(row) == IS_OBJECT) { phalcon_array_next(rows); } } else { PHALCON_INIT_NVAR(row); ZVAL_BOOL(row, 0); } } /** * Valid records are arrays */ if (Z_TYPE_P(row) == IS_ARRAY || Z_TYPE_P(row) == IS_OBJECT) { /** * The result type=1 so we need to build every row */ if (zend_is_true(type)) { /** * Get current hydration mode */ PHALCON_OBS_VAR(hydrate_mode); phalcon_read_property_this(&hydrate_mode, this_ptr, SL("_hydrateMode"), PH_NOISY_CC); PHALCON_INIT_VAR(underscore); ZVAL_STRING(underscore, "_", 1); PHALCON_INIT_VAR(empty_str); ZVAL_STRING(empty_str, "", 1); /** * Each row in a complex result is a Phalcon\Mvc\Model\Row instance */ switch (phalcon_get_intval(hydrate_mode)) { case 0: PHALCON_INIT_VAR(active_row); object_init_ex(active_row, phalcon_mvc_model_row_ce); break; case 1: PHALCON_INIT_NVAR(active_row); array_init(active_row); break; case 2: PHALCON_INIT_NVAR(active_row); object_init(active_row); break; } /** * Create every record according to the column types */ PHALCON_OBS_VAR(columns_types); phalcon_read_property_this(&columns_types, this_ptr, SL("_columnTypes"), PH_NOISY_CC); /** * Set records as dirty state PERSISTENT by default */ PHALCON_INIT_VAR(dirty_state); ZVAL_LONG(dirty_state, 0); if (!phalcon_is_iterable(columns_types, &ah0, &hp0, 0, 0 TSRMLS_CC)) { return; } while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_FOREACH_KEY(alias, ah0, hp0); PHALCON_GET_FOREACH_VALUE(column); PHALCON_OBS_NVAR(type); phalcon_array_fetch_string(&type, column, SL("type"), PH_NOISY_CC); if (PHALCON_IS_STRING(type, "object")) { /** * Object columns are assigned column by column */ PHALCON_OBS_NVAR(source); phalcon_array_fetch_string(&source, column, SL("column"), PH_NOISY_CC); PHALCON_OBS_NVAR(attributes); phalcon_array_fetch_string(&attributes, column, SL("attributes"), PH_NOISY_CC); PHALCON_OBS_NVAR(column_map); phalcon_array_fetch_string(&column_map, column, SL("columnMap"), PH_NOISY_CC); /** * Assign the values from the _source_attribute notation to its real column name */ PHALCON_INIT_NVAR(row_model); array_init(row_model); if (!phalcon_is_iterable(attributes, &ah1, &hp1, 0, 0 TSRMLS_CC)) { return; } while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) { PHALCON_GET_FOREACH_VALUE(attribute); /** * Columns are supposed to be in the form _table_field */ PHALCON_INIT_NVAR(column_alias); PHALCON_CONCAT_VVVV(column_alias, underscore, source, underscore, attribute); PHALCON_OBS_NVAR(column_value); phalcon_array_fetch(&column_value, row, column_alias, PH_NOISY_CC); phalcon_array_update_zval(&row_model, attribute, &column_value, PH_COPY | PH_SEPARATE TSRMLS_CC); zend_hash_move_forward_ex(ah1, &hp1); } /** * Generate the column value according to the hydration type */ switch (phalcon_get_intval(hydrate_mode)) { case 0: /** * Check if the resultset must keep snapshots */ if (phalcon_array_isset_string(column, SS("keepSnapshots"))) { PHALCON_OBS_NVAR(keep_snapshots); phalcon_array_fetch_string(&keep_snapshots, column, SL("keepSnapshots"), PH_NOISY_CC); } else { PHALCON_INIT_NVAR(keep_snapshots); ZVAL_BOOL(keep_snapshots, 0); } /** * Get the base instance */ PHALCON_OBS_NVAR(instance); phalcon_array_fetch_string(&instance, column, SL("instance"), PH_NOISY_CC); /** * Assign the values to the attributes using a column map */ PHALCON_INIT_NVAR(value); PHALCON_CALL_STATIC_PARAMS_5(value, "phalcon\\mvc\\model", "cloneresultmap", instance, row_model, column_map, dirty_state, keep_snapshots); break; default: /** * Other kinds of hydrations */ PHALCON_INIT_NVAR(value); PHALCON_CALL_STATIC_PARAMS_3(value, "phalcon\\mvc\\model", "cloneresultmaphydrate", row_model, column_map, hydrate_mode); break; } /** * The complete object is assigned to an attribute with the name of the alias or * the model name */ PHALCON_OBS_NVAR(attribute); phalcon_array_fetch_string(&attribute, column, SL("balias"), PH_NOISY_CC); } else { /** * Scalar columns are simply assigned to the result object */ if (phalcon_array_isset_string(column, SS("sqlAlias"))) { PHALCON_OBS_NVAR(sql_alias); phalcon_array_fetch_string(&sql_alias, column, SL("sqlAlias"), PH_NOISY_CC); PHALCON_OBS_NVAR(value); phalcon_array_fetch(&value, row, sql_alias, PH_NOISY_CC); } else { PHALCON_OBS_NVAR(value); phalcon_array_fetch(&value, row, alias, PH_NOISY_CC); } /** * If a 'balias' is defined is not an unnamed scalar */ if (phalcon_array_isset_string(column, SS("balias"))) { PHALCON_CPY_WRT(attribute, alias); } else { PHALCON_INIT_NVAR(n_alias); phalcon_fast_str_replace(n_alias, underscore, empty_str, alias TSRMLS_CC); PHALCON_CPY_WRT(attribute, n_alias); } } /** * Assign the instance according to the hydration type */ switch (phalcon_get_intval(hydrate_mode)) { case 1: phalcon_array_update_zval(&active_row, attribute, &value, PH_COPY | PH_SEPARATE TSRMLS_CC); break; default: phalcon_update_property_zval_zval(active_row, attribute, value TSRMLS_CC); break; } zend_hash_move_forward_ex(ah0, &hp0); } /** * Store the generated row in this_ptr->activeRow to be retrieved by 'current' */ phalcon_update_property_this(this_ptr, SL("_activeRow"), active_row TSRMLS_CC); } else { /** * The row is already built so we just assign it to the activeRow */ phalcon_update_property_this(this_ptr, SL("_activeRow"), row TSRMLS_CC); } RETURN_MM_TRUE; } /** * There are no results to retrieve so we update this_ptr->activeRow as false */ phalcon_update_property_bool(this_ptr, SL("_activeRow"), 0 TSRMLS_CC); RETURN_MM_FALSE; }
/** * Check whether internal resource has rows to fetch * * @return boolean */ PHP_METHOD(Phalcon_Mvc_Model_Resultset_Complex, valid){ zval *type = NULL, *row = NULL, *underscore; zval *empty_str, *active_row = NULL; zval *dirty_state, *column = NULL, *alias = NULL, *source = NULL, *attributes = NULL; zval *column_map = NULL, *row_model = NULL, *attribute = NULL, *column_alias = NULL; zval *column_value = NULL; zval *value = NULL, *sql_alias = NULL, *n_alias = NULL; HashTable *ah0, *ah1; HashPosition hp0, hp1; zval **hd; int i_type, is_partial; PHALCON_MM_GROW(); type = phalcon_fetch_nproperty_this(this_ptr, SL("_type"), PH_NOISY TSRMLS_CC); i_type = (Z_TYPE_P(type) == IS_LONG) ? Z_LVAL_P(type) : phalcon_get_intval(type); is_partial = (i_type == PHALCON_MVC_MODEL_RESULTSET_TYPE_PARTIAL); type = NULL; PHALCON_INIT_VAR(row); if (is_partial) { /** * The result is bigger than 32 rows so it's retrieved one by one */ zval *result = phalcon_fetch_nproperty_this(this_ptr, SL("_result"), PH_NOISY TSRMLS_CC); if (PHALCON_IS_NOT_FALSE(result)) { PHALCON_CALL_METHOD(&row, result, "fetch", result); } else { ZVAL_FALSE(row); } } else { /** * The full rows are dumped in this_ptr->rows */ zval *rows = phalcon_fetch_nproperty_this(this_ptr, SL("_rows"), PH_NOISY TSRMLS_CC); if (Z_TYPE_P(rows) == IS_ARRAY) { phalcon_array_get_current(row, rows); if (Z_TYPE_P(row) == IS_OBJECT) { zend_hash_move_forward(Z_ARRVAL_P(rows)); } } else { ZVAL_FALSE(row); } } /** * Valid records are arrays */ if (Z_TYPE_P(row) == IS_ARRAY || Z_TYPE_P(row) == IS_OBJECT) { /** * The result type=1 so we need to build every row */ if (is_partial) { /** * Get current hydration mode */ zval *hydrate_mode = phalcon_fetch_nproperty_this(this_ptr, SL("_hydrateMode"), PH_NOISY TSRMLS_CC); zval *columns_types = phalcon_fetch_nproperty_this(this_ptr, SL("_columnTypes"), PH_NOISY TSRMLS_CC); int i_hydrate_mode = phalcon_get_intval(hydrate_mode); PHALCON_INIT_VAR(underscore); ZVAL_STRING(underscore, "_", 1); PHALCON_INIT_VAR(empty_str); ZVAL_EMPTY_STRING(empty_str); /** * Each row in a complex result is a Phalcon\Mvc\Model\Row instance */ PHALCON_INIT_VAR(active_row); switch (i_hydrate_mode) { case 0: object_init_ex(active_row, phalcon_mvc_model_row_ce); break; case 1: array_init(active_row); break; case 2: default: object_init(active_row); break; } /** * Create every record according to the column types */ /** * Set records as dirty state PERSISTENT by default */ PHALCON_INIT_VAR(dirty_state); ZVAL_LONG(dirty_state, 0); phalcon_is_iterable(columns_types, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HKEY(alias, ah0, hp0); PHALCON_GET_HVALUE(column); PHALCON_OBS_NVAR(type); phalcon_array_fetch_string(&type, column, SL("type"), PH_NOISY); if (PHALCON_IS_STRING(type, "object")) { /** * Object columns are assigned column by column */ PHALCON_OBS_NVAR(source); phalcon_array_fetch_string(&source, column, SL("column"), PH_NOISY); PHALCON_OBS_NVAR(attributes); phalcon_array_fetch_string(&attributes, column, SL("attributes"), PH_NOISY); PHALCON_OBS_NVAR(column_map); phalcon_array_fetch_string(&column_map, column, SL("columnMap"), PH_NOISY); /** * Assign the values from the _source_attribute notation to its real column name */ PHALCON_INIT_NVAR(row_model); array_init(row_model); phalcon_is_iterable(attributes, &ah1, &hp1, 0, 0); while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) { PHALCON_GET_HVALUE(attribute); /** * Columns are supposed to be in the form _table_field */ PHALCON_INIT_NVAR(column_alias); PHALCON_CONCAT_VVVV(column_alias, underscore, source, underscore, attribute); PHALCON_OBS_NVAR(column_value); phalcon_array_fetch(&column_value, row, column_alias, PH_NOISY); phalcon_array_update_zval(&row_model, attribute, column_value, PH_COPY | PH_SEPARATE); zend_hash_move_forward_ex(ah1, &hp1); } /** * Generate the column value according to the hydration type */ switch (phalcon_get_intval(hydrate_mode)) { case 0: { zval *keep_snapshots, *instance; /** * Check if the resultset must keep snapshots */ if (!phalcon_array_isset_string_fetch(&keep_snapshots, column, SS("keepSnapshots"))) { keep_snapshots = PHALCON_GLOBAL(z_false); } /** * Get the base instance */ if (!phalcon_array_isset_string_fetch(&instance, column, SS("instance"))) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: instance"); instance = PHALCON_GLOBAL(z_null); } /** * Assign the values to the attributes using a column map */ PHALCON_CALL_CE_STATIC(&value, phalcon_mvc_model_ce, "cloneresultmap", instance, row_model, column_map, dirty_state, keep_snapshots); break; } default: /** * Other kinds of hydrations */ PHALCON_CALL_CE_STATIC(&value, phalcon_mvc_model_ce, "cloneresultmaphydrate", row_model, column_map, hydrate_mode); break; } /** * The complete object is assigned to an attribute with the name of the alias or * the model name */ PHALCON_OBS_NVAR(attribute); if (phalcon_array_isset_string(column, SS("balias"))) { phalcon_array_fetch_string(&attribute, column, SL("balias"), PH_NOISY); } } else { /** * Scalar columns are simply assigned to the result object */ if (phalcon_array_isset_string(column, SS("sqlAlias"))) { PHALCON_OBS_NVAR(sql_alias); phalcon_array_fetch_string(&sql_alias, column, SL("sqlAlias"), PH_NOISY); PHALCON_OBS_NVAR(value); phalcon_array_fetch(&value, row, sql_alias, PH_NOISY); } else { PHALCON_OBS_NVAR(value); if (phalcon_array_isset(row, alias)) { phalcon_array_fetch(&value, row, alias, PH_NOISY); } } /** * If a 'balias' is defined is not an unnamed scalar */ if (phalcon_array_isset_string(column, SS("balias"))) { PHALCON_CPY_WRT(attribute, alias); } else { PHALCON_INIT_NVAR(n_alias); phalcon_fast_str_replace(n_alias, underscore, empty_str, alias); PHALCON_CPY_WRT(attribute, n_alias); } assert(attribute != NULL); } /** * Assign the instance according to the hydration type */ if (unlikely(!attribute)) { zend_throw_exception_ex(phalcon_mvc_model_exception_ce, 0 TSRMLS_CC, "Unexpected inconsistency: attribute is NULL"); RETURN_MM(); } switch (phalcon_get_intval(hydrate_mode)) { case 1: phalcon_array_update_zval(&active_row, attribute, value, PH_COPY | PH_SEPARATE); break; default: phalcon_update_property_zval_zval(active_row, attribute, value TSRMLS_CC); break; } zend_hash_move_forward_ex(ah0, &hp0); } /** * Store the generated row in this_ptr->activeRow to be retrieved by 'current' */ phalcon_update_property_this(this_ptr, SL("_activeRow"), active_row TSRMLS_CC); } else { /** * The row is already built so we just assign it to the activeRow */ phalcon_update_property_this(this_ptr, SL("_activeRow"), row TSRMLS_CC); } RETURN_MM_TRUE; } /** * There are no results to retrieve so we update this_ptr->activeRow as false */ phalcon_update_property_bool(this_ptr, SL("_activeRow"), 0 TSRMLS_CC); RETURN_MM_FALSE; }
/** * Check whether internal resource has rows to fetch * * @return boolean */ PHP_METHOD(Phalcon_Mvc_Model_Resultset_Simple, valid){ zval *type, *result = NULL, *row = NULL, *rows = NULL, *dirty_state, *hydrate_mode; zval *keep_snapshots, *column_map, *model, *active_row = NULL; PHALCON_MM_GROW(); PHALCON_OBS_VAR(type); phalcon_read_property(&type, this_ptr, SL("_type"), PH_NOISY_CC); if (zend_is_true(type)) { PHALCON_OBS_VAR(result); phalcon_read_property(&result, this_ptr, SL("_result"), PH_NOISY_CC); if (Z_TYPE_P(result) == IS_OBJECT) { PHALCON_INIT_VAR(row); PHALCON_CALL_METHOD_PARAMS_1(row, result, "fetch", result); } else { PHALCON_INIT_NVAR(row); ZVAL_BOOL(row, 0); } } else { PHALCON_OBS_VAR(rows); phalcon_read_property(&rows, this_ptr, SL("_rows"), PH_NOISY_CC); if (Z_TYPE_P(rows) != IS_ARRAY) { PHALCON_OBS_NVAR(result); phalcon_read_property(&result, this_ptr, SL("_result"), PH_NOISY_CC); if (Z_TYPE_P(result) == IS_OBJECT) { PHALCON_INIT_NVAR(rows); PHALCON_CALL_METHOD(rows, result, "fetchall"); phalcon_update_property_zval(this_ptr, SL("_rows"), rows TSRMLS_CC); } } if (Z_TYPE_P(rows) == IS_ARRAY) { PHALCON_INIT_NVAR(row); phalcon_array_get_current(row, rows TSRMLS_CC); if (PHALCON_IS_NOT_FALSE(row)) { phalcon_array_next(rows); } } else { PHALCON_INIT_NVAR(row); ZVAL_BOOL(row, 0); } } if (Z_TYPE_P(row) != IS_ARRAY) { phalcon_update_property_bool(this_ptr, SL("_activeRow"), 0 TSRMLS_CC); RETURN_MM_FALSE; } /** * Set records as dirty state PERSISTENT by default */ PHALCON_INIT_VAR(dirty_state); ZVAL_LONG(dirty_state, 0); /** * Get current hydration mode */ PHALCON_OBS_VAR(hydrate_mode); phalcon_read_property(&hydrate_mode, this_ptr, SL("_hydrateMode"), PH_NOISY_CC); /** * Tell if the resultset is keeping snapshots */ PHALCON_OBS_VAR(keep_snapshots); phalcon_read_property(&keep_snapshots, this_ptr, SL("_keepSnapshots"), PH_NOISY_CC); /** * Get the resultset column map */ PHALCON_OBS_VAR(column_map); phalcon_read_property(&column_map, this_ptr, SL("_columnMap"), PH_NOISY_CC); /** * Hydrate based on the current hydration */ switch (phalcon_get_intval(hydrate_mode)) { case 0: /** * this_ptr->model is the base entity */ PHALCON_OBS_VAR(model); phalcon_read_property(&model, this_ptr, SL("_model"), PH_NOISY_CC); /** * Performs the standard hydration based on objects */ PHALCON_INIT_VAR(active_row); PHALCON_CALL_STATIC_PARAMS_5(active_row, "phalcon\\mvc\\model", "cloneresultmap", model, row, column_map, dirty_state, keep_snapshots); break; default: /** * Other kinds of hydrations */ PHALCON_INIT_NVAR(active_row); PHALCON_CALL_STATIC_PARAMS_3(active_row, "phalcon\\mvc\\model", "cloneresultmaphydrate", row, column_map, hydrate_mode); break; } phalcon_update_property_zval(this_ptr, SL("_activeRow"), active_row TSRMLS_CC); RETURN_MM_TRUE; }