Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.03% covered (warning)
79.03%
245 / 310
85.19% covered (warning)
85.19%
23 / 27
CRAP
0.00% covered (danger)
0.00%
0 / 1
phpbb_dbal_db_tools_test
79.03% covered (warning)
79.03%
245 / 310
85.19% covered (warning)
85.19%
23 / 27
43.04
0.00% covered (danger)
0.00%
0 / 1
 getDataSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUp
100.00% covered (success)
100.00%
49 / 49
100.00% covered (success)
100.00%
1 / 1
1
 tearDown
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 test_created_and_drop_table
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 get_default_values
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
1
 column_values
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
2
 test_created_column
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
3.00
 test_list_columns
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 test_column_exists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_column_change_with_index
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 test_column_change_with_composite_primary
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 test_column_remove
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 test_column_remove_similar_name
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 test_column_remove_with_index
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 test_column_remove_primary
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 test_list_tables
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 test_table_exists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_table_drop
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 test_truncate_table
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
 test_perform_schema_changes_drop_tables
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
1
 test_perform_schema_changes_drop_columns
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
1
 test_index_exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 test_unique_index_exists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 test_create_index_against_index_exists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_create_unique_index_against_unique_index_exists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_create_int_default_null
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 test_create_index_with_long_name
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3use Doctrine\DBAL\Schema\Schema;
4
5/**
6*
7* This file is part of the phpBB Forum Software package.
8*
9* @copyright (c) phpBB Limited <https://www.phpbb.com>
10* @license GNU General Public License, version 2 (GPL-2.0)
11*
12* For full copyright and license information, please see
13* the docs/CREDITS.txt file.
14*
15*/
16
17class phpbb_dbal_db_tools_test extends phpbb_database_test_case
18{
19    /** @var \phpbb\db\driver\driver_interface */
20    protected $db;
21
22    /** @var \Doctrine\DBAL\Connection */
23    protected $doctrine_db;
24
25    /** @var \phpbb\db\tools\tools_interface */
26    protected $tools;
27
28    protected $table_exists;
29    protected $table_data;
30
31    public function getDataSet()
32    {
33        return $this->createXMLDataSet(__DIR__.'/fixtures/config.xml');
34    }
35
36    protected function setUp(): void
37    {
38
39        parent::setUp();
40
41        $table_prefix = 'prefix_';
42        $this->db = $this->new_dbal();
43        $this->doctrine_db = $this->new_doctrine_dbal();
44        $factory = new \phpbb\db\tools\factory();
45        $this->tools = $factory->get($this->doctrine_db);
46        $this->tools->set_table_prefix($table_prefix);
47
48        $this->table_data = array(
49            'COLUMNS'        => array(
50                'c_id'                => array('UINT', NULL, 'auto_increment'),
51                'c_int_size'            => array('INT:4', 4),
52                'c_bint'                => array('BINT', 4),
53                'c_uint'                => array('UINT', 4),
54                'c_uint_size'            => array('UINT:4', 4),
55                'c_tint_size'            => array('TINT:2', 4),
56                'c_usint'                => array('USINT', 4),
57                'c_bool'                => array('BOOL', 1),
58                'c_vchar'                => array('VCHAR', 'foo'),
59                'c_vchar_size'        => array('VCHAR:4', 'foo'),
60                'c_vchar_null'        => array('VCHAR', null),
61                'c_char_size'            => array('CHAR:4', 'foo'),
62                'c_xstext'            => array('XSTEXT', 'foo'),
63                'c_stext'                => array('STEXT', 'foo'),
64                'c_text'                => array('TEXT', 'foo'),
65                'c_mtext'                => array('MTEXT', 'foo'),
66                'c_xstext_uni'        => array('XSTEXT_UNI', 'foo'),
67                'c_stext_uni'            => array('STEXT_UNI', 'foo'),
68                'c_text_uni'            => array('TEXT_UNI', 'foo'),
69                'c_mtext_uni'            => array('MTEXT_UNI', 'foo'),
70                'c_timestamp'            => array('TIMESTAMP', 4),
71                'c_decimal'            => array('DECIMAL', 4.2),
72                'c_decimal_size'        => array('DECIMAL:6', 4.2),
73                'c_pdecimal'            => array('PDECIMAL', 4.2),
74                'c_pdecimal_size'        => array('PDECIMAL:7', 4.2),
75                'c_vchar_uni'            => array('VCHAR_UNI', 'foo'),
76                'c_vchar_uni_size'    => array('VCHAR_UNI:4', 'foo'),
77                'c_vchar_ci'            => array('VCHAR_CI', 'foo'),
78                'c_varbinary'            => array('VARBINARY', 'foo'),
79            ),
80            'PRIMARY_KEY'    => 'c_id',
81            'KEYS'            => array(
82                'i_simple'    => array('INDEX', 'c_uint'),
83                'i_uniq'    => array('UNIQUE', 'c_vchar'),
84                'i_comp'    => array('INDEX', array('c_vchar_uni', 'c_bool')),
85                'i_comp_uniq'    => array('UNIQUE', array('c_vchar_size', 'c_usint')),
86            ),
87        );
88        $this->tools->sql_create_table('prefix_table_name', $this->table_data);
89        $this->table_exists = true;
90    }
91
92    protected function tearDown(): void
93    {
94        if ($this->table_exists)
95        {
96            $this->tools->sql_table_drop('prefix_table_name');
97        }
98
99        parent::tearDown();
100    }
101
102    public function test_created_and_drop_table()
103    {
104        // table is empty after creation and queryable
105        $sql = 'SELECT * FROM prefix_table_name';
106        $result = $this->db->sql_query($sql);
107        $this->assertTrue(! $this->db->sql_fetchrow($result));
108        $this->db->sql_freeresult($result);
109
110        $this->table_exists = false;
111        $this->tools->sql_table_drop('prefix_table_name');
112    }
113
114    protected static function get_default_values()
115    {
116        return array(
117            'c_int_size' => 0,
118            'c_bint' => 0,
119            'c_uint' => 0,
120            'c_uint_size' => 0,
121            'c_tint_size' => 0,
122            'c_usint' => 0,
123            'c_bool' => 0,
124            'c_vchar' => '',
125            'c_vchar_size' => '',
126            'c_vchar_null' => null,
127            'c_char_size' => 'abcd',
128            'c_xstext' => '',
129            'c_stext' => '',
130            'c_text' => '',
131            'c_mtext' => '',
132            'c_xstext_uni' => '',
133            'c_stext_uni' => '',
134            'c_text_uni' => '',
135            'c_mtext_uni' => '',
136            'c_timestamp' => 0,
137            'c_decimal' => 0,
138            'c_decimal_size' => 0,
139            'c_pdecimal' => 0,
140            'c_pdecimal_size' => 0,
141            'c_vchar_uni' => '',
142            'c_vchar_uni_size' => '',
143            'c_vchar_ci' => '',
144            'c_varbinary' => '',
145        );
146    }
147
148    static public function column_values()
149    {
150        return array(
151            array('c_int_size', -9999),
152            array('c_bint', '99999999999999999'),
153            array('c_uint', 16777215),
154            array('c_uint_size', 9999),
155            array('c_tint_size', -99),
156            array('c_usint', 99),
157            array('c_bool', 0),
158            array('c_vchar', str_repeat('a', 255)),
159            array('c_vchar_size', str_repeat('a', 4)),
160            array('c_vchar_null', str_repeat('a', 4)),
161            array('c_char_size', str_repeat('a', 4)),
162            array('c_xstext', str_repeat('a', 1000)),
163            array('c_stext', str_repeat('a', 3000)),
164            array('c_text', str_repeat('a', 8000)),
165            array('c_mtext', str_repeat('a', 10000)),
166            array('c_xstext_uni', str_repeat("\xC3\x84", 100)),
167            array('c_stext_uni', str_repeat("\xC3\x84", 255)),
168            array('c_text_uni', str_repeat("\xC3\x84", 4000)),
169            array('c_mtext_uni', str_repeat("\xC3\x84", 10000)),
170            array('c_timestamp', 2147483647),
171            array('c_decimal', 999.99),
172            array('c_decimal_size', 9999.99),
173            array('c_pdecimal', 999.999),
174            array('c_pdecimal_size', 9999.999),
175            array('c_vchar_uni', str_repeat("\xC3\x84", 255)),
176            array('c_vchar_uni_size', str_repeat("\xC3\x84", 4)),
177            array('c_vchar_ci', str_repeat("\xC3\x84", 255)),
178            array('c_varbinary', str_repeat("\x00\xFF", 127)),
179        );
180    }
181
182    /**
183    * @dataProvider column_values
184    */
185    public function test_created_column($column_name, $column_value)
186    {
187        if ($column_name === 'c_varbinary' && stripos(get_class($this->db), 'mysql') === false)
188        {
189            $this->markTestIncomplete('Binary handling is not implemented properly on non-MySQL DBMSes.');
190        }
191
192        $row_insert = self::get_default_values();
193        $row_insert[$column_name] = $column_value;
194
195        // empty table
196        $sql = 'DELETE FROM prefix_table_name';
197        $this->db->sql_query($sql);
198
199        $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row_insert);
200        $this->db->sql_query($sql);
201
202        $sql = "SELECT *
203            FROM prefix_table_name";
204        $result = $this->db->sql_query($sql);
205        $row_actual = $this->db->sql_fetchrow($result);
206        $this->db->sql_freeresult($result);
207
208        $row_expect = $row_insert;
209
210        unset($row_actual['id']); // auto increment id changes, so ignore
211
212        $type = $this->table_data['COLUMNS'][$column_name][0];
213        $this->assertEquals($row_expect[$column_name], $row_actual[$column_name], "Column $column_name of type $type should have equal return and input value.");
214    }
215
216    public function test_list_columns()
217    {
218        $expected_columns = $this->table_data['COLUMNS'];
219        $found_columns = $this->tools->sql_list_columns('prefix_table_name');
220
221        ksort($expected_columns);
222        ksort($found_columns);
223
224        $this->assertEquals(
225            array_keys($expected_columns),
226            array_values($found_columns)
227        );
228    }
229
230    public function test_column_exists()
231    {
232        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_id'));
233        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'column_does_not_exist'));
234    }
235
236    public function test_column_change_with_index()
237    {
238        $short_table_name = \phpbb\db\doctrine\table_helper::generate_shortname('table_name');
239
240        // Create column
241        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012'));
242        $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_12012', array('DECIMAL', 0)));
243        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012'));
244
245        // Create index over the column
246        $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_i_bug_12012'));
247        $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012', array('c_bug_12012', 'c_bool')));
248        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_i_bug_12012'));
249
250        // Change type from int to string
251        $this->assertTrue($this->tools->sql_column_change('prefix_table_name', 'c_bug_12012', array('VCHAR:100', '')));
252
253        // Remove the index
254        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_i_bug_12012'));
255        $this->assertTrue($this->tools->sql_index_drop('prefix_table_name', 'i_bug_12012'));
256        $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_i_bug_12012'));
257
258        // Remove the column
259        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012'));
260        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_bug_12012'));
261        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012'));
262    }
263
264    public function test_column_change_with_composite_primary()
265    {
266        if (stripos(get_class($this->db), 'sqlite') !== false)
267        {
268            $this->markTestSkipped('Sqlite platform does not support alter primary key.');
269        }
270
271        // Remove the old primary key
272        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_id'));
273        $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_id', array('UINT', 0)));
274
275        // Create a composite key
276        $this->assertTrue($this->tools->sql_create_primary_key('prefix_table_name', array('c_id', 'c_uint')));
277
278        // Create column
279        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12643'));
280        $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_12643', array('DECIMAL', 0)));
281        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12643'));
282
283        // Change type from int to string
284        $this->assertTrue($this->tools->sql_column_change('prefix_table_name', 'c_bug_12643', array('VCHAR:100', '')));
285    }
286
287    public function test_column_remove()
288    {
289        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_int_size'));
290
291        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_int_size'));
292
293        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_int_size'));
294    }
295
296    public function test_column_remove_similar_name()
297    {
298        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_vchar'));
299        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_vchar_size'));
300
301        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_vchar'));
302
303        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_vchar'));
304        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_vchar_size'));
305    }
306
307    public function test_column_remove_with_index()
308    {
309        $short_table_name = \phpbb\db\doctrine\table_helper::generate_shortname('table_name');
310
311        // Create column
312        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2'));
313        $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_12012_2', array('UINT', 4)));
314        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2'));
315
316        // Create index over the column
317        $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_bug_12012_2'));
318        $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_2', array('c_bug_12012_2', 'c_bool')));
319        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_bug_12012_2'));
320
321        $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_bug_12012_3'));
322        $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_3', array('c_bug_12012_2')));
323        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_bug_12012_3'));
324
325        // Remove the column
326        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2'));
327        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_bug_12012_2'));
328        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2'));
329    }
330
331    public function test_column_remove_primary()
332    {
333        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_id'));
334
335        $this->assertTrue($this->tools->sql_column_remove('prefix_table_name', 'c_id'));
336
337        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_id'));
338    }
339
340    public function test_list_tables()
341    {
342        $tables = $this->tools->sql_list_tables();
343        $this->assertTrue(isset($tables['prefix_table_name']));
344        $this->assertFalse(isset($tables['prefix_does_not_exist']));
345    }
346
347    public function test_table_exists()
348    {
349        $this->assertTrue($this->tools->sql_table_exists('prefix_table_name'));
350        $this->assertFalse($this->tools->sql_table_exists('prefix_does_not_exist'));
351    }
352
353    public function test_table_drop()
354    {
355        $this->tools->sql_create_table('prefix_test_table',
356            array('COLUMNS' => array(
357                'foo' => array('UINT', 42)))
358        );
359
360        $this->assertTrue($this->tools->sql_table_exists('prefix_test_table'));
361
362        $this->tools->sql_table_drop('prefix_test_table');
363
364        $this->assertFalse($this->tools->sql_table_exists('prefix_test_table'));
365    }
366
367    public function test_truncate_table()
368    {
369        $this->tools->sql_create_table('truncate_test_table',
370            ['COLUMNS' => [
371                'foo' => ['UINT', 42],
372            ]]
373        );
374
375        $this->assertTrue($this->tools->sql_table_exists('truncate_test_table'));
376
377        $sql = 'INSERT INTO truncate_test_table(foo) VALUES(19)';
378        $this->db->sql_query($sql);
379
380        $sql = 'SELECT * FROM truncate_test_table';
381        $result = $this->db->sql_query($sql);
382        $rowset = $this->db->sql_fetchrowset($result);
383        $this->db->sql_freeresult($result);
384
385        $this->assertGreaterThan(0, count($rowset), 'Failed asserting that data exists in truncate_test_table.');
386
387        $this->tools->sql_truncate_table('truncate_test_table');
388
389        $result = $this->db->sql_query($sql);
390        $rowset = $this->db->sql_fetchrowset($result);
391        $this->db->sql_freeresult($result);
392        $this->assertEquals(0, count($rowset), 'Failed asserting that truncate was successful for table.');
393    }
394
395    public function test_perform_schema_changes_drop_tables()
396    {
397        $db_tools = $this->getMockBuilder('\phpbb\db\tools\doctrine')
398            ->onlyMethods(array('sql_table_exists', 'schema_drop_table'))
399            ->setConstructorArgs(array($this->doctrine_db))
400            ->getMock();
401
402        // pretend all tables exist
403        $db_tools->expects($this->any())->method('sql_table_exists')
404            ->will($this->returnValue(true));
405
406        // drop tables
407        $matcher = $this->exactly(2);
408        $db_tools->expects($matcher)->method('schema_drop_table')
409            ->willReturnCallback(function() use ($matcher) {
410                $args = func_get_args();
411                $schema = array_shift($args);
412                $this->assertInstanceOf(\Doctrine\DBAL\Schema\Schema::class, $schema);
413                match($matcher->numberOfInvocations())
414                {
415                    1 => $this->assertEquals($args, ['dropped_table_1', true]),
416                    2 => $this->assertEquals($args, ['dropped_table_2', true]),
417                };
418            }
419        );
420
421        $db_tools->perform_schema_changes(array(
422            'drop_tables' => array(
423                'dropped_table_1',
424                'dropped_table_2',
425            ),
426        ));
427    }
428
429    public function test_perform_schema_changes_drop_columns()
430    {
431        $db_tools = $this->getMockBuilder('\phpbb\db\tools\doctrine')
432            ->onlyMethods(array('sql_column_exists', 'schema_column_remove'))
433            ->setConstructorArgs(array($this->doctrine_db))
434            ->getMock();
435
436        // pretend all columns exist
437        $db_tools->expects($this->any())->method('sql_column_exists')
438            ->will($this->returnValue(true));
439        $db_tools->expects($this->any())->method('sql_column_exists')
440            ->will($this->returnValue(true));
441
442        // drop columns
443        $matcher = $this->exactly(2);
444        $db_tools->expects($matcher)->method('schema_column_remove')
445            ->willReturnCallback(function() use ($matcher) {
446                $args = func_get_args();
447                $schema = array_shift($args);
448                $this->assertInstanceOf(\Doctrine\DBAL\Schema\Schema::class, $schema);
449                match($matcher->numberOfInvocations()) {
450                    1 => $this->assertEquals($args, ['existing_table', 'dropped_column_1', true]),
451                    2 => $this->assertEquals($args, ['existing_table', 'dropped_column_2', true]),
452                };
453            }
454        );
455
456        $db_tools->perform_schema_changes(array(
457            'drop_columns' => array(
458                'existing_table' => array(
459                    'dropped_column_1',
460                    'dropped_column_2',
461                ),
462            ),
463        ));
464    }
465
466    public function test_index_exists()
467    {
468        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', \phpbb\db\doctrine\table_helper::generate_shortname('table_name') . '_i_simple'));
469    }
470
471    public function test_unique_index_exists()
472    {
473        $this->assertTrue($this->tools->sql_unique_index_exists('prefix_table_name', \phpbb\db\doctrine\table_helper::generate_shortname('table_name') . '_i_uniq'));
474    }
475
476    public function test_create_index_against_index_exists()
477    {
478        $this->tools->sql_create_index('prefix_table_name', 'fookey', array('c_timestamp', 'c_decimal'));
479        $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', \phpbb\db\doctrine\table_helper::generate_shortname('table_name') . '_fookey'));
480    }
481
482    public function test_create_unique_index_against_unique_index_exists()
483    {
484        $this->tools->sql_create_unique_index('prefix_table_name', 'i_uniq_ts_id', array('c_timestamp', 'c_id'));
485        $this->assertTrue($this->tools->sql_unique_index_exists('prefix_table_name', \phpbb\db\doctrine\table_helper::generate_shortname('table_name') . '_i_uniq_ts_id'));
486    }
487
488    public function test_create_int_default_null()
489    {
490        $this->assertFalse($this->tools->sql_column_exists('prefix_table_name', 'c_bug_13282'));
491        $this->assertTrue($this->tools->sql_column_add('prefix_table_name', 'c_bug_13282', array('TINT:2', null)));
492        $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_13282'));
493    }
494
495    public function test_create_index_with_long_name()
496    {
497        $this->markTestSkipped('Skipped because it does not work anymore; To be checked.'); // TODO
498
499        // This constant is being used for checking table prefix.
500        $table_prefix = substr(CONFIG_TABLE, 0, -6); // strlen(config)
501
502        if (strlen($table_prefix) > 20)
503        {
504            $this->markTestIncomplete('The table prefix length is too long for proper testing of index shortening function.');
505        }
506
507        $max_index_length = 30;
508
509        if ($this->tools instanceof \phpbb\db\tools\mssql)
510        {
511            $max_length_method = new ReflectionMethod('\phpbb\db\tools\mssql', 'get_max_index_name_length');
512            $max_index_length = $max_length_method->invoke($this->tools);
513        }
514
515        $table_suffix = str_repeat('a', 25 - strlen($table_prefix));
516        $table_name = $table_prefix . $table_suffix;
517        $short_table_name = \phpbb\db\doctrine\table_helper::generate_shortname($table_suffix);
518
519        $this->tools->sql_create_table($table_name, $this->table_data);
520
521        // Index name and table suffix and table prefix have > maximum index length chars in total.
522        // Index name and table suffix have <= maximum index length chars in total.
523        $long_index_name = str_repeat('i', $max_index_length - strlen($table_suffix));
524        $this->assertFalse($this->tools->sql_index_exists($table_name, $short_table_name . '_' . $long_index_name));
525        $this->assertTrue($this->tools->sql_create_index($table_name, $long_index_name, array('c_timestamp')));
526        $this->assertTrue($this->tools->sql_index_exists($table_name, $short_table_name . '_' . $long_index_name));
527
528        // Index name and table suffix have > maximum index length chars in total.
529        $very_long_index_name = str_repeat('i', $max_index_length);
530        $this->assertFalse($this->tools->sql_index_exists($table_name, $short_table_name . '_' . $very_long_index_name));
531        $this->assertTrue($this->tools->sql_create_index($table_name, $very_long_index_name, array('c_timestamp')));
532        $this->assertTrue($this->tools->sql_index_exists($table_name, $short_table_name . '_' . $very_long_index_name));
533
534        $this->tools->sql_table_drop($table_name);
535
536        // Index name has > maximum index length chars - that should not be possible.
537        $too_long_index_name = str_repeat('i', $max_index_length + 1);
538        $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', $short_table_name . '_' . $too_long_index_name));
539        $this->setExpectedTriggerError(E_USER_ERROR); // TODO: Do we want to keep this limitation, if yes reimplement the user check
540        /* https://github.com/phpbb/phpbb/blob/aee5e373bca6cd20d44b99585d3b758276a2d7e6/phpBB/phpbb/db/tools/tools.php#L1488-L1517 */
541        $this->tools->sql_create_index('prefix_table_name', $too_long_index_name, array('c_timestamp'));
542    }
543}