diff --git a/ext/mvc/model/query/builder.c b/ext/mvc/model/query/builder.c index 76b48436645..180046c0919 100644 --- a/ext/mvc/model/query/builder.c +++ b/ext/mvc/model/query/builder.c @@ -103,6 +103,7 @@ PHALCON_INIT_CLASS(Phalcon_Mvc_Model_Query_Builder){ * 'order' => array('name', 'id'), * 'limit' => 20, * 'offset' => 20, + * // or 'limit' => array(20, 20), *); *$queryBuilder = new Phalcon\Mvc\Model\Query\Builder($params); * @@ -116,6 +117,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query_Builder, __construct){ zval *models, *columns, *group_clause; zval *having_clause, *order_clause, *limit_clause; zval *offset_clause, *for_update, *shared_lock; + zval *limit, *offset; phalcon_fetch_params(0, 0, 2, ¶ms, &dependency_injector); @@ -169,7 +171,17 @@ PHP_METHOD(Phalcon_Mvc_Model_Query_Builder, __construct){ * Assign LIMIT clause */ if (phalcon_array_isset_string_fetch(&limit_clause, params, SS("limit"))) { - phalcon_update_property_this(this_ptr, SL("_limit"), limit_clause TSRMLS_CC); + if (Z_TYPE_P(limit_clause) == IS_ARRAY + && phalcon_array_isset_long_fetch(&limit, limit_clause, 0) + && phalcon_array_isset_long_fetch(&offset, limit_clause, 1) + && phalcon_is_numeric(limit) + && phalcon_is_numeric(offset) + ) { + phalcon_update_property_this(this_ptr, SL("_limit"), limit TSRMLS_CC); + phalcon_update_property_this(this_ptr, SL("_offset"), offset TSRMLS_CC); + } else { + phalcon_update_property_this(this_ptr, SL("_limit"), limit_clause TSRMLS_CC); + } } /** diff --git a/unit-tests/ModelsQueryBuilderTest.php b/unit-tests/ModelsQueryBuilderTest.php index d594f048405..e7c2cf6dbac 100644 --- a/unit-tests/ModelsQueryBuilderTest.php +++ b/unit-tests/ModelsQueryBuilderTest.php @@ -345,4 +345,80 @@ public function testSelectDistinctAll() ->getPhql(); $this->assertEquals($phql, 'SELECT Robots.name FROM [Robots]'); } + + /** + * Test checks passing query params and dependency injector into + * constructor + */ + public function testConstructor() + { + require 'unit-tests/config.db.php'; + if (empty($configMysql)) { + $this->markTestSkipped("Test skipped"); + return; + } + + $di = $this->_getDI(); + + $params = array( + 'models' => 'Robots', + 'columns' => array('id', 'name', 'status'), + 'conditions' => "a > 5", + 'group' => array('type', 'source'), + 'having' => "b < 5", + 'order' => array('name', 'created'), + 'limit' => 10, + 'offset' => 15, + ); + + $builder = new Builder($params, $di); + + $expectedPhql = "SELECT id, name, status FROM [Robots] " + . "WHERE a > 5 GROUP BY [type], [source] " + . "HAVING b < 5 ORDER BY [name], [created] " + . "LIMIT 10 OFFSET 15"; + + $this->assertEquals($expectedPhql, $builder->getPhql()); + $this->assertEquals($di, $builder->getDI()); + } + + /** + * Test checks passing 'limit'/'offset' query param into constructor. + * limit key can take: + * - signle numeric value + * - array of 2 values (limit, offset) + */ + public function testConstructorLimit() + { + require 'unit-tests/config.db.php'; + if (empty($configMysql)) { + $this->markTestSkipped("Test skipped"); + return; + } + + // separate limit and offset + + $params = array( + 'models' => 'Robots', + 'limit' => 10, + 'offset' => 15, + ); + + $builderLimitAndOffset = new Builder($params); + + // separate limit with offset + + $params = array( + 'models' => 'Robots', + 'limit' => array(10, 15), + ); + + $builderLimitWithOffset = new Builder($params); + + $expectedPhql = "SELECT [Robots].* FROM [Robots] " + . "LIMIT 10 OFFSET 15"; + + $this->assertEquals($expectedPhql, $builderLimitAndOffset->getPhql()); + $this->assertEquals($expectedPhql, $builderLimitWithOffset->getPhql()); + } }