Browse files

DC-841 Doctrine_Connection_Mssql::replaceBoundParamsWithInlineValuesI…

…nQuery regex failing to replace all '?' instances
  • Loading branch information...
1 parent 108be3f commit b7ea0eb59f611c07f88154e08eaa95b2337b67af @estahn estahn committed with jwage Sep 2, 2010
Showing with 122 additions and 14 deletions.
  1. +7 −9 lib/Doctrine/Connection/Mssql.php
  2. +1 −1 tests/Ticket/DC840TestCase.php
  3. +114 −4 tests/Ticket/DC841TestCase.php
View
16 lib/Doctrine/Connection/Mssql.php
@@ -400,16 +400,14 @@ public function exec($query, array $params = array())
*/
protected function replaceBoundParamsWithInlineValuesInQuery($query, array $params) {
- foreach ($params as $key => $value) {
- $value = is_null($value) ? 'NULL' : $this->quote($value);
-
- // Supported:
- // * all variations of =, <, >
- // * LIKE
- $re = '/(?<=WHERE)(\s+.+?\s+([=<>]+|LIKE)\s+)(\?)/';
-
- $query = preg_replace($re, "\\1 {$value}", $query, 1);
+ foreach($params as $key => $value) {
+ $re = '/(?<=WHERE|VALUES|SET|JOIN)(.*?)(\?)/';
+ $query = preg_replace($re, "\\1##{$key}##", $query, 1);
}
+
+ $replacement = 'is_null($value) ? \'NULL\' : $this->quote($params[\\1])';
+ $query = preg_replace('/##(\d+)##/e', $replacement, $query);
+
return $query;
}
View
2 tests/Ticket/DC840TestCase.php
@@ -60,7 +60,7 @@ public function testTest()
;
$q->execute();
- $expected = "SELECT [t].[id] AS [t__id] FROM [ticket__d_c840__model] [t] WHERE ([t].[password] = 'abc' AND [t].[modified_at] > '2010-01-01' AND [t].[modified_at] < '2010-01-01' AND [t].[modified_at] <> '2010-01-01' AND [t].[modified_at] <= '2010-01-01' AND [t].[modified_at] >= '2010-01-01')";
+ $expected = "SELECT [t].[id] AS [t__id] FROM [ticket__d_c840__model] [t] WHERE ([t].[password] = 'abc' AND [t].[modified_at] > '2010-01-01' AND [t].[modified_at] < '2010-01-01' AND [t].[modified_at] <> '2010-01-01' AND [t].[modified_at] <= '2010-01-01' AND [t].[modified_at] >= '2010-01-01')";
$sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
$this->assertEqual($expected, $sql);
View
118 tests/Ticket/DC841TestCase.php
@@ -46,16 +46,119 @@ public function testInit()
$this->conn = Doctrine_Manager::getInstance()->openConnection($this->dbh, 'DC841');
}
- public function testQuery()
+ public function testSelect()
{
Doctrine::getTable('Ticket_DC841_Model')
->createQuery('t')
->where('t.username <> ?', 'foo')
+ ->andWhere('t.foo = ?', 't.foo = ?')
->andWhere('t.foo <> ?', 'bar')
->andWhere('t.foo LIKE ?', 'foo')
->execute();
- $expected = "SELECT [t].[model_id] AS [t__model_id], [t].[username] AS [t__username], [t].[password] AS [t__password], [t].[foo] AS [t__foo] FROM [ticket__d_c841__model] [t] WHERE ([t].[username] <> 'foo' AND [t].[foo] <> 'bar' AND [t].[foo] LIKE 'foo')";
+ $expected = "SELECT [t].[id] AS [t__id], [t].[username] AS [t__username], [t].[password] AS [t__password], [t].[foo] AS [t__foo] FROM [ticket__d_c841__model] [t] WHERE ([t].[username] <> 'foo' AND [t].[foo] = 't.foo = ?' AND [t].[foo] <> 'bar' AND [t].[foo] LIKE 'foo')";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testSelectJoinWith()
+ {
+ Doctrine::getTable('Ticket_DC841_Model')
+ ->createQuery('t')
+ ->leftJoin('t.Ticket_DC841_Model WITH t.id = ?', array(30))
+ ->where('t.username = ?', 'foo')
+ ->execute();
+
+ $expected = "SELECT [t].[id] AS [t__id], [t].[username] AS [t__username], [t].[password] AS [t__password], [t].[foo] AS [t__foo], [t2].[id] AS [t2__id], [t2].[username] AS [t2__username], [t2].[password] AS [t2__password], [t2].[foo] AS [t2__foo] FROM [ticket__d_c841__model] [t] LEFT JOIN [ticket__d_c841__model] [t2] ON [t].[id] = [t2].[id] AND ([t].[id] = 30) WHERE ([t].[username] = 'foo')";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testSelectWithStaticParameter()
+ {
+ return; // doesn't work
+ Doctrine::getTable('Ticket_DC841_Model')
+ ->createQuery('t')
+ ->where('t.username = ?', 'foo')
+ ->andWhere("t.foo = 't.foo = ?'")
+ ->andWhere("t.password = ?", 'test')
+ ->execute();
+
+ $expected = "SELECT [t].[id] AS [t__id], [t].[username] AS [t__username], [t].[password] AS [t__password], [t].[foo] AS [t__foo] FROM [ticket__d_c841__model] [t] WHERE ([t].[username] = 'foo' AND [t].[foo] = 't.foo = ?' AND [t].[password] = 'test')";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testSelectWithIn()
+ {
+ Doctrine::getTable('Ticket_DC841_Model')
+ ->createQuery('t')
+ ->whereIn('t.username', array('foo', 'bar'))
+ ->execute();
+
+ $expected = "SELECT [t].[id] AS [t__id], [t].[username] AS [t__username], [t].[password] AS [t__password], [t].[foo] AS [t__foo] FROM [ticket__d_c841__model] [t] WHERE ([t].[username] IN ('foo', 'bar'))";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testInsert()
+ {
+ try {
+ $o = new Ticket_DC841_Model();
+ $o->username = 'abc';
+ $o->password = 'abc';
+ $o->foo = 'abc';
+ $o->save();
+ } catch (Doctrine_Connection_Exception $e) {
+ // Ignore: Couldn't get last insert identifier.
+ }
+
+ $this->sqlStackCounter += 1;
+
+ $expected = "INSERT INTO [ticket__d_c841__model] ([username], [password], [foo]) VALUES ('abc', 'abc', 'abc')";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testUpdate()
+ {
+ $o = new Ticket_DC841_Model();
+ $o->assignIdentifier(33);
+ $o->username = 'abc';
+ $o->password = 'abc';
+ $o->foo = 'abc';
+ $o->state(Doctrine_Record::STATE_CLEAN);
+
+ $this->sqlStackCounter += 7;
+
+ $o->password = 'foobar';
+ $o->save();
+
+ $expected = "UPDATE [ticket__d_c841__model] SET [password] = 'foobar' WHERE id = 33";
+ $sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
+
+ $this->assertEqual($expected, $sql);
+ }
+
+ public function testDelete()
+ {
+ $o = new Ticket_DC841_Model();
+ $o->assignIdentifier(33);
+ $o->username = 'abc';
+ $o->password = 'abc';
+ $o->foo = 'abc';
+ $o->state(Doctrine_Record::STATE_CLEAN);
+
+ $this->sqlStackCounter += 5;
+
+ $o->delete();
+
+ $expected = "DELETE FROM [ticket__d_c841__model] WHERE [id] = 33";
$sql = current(array_slice($this->dbh->getAll(), $this->sqlStackCounter++, 1));
$this->assertEqual($expected, $sql);
@@ -66,7 +169,7 @@ class Ticket_DC841_Model extends Doctrine_Record
{
public function setTableDefinition()
{
- $this->hasColumn('model_id as id', 'integer', null, array(
+ $this->hasColumn('id', 'integer', null, array(
'type' => 'integer',
'unsigned' => false,
'primary' => true,
@@ -76,4 +179,11 @@ public function setTableDefinition()
$this->hasColumn('password', 'string', 255);
$this->hasColumn('foo', 'string', 255);
}
-}
+
+ public function setUp()
+ {
+ $this->hasOne('Ticket_DC841_Model', array(
+ 'local' => 'id',
+ 'foreign' => 'id'));
+ }
+}

0 comments on commit b7ea0eb

Please sign in to comment.