Skip to content

Commit fdb849f

Browse files
committed
Refactor migrations to handle postgresql specifically
1 parent 40d0c91 commit fdb849f

File tree

2 files changed

+134
-3
lines changed

2 files changed

+134
-3
lines changed

migrations/v20x/m15_language_iso.php renamed to migrations/v20x/m15_update_lang_schema.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,18 @@
1010

1111
namespace phpbb\boardrules\migrations\v20x;
1212

13-
class m15_language_iso extends \phpbb\db\migration\container_aware_migration
13+
class m15_update_lang_schema extends \phpbb\db\migration\migration
1414
{
15+
/**
16+
* @inheritDoc
17+
*
18+
* This migration is incompatible with PostgreSQL
19+
*/
20+
public function effectively_installed()
21+
{
22+
return $this->db->get_sql_layer() === 'postgres';
23+
}
24+
1525
/**
1626
* @inheritDoc
1727
*/
@@ -34,6 +44,11 @@ public function update_schema()
3444
'rule_language' => array('VCHAR:30', ''),
3545
),
3646
),
47+
'add_index' => array(
48+
$this->table_prefix . 'boardrules' => array(
49+
'rule_language' => array('rule_language'),
50+
),
51+
),
3752
);
3853
}
3954

@@ -43,9 +58,9 @@ public function update_schema()
4358
public function revert_schema()
4459
{
4560
return array(
46-
'change_columns' => array(
61+
'drop_keys' => array(
4762
$this->table_prefix . 'boardrules' => array(
48-
'rule_language' => array('UINT', ''),
63+
'rule_language',
4964
),
5065
),
5166
);
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
/**
3+
*
4+
* Board Rules extension for the phpBB Forum Software package.
5+
*
6+
* @copyright (c) 2017 phpBB Limited <https://www.phpbb.com>
7+
* @license GNU General Public License, version 2 (GPL-2.0)
8+
*
9+
*/
10+
11+
namespace phpbb\boardrules\migrations\v20x;
12+
13+
class m16_update_lang_postgres extends \phpbb\db\migration\migration
14+
{
15+
/**
16+
* @inheritDoc
17+
*
18+
* This migration is only for PostgreSQL
19+
*/
20+
public function effectively_installed()
21+
{
22+
return strpos($this->db->get_sql_layer(), 'postgres') === false;
23+
}
24+
25+
/**
26+
* @inheritDoc
27+
*/
28+
static public function depends_on()
29+
{
30+
return array(
31+
'\phpbb\boardrules\migrations\v10x\m7_sample_rule_data',
32+
'\phpbb\boardrules\migrations\v20x\m14_reparse',
33+
'\phpbb\boardrules\migrations\v20x\m15_update_lang_schema',
34+
);
35+
}
36+
37+
/**
38+
* @inheritDoc
39+
*/
40+
public function update_data()
41+
{
42+
return array(
43+
array('custom', array(array($this, 'alter_rule_language'))),
44+
);
45+
}
46+
47+
/**
48+
* Alter rule_language column for PostgreSQL
49+
*
50+
* PostgreSQL does not allow us to change a column's data type if it
51+
* already contains values, so the normal 'change_columns' action fails.
52+
* To work around this, we re-create a new rule_language column with
53+
* the new data type and copy the new data to it via specific queries.
54+
*
55+
* @throws \RuntimeException
56+
*/
57+
public function alter_rule_language()
58+
{
59+
// Ensure we are only processing this on postgresql dbms
60+
if (strpos($this->db->get_sql_layer(), 'postgres') === false)
61+
{
62+
return;
63+
}
64+
65+
$boardrules_table = $this->table_prefix . 'boardrules';
66+
67+
// Rename existing column to a temporary name
68+
$sql = 'ALTER TABLE ' . $boardrules_table . '
69+
RENAME COLUMN rule_language TO old_rule_language';
70+
$this->db->sql_query($sql);
71+
72+
// Stop running if column rename failed (custom language must be hardcoded)
73+
if (!$this->db_tools->sql_column_exists($boardrules_table , 'old_rule_language'))
74+
{
75+
throw new \RuntimeException('The column ‘rule_language’ could not be renamed.');
76+
}
77+
78+
// Add a new rule_language column
79+
$this->db_tools->sql_column_add($boardrules_table, 'rule_language', array('VCHAR:30', ''));
80+
81+
// Stop running if add column failed (custom language must be hardcoded)
82+
if (!$this->db_tools->sql_column_exists($boardrules_table, 'rule_language'))
83+
{
84+
throw new \RuntimeException('The column ‘rule_language’ could not be created.');
85+
}
86+
87+
// Add an index for the rule_language column
88+
$this->db_tools->sql_create_index($boardrules_table, 'rule_language', 'rule_language');
89+
90+
// Get installed language identifiers and iso codes
91+
$sql = 'SELECT lang_id, lang_iso
92+
FROM ' . LANG_TABLE;
93+
$result = $this->db->sql_query($sql);
94+
$rows = $this->db->sql_fetchrowset($result);
95+
$this->db->sql_freeresult($result);
96+
97+
// Update the languages in the boardrules table, from id to iso
98+
if (!empty($rows))
99+
{
100+
$this->db->sql_transaction('begin');
101+
102+
foreach ($rows as $row)
103+
{
104+
$sql = 'UPDATE ' . $boardrules_table . "
105+
SET rule_language = '" . $this->db->sql_escape($row['lang_iso']) . "'
106+
WHERE old_rule_language = " . (int) $row['lang_id'];
107+
$this->db->sql_query($sql);
108+
}
109+
110+
$this->db->sql_transaction('commit');
111+
}
112+
113+
// Drop the temporary column
114+
$this->db_tools->sql_column_remove($boardrules_table, 'old_rule_language');
115+
}
116+
}

0 commit comments

Comments
 (0)