<commit_before>
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2013 Phalcon Team (http://www.phalconphp.com)       |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file docs/LICENSE.txt.                        |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to <EMAIL> so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: <NAME> <<EMAIL>>                      |
  |          <NAME> <<EMAIL>>                         |
  +------------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_phalcon.h"
#include "phalcon.h"

#include "Zend/zend_operators.h"
#include "Zend/zend_exceptions.h"
#include "Zend/zend_interfaces.h"

#include "kernel/main.h"
#include "kernel/memory.h"

#include "kernel/array.h"
#include "kernel/object.h"
#include "kernel/exception.h"
#include "kernel/fcall.h"
#include "kernel/concat.h"
#include "kernel/operators.h"
#include "kernel/string.h"
#include "kernel/file.h"
#include "kernel/hash.h"

/**
 * Phalcon\Mvc\Model\Query\Builder
 *
 * Helps to create PHQL queries using an OO interface
 *
 *<code>
 *$resultset = $this->modelsManager->createBuilder()
 *   ->from('Robots')
 *   ->join('RobotsParts')
 *   ->limit(20)
 *   ->orderBy('Robots.name')
 *   ->getQuery()
 *   ->execute();
 *</code>
 */


/**
 * Phalcon\Mvc\Model\Query\Builder initializer
 */
PHALCON_INIT_CLASS(Phalcon_Mvc_Model_Query_Builder){

	PHALCON_REGISTER_CLASS(Phalcon\\Mvc\\Model\\Query, Builder, mvc_model_query_builder, phalcon_mvc_model_query_builder_method_entry, 0);

	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_dependencyInjector"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_columns"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_models"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_joins"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_conditions"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_group"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_having"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_order"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_limit"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_offset"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_forUpdate"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_sharedLock"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_bindParams"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_bindTypes"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_long(phalcon_mvc_model_query_builder_ce, SL("_hiddenParamNumber"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);

	zend_class_implements(phalcon_mvc_model_query_builder_ce TSRMLS_CC, 2, phalcon_mvc_model_query_builderinterface_ce, phalcon_di_injectionawareinterface_ce);

	return SUCCESS;
}

/**
 * Phalcon\Mvc\Model\Query\Builder constructor
 *
 * @param array $params
 * @param Phalcon\DI $dependencyInjector
 */
PHP_METHOD(Phalcon_Mvc_Model_Query_Builder, __construct){

	zval *params = NULL, *dependency_injector = NULL, *conditions = NULL;
	zval *columns, *group_clause, *having_clause;
	zval *order_clause, *limit_clause, *for_update;
	zval *shared_lock;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 0, 2, &params, &dependency_injector);
	
	if (!params) {
		PHALCON_INIT_VAR(params);
	}
	
	if (!dependency_injector) {
		PHALCON_INIT_VAR(dependency_injector);
	}
	
	if (Z_TYPE_P(params) == IS_ARRAY) { 
	
		/** 
		 * Process conditions
		 */
		if (phalcon_array_isset_long(params, 0)) {
			PHALCON_OBS_VAR(conditions);
			phalcon_array_fetch_long(&conditions, params, 0, PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_conditions"), conditions TSRMLS_CC);
		} else {
			if (phalcon_array_isset_string(params, SS("conditions"))) {
				PHALCON_OBS_NVAR(conditions);
				phalcon_array_fetch_string(&conditions, params, SL("conditions"), PH_NOISY);
				phalcon_update_property_this(this_ptr, SL("_conditions"), conditions TSRMLS_CC);
			}
		}
	
		/** 
		 * Assign COLUMNS clause
		 */
		if (phalcon_array_isset_string(params, SS("columns"))) {
			PHALCON_OBS_VAR(columns);
			phalcon_array_fetch_string(&columns, params, SL("columns"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_columns"), columns TSRMLS_CC);
		}
	
		/** 
		 * Assign GROUP clause
		 */
		if (phalcon_array_isset_string(params, SS("group"))) {
			PHALCON_OBS_VAR(group_clause);
			phalcon_array_fetch_string(&group_clause, params, SL("group"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_group"), group_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign HAVING clause
		 */
		if (phalcon_array_isset_string(params, SS("having"))) {
			PHALCON_OBS_VAR(having_clause);
			phalcon_array_fetch_string(&having_clause, params, SL("having"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_group"), having_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign ORDER clause
		 */
		if (phalcon_array_isset_string(params, SS("order"))) {
			PHALCON_OBS_VAR(order_clause);
			phalcon_array_fetch_string(&order_clause, params, SL("order"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_order"), order_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign LIMIT clause
		 */
		if (phalcon_array_isset_string(params, SS("limit"))) {
			PHALCON_OBS_VAR(limit_clause);
			phalcon_array_fetch_string(&limit_clause, params, SL("limit"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_limit"), limit_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign FOR UPDATE clause
		 */
		if (phalcon_array_isset_string(params, SS("for_update"))) {
			PHALCON_OBS_VAR(for_update);
			phalcon_array_fetch_string(&for_update, params, SL("for_update"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_forUpdate"), for_update TSRMLS_CC);
		}
	
		/** 
		 * Assign SHARED LOCK clause
		 */
		if (phalcon_array_isset_string(params, SS("shared_lock"))) {
			PHALCON_OBS_VAR(shared_lock);
			phalcon_array_fetch_string(&shared_lock, params, SL("shared_lock"), PH_NOISY);<commit_msg>Phalcon\Mvc\Query\Builder's constructor sample code in comment + support for offset added (cherry picked from commit a870ae71dec67fd5e143de21d79cc265ae3d2568)<commit_after>
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2013 Phalcon Team (http://www.phalconphp.com)       |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file docs/LICENSE.txt.                        |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to <EMAIL> so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: <NAME> <<EMAIL>>                      |
  |          <NAME> <<EMAIL>>                         |
  +------------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_phalcon.h"
#include "phalcon.h"

#include "Zend/zend_operators.h"
#include "Zend/zend_exceptions.h"
#include "Zend/zend_interfaces.h"

#include "kernel/main.h"
#include "kernel/memory.h"

#include "kernel/array.h"
#include "kernel/object.h"
#include "kernel/exception.h"
#include "kernel/fcall.h"
#include "kernel/concat.h"
#include "kernel/operators.h"
#include "kernel/string.h"
#include "kernel/file.h"
#include "kernel/hash.h"

/**
 * Phalcon\Mvc\Model\Query\Builder
 *
 * Helps to create PHQL queries using an OO interface
 *
 *<code>
 *$resultset = $this->modelsManager->createBuilder()
 *   ->from('Robots')
 *   ->join('RobotsParts')
 *   ->limit(20)
 *   ->orderBy('Robots.name')
 *   ->getQuery()
 *   ->execute();
 *</code>
 */


/**
 * Phalcon\Mvc\Model\Query\Builder initializer
 */
PHALCON_INIT_CLASS(Phalcon_Mvc_Model_Query_Builder){

	PHALCON_REGISTER_CLASS(Phalcon\\Mvc\\Model\\Query, Builder, mvc_model_query_builder, phalcon_mvc_model_query_builder_method_entry, 0);

	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_dependencyInjector"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_columns"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_models"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_joins"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_conditions"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_group"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_having"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_order"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_limit"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_offset"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_forUpdate"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_sharedLock"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_bindParams"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_null(phalcon_mvc_model_query_builder_ce, SL("_bindTypes"), ZEND_ACC_PROTECTED TSRMLS_CC);
	zend_declare_property_long(phalcon_mvc_model_query_builder_ce, SL("_hiddenParamNumber"), 0, ZEND_ACC_PROTECTED TSRMLS_CC);

	zend_class_implements(phalcon_mvc_model_query_builder_ce TSRMLS_CC, 2, phalcon_mvc_model_query_builderinterface_ce, phalcon_di_injectionawareinterface_ce);

	return SUCCESS;
}

/**
 * Phalcon\Mvc\Model\Query\Builder constructor
 *
 *<code>
 * $params = array(
 *    'models'     => array('Users'),
 *    'columns'    => array('id', 'name', 'status'),
 *    'conditions' => "created > '2013-01-01' AND created < '2014-01-01'",
 *    'group'      => array('id', 'name'),
 *    'having'     => "name = 'Kamil'",
 *    'order'      => array('name', 'id'),
 *    'limit'      => 20,
 *    'offset'     => 20,
 *);
 *$queryBuilder = new Phalcon\Mvc\Model\Query\Builder($params);
 *</code> 
 *
 * @param array $params
 * @param Phalcon\DI $dependencyInjector
 */
PHP_METHOD(Phalcon_Mvc_Model_Query_Builder, __construct){

	zval *params = NULL, *dependency_injector = NULL, *conditions = NULL;
	zval *models, *columns, *group_clause;
	zval *having_clause, *order_clause, *limit_clause;
	zval *offset_clause, *for_update, *shared_lock;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 0, 2, &params, &dependency_injector);
	
	if (!params) {
		PHALCON_INIT_VAR(params);
	}
	
	if (!dependency_injector) {
		PHALCON_INIT_VAR(dependency_injector);
	}
	
	if (Z_TYPE_P(params) == IS_ARRAY) { 
	
		/** 
		 * Process conditions
		 */
		if (phalcon_array_isset_long(params, 0)) {
			PHALCON_OBS_VAR(conditions);
			phalcon_array_fetch_long(&conditions, params, 0, PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_conditions"), conditions TSRMLS_CC);
		} else {
			if (phalcon_array_isset_string(params, SS("conditions"))) {
				PHALCON_OBS_NVAR(conditions);
				phalcon_array_fetch_string(&conditions, params, SL("conditions"), PH_NOISY);
				phalcon_update_property_this(this_ptr, SL("_conditions"), conditions TSRMLS_CC);
			}
		}

		/** 
		 * Assign 'FROM' clause
		 */
		if (phalcon_array_isset_string(params, SS("models"))) {
			PHALCON_OBS_VAR(models);
			phalcon_array_fetch_string(&models, params, SL("models"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_models"), models TSRMLS_CC);
		}

		/** 
		 * Assign COLUMNS clause
		 */
		if (phalcon_array_isset_string(params, SS("columns"))) {
			PHALCON_OBS_VAR(columns);
			phalcon_array_fetch_string(&columns, params, SL("columns"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_columns"), columns TSRMLS_CC);
		}
	
		/** 
		 * Assign GROUP clause
		 */
		if (phalcon_array_isset_string(params, SS("group"))) {
			PHALCON_OBS_VAR(group_clause);
			phalcon_array_fetch_string(&group_clause, params, SL("group"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_group"), group_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign HAVING clause
		 */
		if (phalcon_array_isset_string(params, SS("having"))) {
			PHALCON_OBS_VAR(having_clause);
			phalcon_array_fetch_string(&having_clause, params, SL("having"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_group"), having_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign ORDER clause
		 */
		if (phalcon_array_isset_string(params, SS("order"))) {
			PHALCON_OBS_VAR(order_clause);
			phalcon_array_fetch_string(&order_clause, params, SL("order"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_order"), order_clause TSRMLS_CC);
		}
	
		/** 
		 * Assign LIMIT clause
		 */
		if (phalcon_array_isset_string(params, SS("limit"))) {
			PHALCON_OBS_VAR(limit_clause);
			phalcon_array_fetch_string(&limit_clause, params, SL("limit"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_limit"), limit_clause TSRMLS_CC);
		}
		
		/** 
		 * Assign OFFSET clause
		 */
		if (phalcon_array_isset_string(params, SS("offset"))) {
			PHALCON_OBS_VAR(offset_clause);
			phalcon_array_fetch_string(&offset_clause, params, SL("offset"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_offset"), offset_clause TSRMLS_CC);
		}

		/** 
		 * Assign FOR UPDATE clause
		 */
		if (phalcon_array_isset_string(params, SS("for_update"))) {
			PHALCON_OBS_VAR(for_update);
			phalcon_array_fetch_string(&for_update, params, SL("for_update"), PH_NOISY);
			phalcon_update_property_this(this_ptr, SL("_forUpdate"), for_update TSRMLS_CC);
		}
	
		/** 
		 * Assign SHARED LOCK clause
		 */
		if (phalcon_array_isset_string(params, SS("shared_lock"))) {
			PHALCON_OBS_VAR(shared_lock);
			phalcon_array_fetch_string(&shared_lock, params, SL("shared_lock"), PH_NOISY);
{'fraction_non_alphanumeric': 0.16344003578046132, 'fraction_numerical': 0.005047600792281643, 'mean_word_length': 3.8413238478193628, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, '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': '5423185', 'n_tokens_mistral': 6099, 'n_tokens_neox': 5534, 'n_words': 825}