[TASK] Remove closing PHP tags
[Packages/TYPO3.CMS.git] / typo3 / sysext / dbal / Tests / Unit / Database / DatabaseConnectionTest.php
1 <?php
2 namespace TYPO3\CMS\Dbal\Tests\Unit\Database;
3
4 /**
5 * Testcase for class DatabaseConnection.
6 *
7 * @author Xavier Perseguers <xavier@typo3.org>
8 */
9 class DatabaseConnectionTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
10
11 /**
12 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
13 */
14 protected $db;
15
16 /**
17 * @var array
18 */
19 protected $loadedExtensions;
20
21 /**
22 * @var array
23 */
24 protected $temporaryFiles;
25
26 /**
27 * Prepares the environment before running a test.
28 */
29 public function setUp() {
30 // Backup list of loaded extensions
31 $this->loadedExtensions = $GLOBALS['TYPO3_LOADED_EXT'];
32 // Backup database connection
33 $this->db = $GLOBALS['TYPO3_DB'];
34 $this->temporaryFiles = array();
35 $className = self::buildAccessibleProxy('TYPO3\\CMS\\Dbal\\Database\\DatabaseConnection');
36 $GLOBALS['TYPO3_DB'] = new $className();
37 $GLOBALS['TYPO3_DB']->lastHandlerKey = '_DEFAULT';
38 }
39
40 /**
41 * Cleans up the environment after running a test.
42 */
43 public function tearDown() {
44 // Clear DBAL-generated cache files
45 $GLOBALS['TYPO3_DB']->clearCachedFieldInfo();
46 // Delete temporary files
47 foreach ($this->temporaryFiles as $filename) {
48 unlink($filename);
49 }
50 // Restore DB connection
51 $GLOBALS['TYPO3_DB'] = $this->db;
52 // Restore list of loaded extensions
53 $GLOBALS['TYPO3_LOADED_EXT'] = $this->loadedExtensions;
54 }
55
56 /**
57 * Cleans a SQL query.
58 *
59 * @param mixed $sql
60 * @return mixed (string or array)
61 */
62 private function cleanSql($sql) {
63 if (!is_string($sql)) {
64 return $sql;
65 }
66 $sql = str_replace('
67 ', ' ', $sql);
68 $sql = preg_replace('/\\s+/', ' ', $sql);
69 return trim($sql);
70 }
71
72 /**
73 * Creates a fake extension with a given table definition.
74 *
75 * @param string $tableDefinition SQL script to create the extension's tables
76 * @return void
77 */
78 protected function createFakeExtension($tableDefinition) {
79 // Prepare a fake extension configuration
80 $ext_tables = \TYPO3\CMS\Core\Utility\GeneralUtility::tempnam('ext_tables');
81 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($ext_tables, $tableDefinition);
82 $this->temporaryFiles[] = $ext_tables;
83 $GLOBALS['TYPO3_LOADED_EXT']['test_dbal'] = array(
84 'ext_tables.sql' => $ext_tables
85 );
86 // Append our test table to the list of existing tables
87 $GLOBALS['TYPO3_DB']->clearCachedFieldInfo();
88 $GLOBALS['TYPO3_DB']->_call('initInternalVariables');
89 }
90
91 /**
92 * @test
93 * @see http://bugs.typo3.org/view.php?id=12515
94 */
95 public function concatCanBeParsedAfterLikeOperator() {
96 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery('*', 'sys_refindex, tx_dam_file_tracking', 'sys_refindex.tablename = \'tx_dam_file_tracking\'' . ' AND sys_refindex.ref_string LIKE CONCAT(tx_dam_file_tracking.file_path, tx_dam_file_tracking.file_name)'));
97 $expected = 'SELECT * FROM sys_refindex, tx_dam_file_tracking WHERE sys_refindex.tablename = \'tx_dam_file_tracking\'';
98 $expected .= ' AND sys_refindex.ref_string LIKE CONCAT(tx_dam_file_tracking.file_path, tx_dam_file_tracking.file_name)';
99 $this->assertEquals($expected, $query);
100 }
101
102 /**
103 * @test
104 * @see http://bugs.typo3.org/view.php?id=10965
105 */
106 public function floatNumberCanBeStoredInDatabase() {
107 $this->createFakeExtension('
108 CREATE TABLE tx_test_dbal (
109 foo double default \'0\',
110 foobar integer default \'0\'
111 );
112 ');
113 $data = array(
114 'foo' => 99.12,
115 'foobar' => -120
116 );
117 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->INSERTquery('tx_test_dbal', $data));
118 $expected = 'INSERT INTO tx_test_dbal ( foo, foobar ) VALUES ( \'99.12\', \'-120\' )';
119 $this->assertEquals($expected, $query);
120 }
121
122 /**
123 * @test
124 * @see http://bugs.typo3.org/view.php?id=11093
125 */
126 public function positive64BitIntegerIsSupported() {
127 $this->createFakeExtension('
128 CREATE TABLE tx_test_dbal (
129 foo int default \'0\',
130 foobar bigint default \'0\'
131 );
132 ');
133 $data = array(
134 'foo' => 9223372036854775807,
135 'foobar' => 9223372036854775807
136 );
137 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->INSERTquery('tx_test_dbal', $data));
138 $expected = 'INSERT INTO tx_test_dbal ( foo, foobar ) VALUES ( \'9223372036854775807\', \'9223372036854775807\' )';
139 $this->assertEquals($expected, $query);
140 }
141
142 /**
143 * @test
144 * @see http://bugs.typo3.org/view.php?id=11093
145 */
146 public function negative64BitIntegerIsSupported() {
147 $this->createFakeExtension('
148 CREATE TABLE tx_test_dbal (
149 foo int default \'0\',
150 foobar bigint default \'0\'
151 );
152 ');
153 $data = array(
154 'foo' => -9.2233720368548E+18,
155 'foobar' => -9.2233720368548E+18
156 );
157 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->INSERTquery('tx_test_dbal', $data));
158 $expected = 'INSERT INTO tx_test_dbal ( foo, foobar ) VALUES ( \'-9223372036854775808\', \'-9223372036854775808\' )';
159 $this->assertEquals($expected, $query);
160 }
161
162 /**
163 * @test
164 */
165 public function sqlForInsertWithMultipleRowsIsValid() {
166 $fields = array('uid', 'pid', 'title', 'body');
167 $rows = array(
168 array('1', '2', 'Title #1', 'Content #1'),
169 array('3', '4', 'Title #2', 'Content #2'),
170 array('5', '6', 'Title #3', 'Content #3')
171 );
172 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->INSERTmultipleRows('tt_content', $fields, $rows));
173 $expected = 'INSERT INTO tt_content (uid, pid, title, body) VALUES ';
174 $expected .= '(\'1\', \'2\', \'Title #1\', \'Content #1\'), ';
175 $expected .= '(\'3\', \'4\', \'Title #2\', \'Content #2\'), ';
176 $expected .= '(\'5\', \'6\', \'Title #3\', \'Content #3\')';
177 $this->assertEquals($expected, $query);
178 }
179
180 /**
181 * @test
182 * @see http://bugs.typo3.org/view.php?id=4493
183 */
184 public function minFunctionAndInOperatorCanBeParsed() {
185 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery('*', 'pages', 'MIN(uid) IN (1,2,3,4)'));
186 $expected = 'SELECT * FROM pages WHERE MIN(uid) IN (1,2,3,4)';
187 $this->assertEquals($expected, $query);
188 }
189
190 /**
191 * @test
192 * @see http://bugs.typo3.org/view.php?id=4493
193 */
194 public function maxFunctionAndInOperatorCanBeParsed() {
195 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery('*', 'pages', 'MAX(uid) IN (1,2,3,4)'));
196 $expected = 'SELECT * FROM pages WHERE MAX(uid) IN (1,2,3,4)';
197 $this->assertEquals($expected, $query);
198 }
199
200 /**
201 * @test
202 * @see http://bugs.typo3.org/view.php?id=12535
203 */
204 public function likeBinaryOperatorIsKept() {
205 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery('*', 'tt_content', 'bodytext LIKE BINARY \'test\''));
206 $expected = 'SELECT * FROM tt_content WHERE bodytext LIKE BINARY \'test\'';
207 $this->assertEquals($expected, $query);
208 }
209
210 /**
211 * @test
212 * @see http://bugs.typo3.org/view.php?id=12535
213 */
214 public function notLikeBinaryOperatorIsKept() {
215 $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery('*', 'tt_content', 'bodytext NOT LIKE BINARY \'test\''));
216 $expected = 'SELECT * FROM tt_content WHERE bodytext NOT LIKE BINARY \'test\'';
217 $this->assertEquals($expected, $query);
218 }
219
220 ///////////////////////////////////////
221 // Tests concerning prepared queries
222 ///////////////////////////////////////
223 /**
224 * @test
225 * @see http://bugs.typo3.org/view.php?id=15457
226 */
227 public function similarNamedParametersAreProperlyReplaced() {
228 $sql = 'SELECT * FROM cache WHERE tag = :tag1 OR tag = :tag10 OR tag = :tag100';
229 $parameterValues = array(
230 ':tag1' => 'tag-one',
231 ':tag10' => 'tag-two',
232 ':tag100' => 'tag-three'
233 );
234 $className = self::buildAccessibleProxy('TYPO3\\CMS\\Core\\Database\\PreparedStatement');
235 $query = $sql;
236 $precompiledQueryParts = array();
237 $statement = new $className($sql, 'cache');
238 $statement->bindValues($parameterValues);
239 $parameters = $statement->_get('parameters');
240 $statement->_callRef('replaceValuesInQuery', $query, $precompiledQueryParts, $parameters);
241 $expected = 'SELECT * FROM cache WHERE tag = \'tag-one\' OR tag = \'tag-two\' OR tag = \'tag-three\'';
242 $this->assertEquals($expected, $query);
243 }
244
245 }