mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 14:18:52 +00:00
Merge PR #1101 branch 'develop-olympus' into develop
* develop-olympus: [ticket/11219] Coding guidelines and naming consistency changes [ticket/11219] Only update sequences that are affected by a fixture [ticket/11219] Recreate Oracle sequences instead of altering them [ticket/11219] Add unit test for inserting into a sequence column [ticket/11219] Update sequence values after loading fixtures
This commit is contained in:
commit
2364d4b217
3 changed files with 181 additions and 1 deletions
55
tests/dbal/write_sequence_test.php
Normal file
55
tests/dbal/write_sequence_test.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package testing
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
|
||||||
|
|
||||||
|
class phpbb_dbal_write_sequence_test extends phpbb_database_test_case
|
||||||
|
{
|
||||||
|
public function getDataSet()
|
||||||
|
{
|
||||||
|
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/three_users.xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function write_sequence_data()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'ticket/11219',
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider write_sequence_data
|
||||||
|
*/
|
||||||
|
public function test_write_sequence($username, $expected)
|
||||||
|
{
|
||||||
|
$db = $this->new_dbal();
|
||||||
|
|
||||||
|
$sql = 'INSERT INTO phpbb_users ' . $db->sql_build_array('INSERT', array(
|
||||||
|
'username' => $username,
|
||||||
|
'username_clean' => $username,
|
||||||
|
'user_permissions' => '',
|
||||||
|
'user_sig' => '',
|
||||||
|
'user_occ' => '',
|
||||||
|
'user_interests' => '',
|
||||||
|
));
|
||||||
|
$db->sql_query($sql);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $db->sql_nextid());
|
||||||
|
|
||||||
|
$sql = "SELECT user_id
|
||||||
|
FROM phpbb_users
|
||||||
|
WHERE username_clean = '" . $db->sql_escape($username) . "'";
|
||||||
|
$result = $db->sql_query_limit($sql, 1);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $db->sql_fetchfield('user_id'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,8 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
|
||||||
|
|
||||||
protected $test_case_helpers;
|
protected $test_case_helpers;
|
||||||
|
|
||||||
|
protected $fixture_xml_data;
|
||||||
|
|
||||||
public function __construct($name = NULL, array $data = array(), $dataName = '')
|
public function __construct($name = NULL, array $data = array(), $dataName = '')
|
||||||
{
|
{
|
||||||
parent::__construct($name, $data, $dataName);
|
parent::__construct($name, $data, $dataName);
|
||||||
|
@ -28,6 +30,20 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
// Resynchronise tables if a fixture was loaded
|
||||||
|
if (isset($this->fixture_xml_data))
|
||||||
|
{
|
||||||
|
$config = $this->get_database_config();
|
||||||
|
$manager = $this->create_connection_manager($config);
|
||||||
|
$manager->connect();
|
||||||
|
$manager->post_setup_synchronisation($this->fixture_xml_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function createXMLDataSet($path)
|
public function createXMLDataSet($path)
|
||||||
{
|
{
|
||||||
$db_config = $this->get_database_config();
|
$db_config = $this->get_database_config();
|
||||||
|
@ -47,7 +63,9 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
|
||||||
$path = $meta_data['uri'];
|
$path = $meta_data['uri'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::createXMLDataSet($path);
|
$this->fixture_xml_data = parent::createXMLDataSet($path);
|
||||||
|
|
||||||
|
return $this->fixture_xml_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_test_case_helpers()
|
public function get_test_case_helpers()
|
||||||
|
|
|
@ -426,4 +426,111 @@ class phpbb_database_test_connection_manager
|
||||||
$this->pdo->exec($query);
|
$this->pdo->exec($query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs synchronisations on the database after a fixture has been loaded
|
||||||
|
*
|
||||||
|
* @param PHPUnit_Extensions_Database_DataSet_XmlDataSet $xml_data_set Information about the tables contained within the loaded fixture
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function post_setup_synchronisation($xml_data_set)
|
||||||
|
{
|
||||||
|
$this->ensure_connected(__METHOD__);
|
||||||
|
$queries = array();
|
||||||
|
|
||||||
|
// Get escaped versions of the table names used in the fixture
|
||||||
|
$table_names = array_map(array($this->pdo, 'PDO::quote'), $xml_data_set->getTableNames());
|
||||||
|
|
||||||
|
switch ($this->config['dbms'])
|
||||||
|
{
|
||||||
|
case 'oracle':
|
||||||
|
// Get all of the information about the sequences
|
||||||
|
$sql = "SELECT t.table_name, tc.column_name, d.referenced_name as sequence_name, s.increment_by, s.min_value
|
||||||
|
FROM USER_TRIGGERS t
|
||||||
|
JOIN USER_DEPENDENCIES d ON (d.name = t.trigger_name)
|
||||||
|
JOIN USER_TRIGGER_COLS tc ON (tc.trigger_name = t.trigger_name)
|
||||||
|
JOIN USER_SEQUENCES s ON (s.sequence_name = d.referenced_name)
|
||||||
|
WHERE d.referenced_type = 'SEQUENCE'
|
||||||
|
AND d.type = 'TRIGGER'
|
||||||
|
AND t.table_name IN (" . implode(', ', array_map('strtoupper', $table_names)) . ')';
|
||||||
|
|
||||||
|
$result = $this->pdo->query($sql);
|
||||||
|
|
||||||
|
while ($row = $result->fetch(PDO::FETCH_ASSOC))
|
||||||
|
{
|
||||||
|
// Get the current max value of the table
|
||||||
|
$sql = "SELECT MAX({$row['COLUMN_NAME']}) AS max FROM {$row['TABLE_NAME']}";
|
||||||
|
$max_result = $this->pdo->query($sql);
|
||||||
|
$max_row = $max_result->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$max_row)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_val = (int) $max_row['MAX'];
|
||||||
|
$max_val++;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is not the "proper" way, but the proper way does not allow you to completely reset
|
||||||
|
* tables with no rows since you have to select the next value to make the change go into effect.
|
||||||
|
* You would have to go past the minimum value to set it correctly, but that's illegal.
|
||||||
|
* Since we have no objects attached to our sequencers (triggers aren't attached), this works fine.
|
||||||
|
*/
|
||||||
|
$queries[] = 'DROP SEQUENCE ' . $row['SEQUENCE_NAME'];
|
||||||
|
$queries[] = "CREATE SEQUENCE {$row['SEQUENCE_NAME']}
|
||||||
|
MINVALUE {$row['MIN_VALUE']}
|
||||||
|
INCREMENT BY {$row['INCREMENT_BY']}
|
||||||
|
START WITH $max_val";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'postgres':
|
||||||
|
// Get the sequences attached to the tables
|
||||||
|
$sql = 'SELECT column_name, table_name FROM information_schema.columns
|
||||||
|
WHERE table_name IN (' . implode(', ', $table_names) . ")
|
||||||
|
AND strpos(column_default, '_seq''::regclass') > 0";
|
||||||
|
$result = $this->pdo->query($sql);
|
||||||
|
|
||||||
|
$setval_queries = array();
|
||||||
|
while ($row = $result->fetch(PDO::FETCH_ASSOC))
|
||||||
|
{
|
||||||
|
// Get the columns used in the fixture for this table
|
||||||
|
$column_names = $xml_data_set->getTableMetaData($row['table_name'])->getColumns();
|
||||||
|
|
||||||
|
// Skip sequences that weren't specified in the fixture
|
||||||
|
if (!in_array($row['column_name'], $column_names))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the old value if it exists, or use 1 if it doesn't
|
||||||
|
$sql = "SELECT COALESCE((SELECT MAX({$row['column_name']}) + 1 FROM {$row['table_name']}), 1) AS val";
|
||||||
|
$result_max = $this->pdo->query($sql);
|
||||||
|
$row_max = $result_max->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($row_max)
|
||||||
|
{
|
||||||
|
$seq_name = $this->pdo->quote($row['table_name'] . '_seq');
|
||||||
|
$max_val = (int) $row_max['val'];
|
||||||
|
|
||||||
|
// The last parameter is false so that the system doesn't increment it again
|
||||||
|
$setval_queries[] = "SETVAL($seq_name, $max_val, false)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine all of the SETVALs into one query
|
||||||
|
if (sizeof($setval_queries))
|
||||||
|
{
|
||||||
|
$queries[] = 'SELECT ' . implode(', ', $setval_queries);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($queries as $query)
|
||||||
|
{
|
||||||
|
$this->pdo->exec($query);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue