@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3abstract class PhabricatorConfigStorageSchema extends Phobject {
4
5 const ISSUE_MISSING = 'missing';
6 const ISSUE_MISSINGKEY = 'missingkey';
7 const ISSUE_SURPLUS = 'surplus';
8 const ISSUE_SURPLUSKEY = 'surpluskey';
9 const ISSUE_CHARSET = 'charset';
10 const ISSUE_COLLATION = 'collation';
11 const ISSUE_COLUMNTYPE = 'columntype';
12 const ISSUE_NULLABLE = 'nullable';
13 const ISSUE_KEYCOLUMNS = 'keycolumns';
14 const ISSUE_UNIQUE = 'unique';
15 const ISSUE_LONGKEY = 'longkey';
16 const ISSUE_SUBWARN = 'subwarn';
17 const ISSUE_SUBFAIL = 'subfail';
18 const ISSUE_AUTOINCREMENT = 'autoincrement';
19 const ISSUE_UNKNOWN = 'unknown';
20 const ISSUE_ACCESSDENIED = 'accessdenied';
21 const ISSUE_ENGINE = 'engine';
22
23 const STATUS_OKAY = 'okay';
24 const STATUS_WARN = 'warn';
25 const STATUS_FAIL = 'fail';
26
27 private $issues = array();
28 private $name;
29
30 abstract public function newEmptyClone();
31 abstract protected function compareToSimilarSchema(
32 PhabricatorConfigStorageSchema $expect);
33 abstract protected function getSubschemata();
34
35 public function compareTo(PhabricatorConfigStorageSchema $expect) {
36 if (get_class($expect) != get_class($this)) {
37 throw new Exception(pht('Classes must match to compare schemata!'));
38 }
39
40 if ($this->getName() != $expect->getName()) {
41 throw new Exception(pht('Names must match to compare schemata!'));
42 }
43
44 return $this->compareToSimilarSchema($expect);
45 }
46
47 public function setName($name) {
48 $this->name = $name;
49 return $this;
50 }
51
52 public function getName() {
53 return $this->name;
54 }
55
56 public function setIssues(array $issues) {
57 $this->issues = array_fuse($issues);
58 return $this;
59 }
60
61 public function getIssues() {
62 $issues = $this->issues;
63
64 foreach ($this->getSubschemata() as $sub) {
65 switch ($sub->getStatus()) {
66 case self::STATUS_WARN:
67 $issues[self::ISSUE_SUBWARN] = self::ISSUE_SUBWARN;
68 break;
69 case self::STATUS_FAIL:
70 $issues[self::ISSUE_SUBFAIL] = self::ISSUE_SUBFAIL;
71 break;
72 }
73 }
74
75 return $issues;
76 }
77
78 public function getLocalIssues() {
79 return $this->issues;
80 }
81
82 public function hasIssue($issue) {
83 return (bool)idx($this->getIssues(), $issue);
84 }
85
86 public function getAllIssues() {
87 $issues = $this->getIssues();
88 foreach ($this->getSubschemata() as $sub) {
89 $issues += $sub->getAllIssues();
90 }
91 return $issues;
92 }
93
94 public function getStatus() {
95 $status = self::STATUS_OKAY;
96 foreach ($this->getAllIssues() as $issue) {
97 $issue_status = self::getIssueStatus($issue);
98 $status = self::getStrongestStatus($status, $issue_status);
99 }
100 return $status;
101 }
102
103 public static function getIssueName($issue) {
104 switch ($issue) {
105 case self::ISSUE_MISSING:
106 return pht('Missing');
107 case self::ISSUE_MISSINGKEY:
108 return pht('Missing Key');
109 case self::ISSUE_SURPLUS:
110 return pht('Surplus');
111 case self::ISSUE_SURPLUSKEY:
112 return pht('Surplus Key');
113 case self::ISSUE_CHARSET:
114 return pht('Better Character Set Available');
115 case self::ISSUE_COLLATION:
116 return pht('Better Collation Available');
117 case self::ISSUE_COLUMNTYPE:
118 return pht('Wrong Column Type');
119 case self::ISSUE_NULLABLE:
120 return pht('Wrong Nullable Setting');
121 case self::ISSUE_KEYCOLUMNS:
122 return pht('Key on Wrong Columns');
123 case self::ISSUE_UNIQUE:
124 return pht('Key has Wrong Uniqueness');
125 case self::ISSUE_LONGKEY:
126 return pht('Key is Too Long');
127 case self::ISSUE_SUBWARN:
128 return pht('Subschemata Have Warnings');
129 case self::ISSUE_SUBFAIL:
130 return pht('Subschemata Have Failures');
131 case self::ISSUE_AUTOINCREMENT:
132 return pht('Column has Wrong Autoincrement');
133 case self::ISSUE_UNKNOWN:
134 return pht('Column Has No Specification');
135 case self::ISSUE_ACCESSDENIED:
136 return pht('Access Denied');
137 case self::ISSUE_ENGINE:
138 return pht('Better Table Engine Available');
139 default:
140 throw new Exception(pht('Unknown schema issue "%s"!', $issue));
141 }
142 }
143
144 public static function getIssueDescription($issue) {
145 switch ($issue) {
146 case self::ISSUE_MISSING:
147 return pht('This schema is expected to exist, but does not.');
148 case self::ISSUE_MISSINGKEY:
149 return pht('This key is expected to exist, but does not.');
150 case self::ISSUE_SURPLUS:
151 return pht('This schema is not expected to exist.');
152 case self::ISSUE_SURPLUSKEY:
153 return pht('This key is not expected to exist.');
154 case self::ISSUE_CHARSET:
155 return pht('This schema can use a better character set.');
156 case self::ISSUE_COLLATION:
157 return pht('This schema can use a better collation.');
158 case self::ISSUE_COLUMNTYPE:
159 return pht('This schema can use a better column type.');
160 case self::ISSUE_NULLABLE:
161 return pht('This schema has the wrong nullable setting.');
162 case self::ISSUE_KEYCOLUMNS:
163 return pht('This key is on the wrong columns.');
164 case self::ISSUE_UNIQUE:
165 return pht('This key has the wrong uniqueness setting.');
166 case self::ISSUE_LONGKEY:
167 return pht('This key is too long for utf8mb4.');
168 case self::ISSUE_SUBWARN:
169 return pht('Subschemata have setup warnings.');
170 case self::ISSUE_SUBFAIL:
171 return pht('Subschemata have setup failures.');
172 case self::ISSUE_AUTOINCREMENT:
173 return pht('This column has the wrong autoincrement setting.');
174 case self::ISSUE_UNKNOWN:
175 return pht('This column is missing a type specification.');
176 case self::ISSUE_ENGINE:
177 return pht('This table can use a better table engine.');
178 default:
179 throw new Exception(pht('Unknown schema issue "%s"!', $issue));
180 }
181 }
182
183 public static function getIssueStatus($issue) {
184 switch ($issue) {
185 case self::ISSUE_MISSING:
186 case self::ISSUE_ACCESSDENIED:
187 case self::ISSUE_SURPLUS:
188 case self::ISSUE_NULLABLE:
189 case self::ISSUE_SUBFAIL:
190 case self::ISSUE_UNKNOWN:
191 return self::STATUS_FAIL;
192 case self::ISSUE_SUBWARN:
193 case self::ISSUE_COLUMNTYPE:
194 case self::ISSUE_CHARSET:
195 case self::ISSUE_COLLATION:
196 case self::ISSUE_MISSINGKEY:
197 case self::ISSUE_SURPLUSKEY:
198 case self::ISSUE_UNIQUE:
199 case self::ISSUE_KEYCOLUMNS:
200 case self::ISSUE_LONGKEY:
201 case self::ISSUE_AUTOINCREMENT:
202 case self::ISSUE_ENGINE:
203 return self::STATUS_WARN;
204 default:
205 throw new Exception(pht('Unknown schema issue "%s"!', $issue));
206 }
207 }
208
209 public static function getStatusSeverity($status) {
210 switch ($status) {
211 case self::STATUS_FAIL:
212 return 2;
213 case self::STATUS_WARN:
214 return 1;
215 case self::STATUS_OKAY:
216 return 0;
217 default:
218 throw new Exception(pht('Unknown schema status "%s"!', $status));
219 }
220 }
221
222 public static function getStrongestStatus($u, $v) {
223 $u_sev = self::getStatusSeverity($u);
224 $v_sev = self::getStatusSeverity($v);
225
226 if ($u_sev >= $v_sev) {
227 return $u;
228 } else {
229 return $v;
230 }
231 }
232
233
234}