ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTreeImplementationSwitch.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
24
26{
27 public const NESTED_SET_TO_MATERIALIZED_PATH = 'nested_set_to_materialized_path';
28 public const MATERIALIZED_PATH_TO_NESTED_SET = 'materialized_path_to_nested_set';
29
30 private string $mode;
31
32 public function __construct(string $mode)
33 {
35 $this->mode = $mode;
36 }
37
38 public function getHash(): string
39 {
40 return hash('sha256', self::class);
41 }
42
43 public function getLabel(): string
44 {
45 if ($this->mode === self::MATERIALIZED_PATH_TO_NESTED_SET) {
46 return 'The tree implementation is switched to nested set';
47 }
48 return 'The tree implementation is switched to materialized path';
49 }
50
51 public function isNotable(): bool
52 {
53 return true;
54 }
55
56 public function getPreconditions(Environment $environment): array
57 {
58 return [
61 ];
62 }
63
64 public function achieve(Environment $environment): Environment
65 {
66 $db = $environment->getResource(Environment::RESOURCE_DATABASE);
67 $settings_factory = $environment->getResource(Environment::RESOURCE_SETTINGS_FACTORY);
68
69 $is_nested_set = $settings_factory->settingsFor('common')->get('main_tree_impl', 'ns') === 'ns';
70
71 if ($this->mode === self::NESTED_SET_TO_MATERIALIZED_PATH && $is_nested_set) {
73
74 $db->dropIndexByFields('tree', ['lft']);
75 $db->dropIndexByFields('tree', ['path']);
76 $db->addIndex('tree', ['path'], 'i4');
77
78 $settings_factory->settingsFor('common')->set('main_tree_impl', 'mp');
79 } elseif ($this->mode === self::MATERIALIZED_PATH_TO_NESTED_SET && !$is_nested_set) {
80 $renumber_callable = function (ilDBInterface $db) {
81 $this->renumberNestedSet($db, 1, 1);
82 };
83 $ilAtomQuery = $db->buildAtomQuery();
84 $ilAtomQuery->addTableLock('tree');
85
86 $ilAtomQuery->addQueryCallable($renumber_callable);
87 $ilAtomQuery->run();
88
89 $db->dropIndexByFields('tree', ['lft']);
90 $db->dropIndexByFields('tree', ['path']);
91 $db->addIndex('tree', ['lft'], 'i4');
92
93 $settings_factory->settingsFor('common')->set('main_tree_impl', 'ns');
94 } else {
95 throw new UnachievableException('The tree implementation switch does already equal the requested mode');
96 }
97
98 return $environment;
99 }
100
101 private function renumberNestedSet(ilDBInterface $db, int $node_id, int $i): int
102 {
103 $db->manipulateF(
104 'UPDATE tree SET lft = %s WHERE child = %s',
106 [$i, $node_id]
107 );
108
109 $query = 'SELECT child FROM tree WHERE parent = ' . $db->quote($node_id, ilDBConstants::T_INTEGER) . ' ORDER BY lft';
110 $res = $db->query($query);
111
112 $children = [];
113 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
114 $children[] = (int) $row->child;
115 }
116
117 foreach ($children as $child) {
118 $i = $this->renumberNestedSet($db, $child, $i + 1);
119 }
120 $i++;
121
122 if (count($children) > 0) {
123 $i += 100;
124 }
125
126 $query = 'UPDATE tree SET rgt = %s WHERE child = %s';
127 $db->manipulateF(
128 $query,
130 [$i, $node_id]
131 );
132
133 return $i;
134 }
135
136 public function isApplicable(Environment $environment): bool
137 {
138 $settings_factory = $environment->getResource(Environment::RESOURCE_SETTINGS_FACTORY);
139
140 $is_nested_set = $settings_factory->settingsFor('common')->get('main_tree_impl', 'ns') === 'ns';
141
142 if ($this->mode === self::MATERIALIZED_PATH_TO_NESTED_SET) {
143 return !$is_nested_set;
144 }
145
146 return $is_nested_set;
147 }
148}
A configuration with no content.
Definition: NullConfig.php:27
Signals that some goal won't be achievable by actions of the system ever.
static createFromParentRelation(ilDBInterface $db)
renumberNestedSet(ilDBInterface $db, int $node_id, int $i)
An environment holds resources to be used in the setup process.
Definition: Environment.php:28
getResource(string $id)
Consumers of this method should check if the result is what they expect, e.g.
Interface ilDBInterface.
quote($value, string $type)
manipulateF(string $query, array $types, array $values)
query(string $query)
Run a (read-only) Query on the database.
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc