mirror of
https://github.com/phpbb/phpbb.git
synced 2025-02-24 03:54:10 +01:00
Merge PR #1101 branch 'Noxwizard/ticket/11219' into develop-olympus
* Noxwizard/ticket/11219: [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
18bcb9f804
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 $fixture_xml_data;
|
||||
|
||||
public function __construct($name = NULL, array $data = array(), $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)
|
||||
{
|
||||
$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'];
|
||||
}
|
||||
|
||||
return parent::createXMLDataSet($path);
|
||||
$this->fixture_xml_data = parent::createXMLDataSet($path);
|
||||
|
||||
return $this->fixture_xml_data;
|
||||
}
|
||||
|
||||
public function get_test_case_helpers()
|
||||
|
@ -426,4 +426,111 @@ class phpbb_database_test_connection_manager
|
||||
$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…
x
Reference in New Issue
Block a user