From f6103830c3c48612797be9833653e0450fe70609 Mon Sep 17 00:00:00 2001 From: nate Date: Fri, 18 Apr 2008 00:30:32 +0000 Subject: [PATCH] Adding prepared statement support to Model::query(), closes #2069 (thanks Mark Story) git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6687 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/model/datasources/dbo_source.php | 30 ++++++++- cake/tests/cases/libs/model/model.test.php | 72 ++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 909a48d89..7d938f8e6 100644 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -181,7 +181,7 @@ class DboSource extends DataSource { $limit = null; $page = null; $recursive = null; - + if (count($args) == 1) { return $this->fetchAll($args[0]); @@ -254,8 +254,22 @@ class DboSource extends DataSource { } else { if (isset($args[1]) && $args[1] === true) { return $this->fetchAll($args[0], true); + } else if (isset($args[1]) && !is_array($args[1]) ) { + return $this->fetchAll($args[0], false); + } else if (isset($args[1]) && is_array($args[1])) { + $offset = 0; + if (isset($args[2])) { + $cache = $args[2]; + } else { + $cache = true; + } + while ($pos = strpos($args[0], '?', $offset)) { + $offset = $pos; + $value = $this->value(array_shift($args[1])); + $args[0] = substr_replace($args[0], $value, $pos, 1); + } + return $this->fetchAll($args[0], $cache); } - return $this->fetchAll($args[0], false); } } /** @@ -965,6 +979,18 @@ class DboSource extends DataSource { unset($assocFields, $passedFields); } + // $tmpModel =& $model; + // + // if ($linkModel != null) { + // $tmpModel =& $linkModel; + // } + // foreach ($tmpModel->schema() as $field => $info) { + // if ($info['type'] == 'boolean') { + // $this->_booleans[$tmpModel->alias][] = $field; + // } + // } + // unset($tmpModel); + if ($linkModel == null) { return $this->buildStatement( array( diff --git a/cake/tests/cases/libs/model/model.test.php b/cake/tests/cases/libs/model/model.test.php index 39532ccd3..4764262b8 100644 --- a/cake/tests/cases/libs/model/model.test.php +++ b/cake/tests/cases/libs/model/model.test.php @@ -3439,6 +3439,78 @@ class ModelTest extends CakeTestCase { $this->assertEqual($this->Comment->displayField, 'id'); } + + function testOldQuery() { + $this->loadFixtures('Article'); + $this->Article =& new Article(); + + $query = "SELECT title FROM articles WHERE articles.id IN (1,2)"; + $results = $this->Article->query($query); + $this->assertTrue(is_array($results)); + $this->assertEqual(count($results), 2); + + $query = "SELECT title, body FROM articles WHERE articles.id = 1"; + $results = $this->Article->query($query, false); + $db =& ConnectionManager::getDataSource($this->Article->useDbConfig); + $this->assertTrue(!isset($db->_queryCache[$query])); + $this->assertTrue(is_array($results)); + + $query = "SELECT title, id FROM articles WHERE articles.published = 'Y'"; + $results = $this->Article->query($query, true); + $this->assertTrue(isset($db->_queryCache[$query])); + $this->assertTrue(is_array($results)); + } + + function testPreparedQuery() { + $this->loadFixtures('Article'); + $this->Article =& new Article(); + $db =& ConnectionManager::getDataSource($this->Article->useDbConfig); + + $finalQuery = "SELECT title, published FROM articles WHERE articles.id = 1 AND articles.published = 'Y'"; + $query = "SELECT title, published FROM articles WHERE articles.id = ? AND articles.published = ?"; + $params = array(1, 'Y'); + $result = $this->Article->query($query, $params); + $expected = array('0' => array('articles' => array('title' => 'First Article', 'published' => 'Y'))); + $this->assertEqual($result, $expected); + $this->assertTrue(isset($db->_queryCache[$finalQuery])); + + $finalQuery = "SELECT id, created FROM articles WHERE articles.title = 'First Article'"; + $query = "SELECT id, created FROM articles WHERE articles.title = ?"; + $params = array('First Article'); + $result = $this->Article->query($query, $params, false); + $this->assertTrue(is_array($result)); + $this->assertTrue(isset($result[0]['articles'])); + $this->assertFalse(isset($db->_queryCache[$finalQuery])); + + $query = "SELECT title FROM articles WHERE articles.title LIKE ?"; + $params = array('%First%'); + $result = $this->Article->query($query, $params); + $this->assertTrue(is_array($result)); + $this->assertTrue(isset($result[0]['articles']['title'])); + } + + function testParameterMismatch() { + $this->loadFixtures('Article'); + $this->Article =& new Article(); + + $query = "SELECT * FROM articles WHERE articles.published = ? AND articles.user_id = ?"; + $params = array('Y'); + $result = $this->Article->query($query, $params); + $this->assertEqual($result, null); + } + + function testVeryStrangeUseCase() { + $this->loadFixtures('Article'); + $this->Article =& new Article(); + + $query = "SELECT * FROM ? WHERE ? = ? AND ? = ?"; + $param = array('articles', 'articles.user_id', '3', 'articles.published', 'Y'); + $this->expectError(); + ob_start(); + $result = $this->Article->query($query, $param); + ob_end_clean(); + } + function endTest() { ClassRegistry::flush(); }