diff --git a/src/Storm/Model/PersistenceStrategy/Db.php b/src/Storm/Model/PersistenceStrategy/Db.php index 59bebfba1f89abbdf39ded75ee235c63ff460a0c..e771b73ddc6f229739aed03dd7ff3b26168b44f9 100644 --- a/src/Storm/Model/PersistenceStrategy/Db.php +++ b/src/Storm/Model/PersistenceStrategy/Db.php @@ -61,10 +61,8 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy return null; } - public function update($data,$id) { - return $this->getTable() - ->update($data, $this->_loader->getIdField(). "='" . $id . "'"); - + public function update($data, $id) { + return $this->getTable()->update($data, $this->_loader->getIdField(). "='" . $id . "'"); } @@ -73,24 +71,33 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy } - public function deleteBy($clauses) { + public function deleteBy($where_or_clauses) { + if (!is_array($where_or_clauses)) + return $this->getTable()->delete($where_or_clauses); + $where = []; - foreach($clauses as $key => $value) { + foreach($where_or_clauses as $key => $value) $where []= $this->_generateWhereClauseForKeyAndValue($key, $value); - } return $this->getTable()->delete(implode(' and ', $where)); } protected function _generateWhereClauseForKeyAndValue($key, $value_or_array) { - if (!is_array($value_or_array)) - return $key ."='" . $value_or_array . "'"; + if ('where' == $key) + return '(' . $value_or_array . ')'; + + $operator = is_array($value_or_array) + ? ' in (?)' + : '=?'; + + return $this->quoteInto($key . $operator, $value_or_array); + } - foreach ($value_or_array as &$value) - $value = '\'' . addslashes($value) . '\''; - return $key . ' in (' . implode(',', $value_or_array) . ')'; + /** @see Zend_Db_Adapter_Abstract::quoteInto() */ + public function quoteInto($text, $value, $type = null, $count = null) { + return $this->getTable()->getAdapter()->quoteInto($text, $value, $type, $count); } @@ -207,4 +214,3 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy $select->where($scope_field . '=?', $scope_value); } } -?> diff --git a/src/Storm/Model/PersistenceStrategy/Volatile.php b/src/Storm/Model/PersistenceStrategy/Volatile.php index 6b1ed40c2df31b50a1a143cf7afeacf081bfa4f9..f9262921224d9e6f3706f096bc967ec493ed490f 100644 --- a/src/Storm/Model/PersistenceStrategy/Volatile.php +++ b/src/Storm/Model/PersistenceStrategy/Volatile.php @@ -287,6 +287,9 @@ class Storm_Model_PersistenceStrategy_Volatile extends Storm_Model_PersistenceS public function deleteBy($clauses) { $delete_count = 0; + if (!is_array($clauses)) + return $delete_count; + foreach($this->getInstancesArray() as $id => $model) { if ($this->containsAllAttributes($model, $clauses)) { unset($this->_instances[$model['id']]); @@ -294,7 +297,6 @@ class Storm_Model_PersistenceStrategy_Volatile extends Storm_Model_PersistenceS } } - return $delete_count; } diff --git a/tests/Storm/Test/LoaderTest.php b/tests/Storm/Test/LoaderTest.php index b28631379fb2cc54ae46fd0ff0cb30dc5149187d..14feb604b628d215b14ea29878e32a2f053ac189 100644 --- a/tests/Storm/Test/LoaderTest.php +++ b/tests/Storm/Test/LoaderTest.php @@ -25,84 +25,96 @@ THE SOFTWARE. */ class Storm_Test_LoaderTest extends Storm_Test_ModelTestCase { - protected $_loader; - protected $_table; + protected $_loader, $_table; public function setUp() { parent::setUp(); - $this->_loader = Storm_Test_Mock_User::getLoader(); - $this->_table = Storm_Test_ObjectWrapper::mock(); - - $this->_loader->setTable($this->_table); + $this->_table = $this->mock(); + $this->_table + ->whenCalled('getAdapter') + ->answers($this->_table) + + ->whenCalled('quoteInto') + ->willDo(function($clause, $value) + { + return str_replace('?', + is_array($value) + ? implode(',', + array_map(function($item){ return "'" . $item . "'"; }, + $value)) + : "'" . $value . "'", + $clause); + }) + ; + + $this->_loader = Storm_Test_Mock_User::getLoader()->setTable($this->_table); } /** @test */ public function findAllShouldAcceptASQLQuery() { - $this->_table - ->whenCalled('getAdapter')->answers($this->_table) - ->whenCalled('fetchAll')->answers(array()); + $this->_table->whenCalled('fetchAll')->answers([]); - $this->assertEquals(array(), $this->_loader->findAll('SELECT * FROM USERS')); - $this->assertEquals('SELECT * FROM USERS', $this->_table->getFirstAttributeForLastCallOn('fetchAll')); + $this->assertEquals([], $this->_loader->findAll('SELECT * FROM USERS')); + $this->assertEquals('SELECT * FROM USERS', + $this->_table->getFirstAttributeForLastCallOn('fetchAll')); } /** @test */ public function countByWithWhereShouldBuildRightSQL() { - $select = Storm_Test_ObjectWrapper::mock() - ->whenCalled('from') - ->with($this->_table, ['count(*) as numberof']) - ->answers(null) + $select = $this->mock() + ->whenCalled('from') + ->with($this->_table, ['count(*) as numberof']) + ->answers(null) - ->whenCalled('where') - ->with('nom like "%zork%"') - ->answers(null) + ->whenCalled('where') + ->with('nom like "%zork%"') + ->answers(null) - ->beStrict(); + ->beStrict(); $this->_table ->whenCalled('select')->answers($select) ->whenCalled('fetchAll') ->with($select) - ->answers(new Zend_Db_Table_Rowset(array('data' => array(array('numberof' => 3))))); - + ->answers(new Zend_Db_Table_Rowset(['data' => [['numberof' => 3]]])); - $this->assertEquals(3, $this->_loader->countBy(array('where' => 'nom like "%zork%"'))); + $this->assertEquals(3, $this->_loader->countBy(['where' => 'nom like "%zork%"'])); } /** @test */ public function withLimitPageFindAllByShouldBuildSql() { $this->_table - ->whenCalled('select')->answers($select = Storm_Test_ObjectWrapper::mock()) + ->whenCalled('select')->answers($select = $this->mock()) ->whenCalled('fetchAll')->with($select) - ->answers(new Zend_Db_Table_Rowset(array())); + ->answers(new Zend_Db_Table_Rowset([])); $select ->whenCalled('where')->answers($select) ->whenCalled('limitPage')->answers($select); - $this->_loader->findAllBy(array('limitPage' => array(2, 80))); + $this->_loader->findAllBy(['limitPage' => [2, 80]]); - $this->assertEquals(array(2, 80), $select->getAttributesForLastCallOn('limitPage')); + $this->assertEquals([2, 80], $select->getAttributesForLastCallOn('limitPage')); } /** @test */ public function withNullValueFindAllByShouldBuildSqlWithIsNullStatement() { - $select = Storm_Test_ObjectWrapper::mock() - ->whenCalled('where') - ->with('parent_id is null') - ->answers(null) + $select = $this->mock() + ->whenCalled('where') + ->with('parent_id is null') + ->answers(null) - ->whenCalled('where') - ->with('cat_id=?', 3) - ->answers(null) + ->whenCalled('where') + ->with('cat_id=?', 3) + ->answers(null) - ->beStrict(); + ->beStrict(); $this->_table ->whenCalled('select')->answers($select) @@ -126,26 +138,25 @@ class Storm_Test_LoaderTest extends Storm_Test_ModelTestCase { ->whenCalled('fetchAll') ->with(null) ->answers(new Zend_Db_Table_Rowset(['data' => [ - ['id' => 29, - 'name' => 'lp'], + ['id' => 29, + 'name' => 'lp'], - ['id' => 34, - 'name' => 'jc'] ] - ])); + ['id' => 34, + 'name' => 'jc'] ] + ])); $this->assertSame($existing_user, $this->_loader->findAll()[1]); } /** @test */ - public function withNegatedValueShouldBeAsExpected() { + public function findAllByNegatedValueShouldGenerateNegatedClauses() { $this->_table - ->whenCalled('select')->answers($select = Storm_Test_ObjectWrapper::mock()) + ->whenCalled('select')->answers($select = $this->mock()) ->whenCalled('fetchAll')->with($select) ->answers(new Zend_Db_Table_Rowset([])); - $select - ->whenCalled('where')->answers($select); + $select->whenCalled('where')->answers($select); $this->_loader->findAllBy(['name not' => 'Harlock']); $this->assertEquals(['name!=?', 'Harlock'], $select->getAttributesForLastCallOn('where')); @@ -161,25 +172,51 @@ class Storm_Test_LoaderTest extends Storm_Test_ModelTestCase { /** @test */ - public function basicDeleteWithNomBondPrenomJamesShouldExpectationSetWhereClauseInDelete() { - $this->_table - ->whenCalled('delete') - ->with('nom=\'bond\' and prenom=\'james\'') - ->answers(10) - ->beStrict(); - $this->assertEquals(10, $this->_loader->basicDeleteBy(['nom' => 'bond', - 'prenom' => 'james'])); + public function basicDeleteWithNomBondPrenomJamesShouldSetWhereClauseWithAnd() { + $this->_table->whenCalled('delete')->answers(10); + $this->_loader->basicDeleteBy(['nom' => 'bond', 'prenom' => 'james']); + + $this->assertEquals('nom=\'bond\' and prenom=\'james\'', + $this->_table->getFirstAttributeForLastCallOn('delete')); } /** @test */ - public function basicDeleteWithNomArrayBondLQuoteupinShouldExpectationSetWhereNomInClauseInDelete() { - $this->_table - ->whenCalled('delete') - ->with("nom in ('bond','l\'upin')") - ->answers(2) - ->beStrict(); - $this->assertEquals(2, $this->_loader->basicDeleteBy(['nom' => ['bond', - 'l\'upin']])); + public function basicDeleteWithNomArrayBondLQuoteUpinShouldSetWhereNomInClause() { + $this->_table->whenCalled('delete')->answers(2); + $this->_loader->basicDeleteBy(['nom' => ['bond', 'l\'upin']]); + + $this->assertEquals("nom in ('bond','l'upin')", + $this->_table->getFirstAttributeForLastCallOn('delete')); + } + + + /** @test */ + public function basicDeleteWithWhereInArrayShouldCallDeleteWithIt() { + $this->_table->whenCalled('delete')->answers(2); + $this->_loader->basicDeleteBy(['where' => 'nom > "22"']); + + $this->assertEquals('(nom > "22")', + $this->_table->getFirstAttributeForLastCallOn('delete')); + } + + + /** @test */ + public function basicDeleteWithWhereInArrayAndNomBondShouldCallDeleteWithItJoinedByAnd() { + $this->_table->whenCalled('delete')->answers(2); + $this->_loader->basicDeleteBy(['where' => 'nom > "22"', + 'nom' => 'bond']); + + $this->assertEquals('(nom > "22") and nom=\'bond\'', + $this->_table->getFirstAttributeForLastCallOn('delete')); + } + + + /** @test */ + public function basicDeleteWithWhereStringShouldCallDeleteWithIt() { + $this->_table->whenCalled('delete')->answers(4); + $this->_loader->basicDeleteBy('nom = "dupont"'); + + $this->assertEquals('nom = "dupont"', $this->_table->getFirstAttributeForLastCallOn('delete')); } } diff --git a/tests/Storm/Test/LoaderVolatileTest.php b/tests/Storm/Test/LoaderVolatileTest.php index 6ba6fb01d2f70e174af4ce3accd9f576f33be8de..aac0b8979cdb1fe329b890ee5a36661813a89c5f 100644 --- a/tests/Storm/Test/LoaderVolatileTest.php +++ b/tests/Storm/Test/LoaderVolatileTest.php @@ -673,6 +673,11 @@ class Storm_Test_LoaderVolatileTest extends Storm_Test_ModelTestCase { $this->assertEquals([ $this->zoe ], Storm_Test_VolatileUser::findAll()); } -} -?> + + /** @test */ + public function basicDeleteByWithWhereStringShouldIgnoreIt() { + Storm_Test_VolatileUser::basicDeleteBy('login = "albert"'); + $this->assertEquals(3, Storm_Test_VolatileUser::count()); + } +}