DataAccessTest.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace Doctrine\Tests\DBAL\Functional;
  3. use Doctrine\DBAL\Types\Type;
  4. use Doctrine\DBAL\Connection;
  5. use PDO;
  6. require_once __DIR__ . '/../../TestInit.php';
  7. class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
  8. {
  9. public function setUp()
  10. {
  11. parent::setUp();
  12. try {
  13. /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
  14. $table = new \Doctrine\DBAL\Schema\Table("fetch_table");
  15. $table->addColumn('test_int', 'integer');
  16. $table->addColumn('test_string', 'string');
  17. $table->addColumn('test_datetime', 'datetime', array('notnull' => false));
  18. $sm = $this->_conn->getSchemaManager();
  19. $sm->createTable($table);
  20. $this->_conn->insert('fetch_table', array('test_int' => 1, 'test_string' => 'foo', 'test_datetime' => '2010-01-01 10:10:10'));
  21. } catch(\Exception $e) {
  22. }
  23. }
  24. public function testPrepareWithBindValue()
  25. {
  26. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  27. $stmt = $this->_conn->prepare($sql);
  28. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  29. $stmt->bindValue(1, 1);
  30. $stmt->bindValue(2, 'foo');
  31. $stmt->execute();
  32. $row = $stmt->fetch(\PDO::FETCH_ASSOC);
  33. $row = array_change_key_case($row, \CASE_LOWER);
  34. $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
  35. }
  36. public function testPrepareWithBindParam()
  37. {
  38. $paramInt = 1;
  39. $paramStr = 'foo';
  40. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  41. $stmt = $this->_conn->prepare($sql);
  42. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  43. $stmt->bindParam(1, $paramInt);
  44. $stmt->bindParam(2, $paramStr);
  45. $stmt->execute();
  46. $row = $stmt->fetch(\PDO::FETCH_ASSOC);
  47. $row = array_change_key_case($row, \CASE_LOWER);
  48. $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
  49. }
  50. public function testPrepareWithFetchAll()
  51. {
  52. $paramInt = 1;
  53. $paramStr = 'foo';
  54. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  55. $stmt = $this->_conn->prepare($sql);
  56. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  57. $stmt->bindParam(1, $paramInt);
  58. $stmt->bindParam(2, $paramStr);
  59. $stmt->execute();
  60. $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
  61. $rows[0] = array_change_key_case($rows[0], \CASE_LOWER);
  62. $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $rows[0]);
  63. }
  64. public function testPrepareWithFetchColumn()
  65. {
  66. $paramInt = 1;
  67. $paramStr = 'foo';
  68. $sql = "SELECT test_int FROM fetch_table WHERE test_int = ? AND test_string = ?";
  69. $stmt = $this->_conn->prepare($sql);
  70. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  71. $stmt->bindParam(1, $paramInt);
  72. $stmt->bindParam(2, $paramStr);
  73. $stmt->execute();
  74. $column = $stmt->fetchColumn();
  75. $this->assertEquals(1, $column);
  76. }
  77. public function testPrepareWithQuoted()
  78. {
  79. $table = 'fetch_table';
  80. $paramInt = 1;
  81. $paramStr = 'foo';
  82. $sql = "SELECT test_int, test_string FROM " . $this->_conn->quoteIdentifier($table) . " ".
  83. "WHERE test_int = " . $this->_conn->quote($paramInt) . " AND test_string = " . $this->_conn->quote($paramStr);
  84. $stmt = $this->_conn->prepare($sql);
  85. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  86. }
  87. public function testPrepareWithExecuteParams()
  88. {
  89. $paramInt = 1;
  90. $paramStr = 'foo';
  91. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  92. $stmt = $this->_conn->prepare($sql);
  93. $this->assertInstanceOf('Doctrine\DBAL\Statement', $stmt);
  94. $stmt->execute(array($paramInt, $paramStr));
  95. $row = $stmt->fetch(\PDO::FETCH_ASSOC);
  96. $row = array_change_key_case($row, \CASE_LOWER);
  97. $this->assertEquals(array('test_int' => 1, 'test_string' => 'foo'), $row);
  98. }
  99. public function testFetchAll()
  100. {
  101. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  102. $data = $this->_conn->fetchAll($sql, array(1, 'foo'));
  103. $this->assertEquals(1, count($data));
  104. $row = $data[0];
  105. $this->assertEquals(2, count($row));
  106. $row = array_change_key_case($row, \CASE_LOWER);
  107. $this->assertEquals(1, $row['test_int']);
  108. $this->assertEquals('foo', $row['test_string']);
  109. }
  110. public function testFetchRow()
  111. {
  112. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  113. $row = $this->_conn->fetchAssoc($sql, array(1, 'foo'));
  114. $row = array_change_key_case($row, \CASE_LOWER);
  115. $this->assertEquals(1, $row['test_int']);
  116. $this->assertEquals('foo', $row['test_string']);
  117. }
  118. public function testFetchArray()
  119. {
  120. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  121. $row = $this->_conn->fetchArray($sql, array(1, 'foo'));
  122. $this->assertEquals(1, $row[0]);
  123. $this->assertEquals('foo', $row[1]);
  124. }
  125. public function testFetchColumn()
  126. {
  127. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  128. $testInt = $this->_conn->fetchColumn($sql, array(1, 'foo'), 0);
  129. $this->assertEquals(1, $testInt);
  130. $sql = "SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?";
  131. $testString = $this->_conn->fetchColumn($sql, array(1, 'foo'), 1);
  132. $this->assertEquals('foo', $testString);
  133. }
  134. /**
  135. * @group DDC-697
  136. */
  137. public function testExecuteQueryBindDateTimeType()
  138. {
  139. $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
  140. $stmt = $this->_conn->executeQuery($sql,
  141. array(1 => new \DateTime('2010-01-01 10:10:10')),
  142. array(1 => Type::DATETIME)
  143. );
  144. $this->assertEquals(1, $stmt->fetchColumn());
  145. }
  146. /**
  147. * @group DDC-697
  148. */
  149. public function testExecuteUpdateBindDateTimeType()
  150. {
  151. $datetime = new \DateTime('2010-02-02 20:20:20');
  152. $sql = 'INSERT INTO fetch_table (test_int, test_string, test_datetime) VALUES (?, ?, ?)';
  153. $affectedRows = $this->_conn->executeUpdate($sql,
  154. array(1 => 1, 2 => 'foo', 3 => $datetime),
  155. array(1 => PDO::PARAM_INT, 2 => PDO::PARAM_STR, 3 => Type::DATETIME)
  156. );
  157. $this->assertEquals(1, $affectedRows);
  158. $this->assertEquals(1, $this->_conn->executeQuery(
  159. 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?',
  160. array(1 => $datetime),
  161. array(1 => Type::DATETIME)
  162. )->fetchColumn());
  163. }
  164. /**
  165. * @group DDC-697
  166. */
  167. public function testPrepareQueryBindValueDateTimeType()
  168. {
  169. $sql = 'SELECT count(*) AS c FROM fetch_table WHERE test_datetime = ?';
  170. $stmt = $this->_conn->prepare($sql);
  171. $stmt->bindValue(1, new \DateTime('2010-01-01 10:10:10'), Type::DATETIME);
  172. $stmt->execute();
  173. $this->assertEquals(1, $stmt->fetchColumn());
  174. }
  175. /**
  176. * @group DBAL-78
  177. */
  178. public function testNativeArrayListSupport()
  179. {
  180. for ($i = 100; $i < 110; $i++) {
  181. $this->_conn->insert('fetch_table', array('test_int' => $i, 'test_string' => 'foo' . $i, 'test_datetime' => '2010-01-01 10:10:10'));
  182. }
  183. $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_int IN (?)',
  184. array(array(100, 101, 102, 103, 104)), array(Connection::PARAM_INT_ARRAY));
  185. $data = $stmt->fetchAll(PDO::FETCH_NUM);
  186. $this->assertEquals(5, count($data));
  187. $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
  188. $stmt = $this->_conn->executeQuery('SELECT test_int FROM fetch_table WHERE test_string IN (?)',
  189. array(array('foo100', 'foo101', 'foo102', 'foo103', 'foo104')), array(Connection::PARAM_STR_ARRAY));
  190. $data = $stmt->fetchAll(PDO::FETCH_NUM);
  191. $this->assertEquals(5, count($data));
  192. $this->assertEquals(array(array(100), array(101), array(102), array(103), array(104)), $data);
  193. }
  194. /**
  195. * @group DDC-1014
  196. */
  197. public function testDateArithmetics()
  198. {
  199. $p = $this->_conn->getDatabasePlatform();
  200. $sql = 'SELECT ';
  201. $sql .= $p->getDateDiffExpression('test_datetime', $p->getCurrentTimestampSQL()) .' AS diff, ';
  202. $sql .= $p->getDateAddDaysExpression('test_datetime', 10) .' AS add_days, ';
  203. $sql .= $p->getDateSubDaysExpression('test_datetime', 10) .' AS sub_days, ';
  204. $sql .= $p->getDateAddMonthExpression('test_datetime', 2) .' AS add_month, ';
  205. $sql .= $p->getDateSubMonthExpression('test_datetime', 2) .' AS sub_month ';
  206. $sql .= 'FROM fetch_table';
  207. $row = $this->_conn->fetchAssoc($sql);
  208. $row = array_change_key_case($row, CASE_LOWER);
  209. $diff = floor( (strtotime('2010-01-01')-time()) / 3600 / 24);
  210. $this->assertEquals($diff, (int)$row['diff'], "Date difference should be approx. ".$diff." days.", 1);
  211. $this->assertEquals('2010-01-11', date('Y-m-d', strtotime($row['add_days'])), "Adding date should end up on 2010-01-11");
  212. $this->assertEquals('2009-12-22', date('Y-m-d', strtotime($row['sub_days'])), "Subtracting date should end up on 2009-12-22");
  213. $this->assertEquals('2010-03-01', date('Y-m-d', strtotime($row['add_month'])), "Adding month should end up on 2010-03-01");
  214. $this->assertEquals('2009-11-01', date('Y-m-d', strtotime($row['sub_month'])), "Adding month should end up on 2009-11-01");
  215. }
  216. public function testQuoteSQLInjection()
  217. {
  218. $sql = "SELECT * FROM fetch_table WHERE test_string = " . $this->_conn->quote("bar' OR '1'='1");
  219. $rows = $this->_conn->fetchAll($sql);
  220. $this->assertEquals(0, count($rows), "no result should be returned, otherwise SQL injection is possible");
  221. }
  222. }