Conditions | 8 |
Paths | 34 |
Total Lines | 146 |
Code Lines | 95 |
Lines | 0 |
Ratio | 0 % |
Changes | 10 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
38 | public function upgrade(): void |
||
39 | { |
||
40 | // It is simpler to create a new table than to update the existing one. |
||
41 | |||
42 | if (!DB::schema()->hasTable('place_location')) { |
||
43 | DB::schema()->create('place_location', static function (Blueprint $table): void { |
||
44 | $table->integer('id', true); |
||
45 | $table->integer('parent_id')->nullable(); |
||
46 | $table->string('place', 120); |
||
47 | $table->double('latitude')->nullable(); |
||
48 | $table->double('longitude')->nullable(); |
||
49 | |||
50 | $table->unique(['parent_id', 'place']); |
||
51 | $table->unique(['place', 'parent_id']); |
||
52 | |||
53 | $table->index(['latitude']); |
||
54 | $table->index(['longitude']); |
||
55 | }); |
||
56 | |||
57 | DB::schema()->table('place_location', static function (Blueprint $table): void { |
||
58 | $table->foreign(['parent_id']) |
||
59 | ->references(['id']) |
||
60 | ->on('place_location') |
||
61 | ->onDelete('CASCADE') |
||
62 | ->onUpdate('CASCADE'); |
||
63 | }); |
||
64 | } |
||
65 | |||
66 | if (DB::schema()->hasTable('placelocation')) { |
||
67 | DB::table('placelocation') |
||
68 | ->where('pl_lati', '=', '') |
||
69 | ->orWhere('pl_long', '=', '') |
||
70 | ->update([ |
||
71 | 'pl_lati' => null, |
||
72 | 'pl_long' => null, |
||
73 | ]); |
||
74 | |||
75 | // Missing/invalid parents? Move them to the top level |
||
76 | DB::table('placelocation AS pl1') |
||
77 | ->leftJoin('placelocation AS pl2', 'pl1.pl_parent_id', '=', 'pl2.pl_id') |
||
78 | ->whereNull('pl2.pl_id') |
||
79 | ->update([ |
||
80 | 'pl1.pl_parent_id' => 0, |
||
81 | ]); |
||
82 | |||
83 | // Remove invalid values. |
||
84 | if (DB::connection()->getDriverName() === 'mysql') { |
||
85 | DB::table('placelocation') |
||
86 | ->where('pl_lati', 'NOT REGEXP', '[^NS][0-9]+[.]?[0-9]*$') |
||
87 | ->orWhere('pl_long', 'NOT REGEXP', '[^EW][0-9]+[.]?[0-9]*$') |
||
88 | ->update([ |
||
89 | 'pl_lati' => '', |
||
90 | 'pl_long' => '', |
||
91 | ]); |
||
92 | } |
||
93 | |||
94 | // The existing data may have placenames that only differ after the first 120 chars. |
||
95 | // Need to remove the constraint before we truncate/merge them. |
||
96 | try { |
||
97 | DB::schema()->table('placelocation', static function (Blueprint $table): void { |
||
98 | $table->dropUnique(['pl_parent_id', 'pl_place']); |
||
99 | }); |
||
100 | } catch (PDOException $ex) { |
||
101 | // Already deleted, or does not exist; |
||
102 | } |
||
103 | |||
104 | DB::table('placelocation') |
||
105 | ->update([ |
||
106 | 'pl_place' => new Expression('SUBSTR(pl_place, 1, 120)'), |
||
107 | ]); |
||
108 | |||
109 | // The lack of unique key constraints means that there may be duplicates... |
||
110 | while (true) { |
||
111 | // Two places with the same name and parent... |
||
112 | $row = DB::table('placelocation') |
||
113 | ->select([ |
||
114 | new Expression('MIN(pl_id) AS min'), |
||
115 | new Expression('MAX(pl_id) AS max'), |
||
116 | ]) |
||
117 | ->groupBy(['pl_parent_id', 'pl_place']) |
||
118 | ->having(new Expression('COUNT(*)'), '>', '1') |
||
119 | ->first(); |
||
120 | |||
121 | if ($row === null) { |
||
122 | break; |
||
123 | } |
||
124 | |||
125 | // ...move children to the first |
||
126 | DB::table('placelocation') |
||
127 | ->where('pl_parent_id', '=', $row->max) |
||
128 | ->update(['pl_parent_id' => $row->min]); |
||
129 | |||
130 | // ...delete the second |
||
131 | DB::table('placelocation') |
||
132 | ->where('pl_id', '=', $row->max) |
||
133 | ->delete(); |
||
134 | } |
||
135 | |||
136 | // This is the SQL standard. It works with Postgres, Sqlite and MySQL 8 |
||
137 | $select1 = DB::table('placelocation') |
||
138 | ->leftJoin('place_location', 'id', '=', 'pl_id') |
||
139 | ->whereNull('id') |
||
140 | ->orderBy('pl_level') |
||
141 | ->orderBy('pl_id') |
||
142 | ->select([ |
||
143 | 'pl_id', |
||
144 | new Expression('CASE pl_parent_id WHEN 0 THEN NULL ELSE pl_parent_id END'), |
||
145 | 'pl_place', |
||
146 | new Expression("CAST(REPLACE(REPLACE(pl_lati, 'S', '-'), 'N', '') AS FLOAT)"), |
||
147 | new Expression("CAST(REPLACE(REPLACE(pl_long, 'W', '-'), 'E', '') AS FLOAT)"), |
||
148 | ]); |
||
149 | |||
150 | // This works for MySQL 5.7 and lower, which cannot cast to FLOAT |
||
151 | $select2 = DB::table('placelocation') |
||
152 | ->leftJoin('place_location', 'id', '=', 'pl_id') |
||
153 | ->whereNull('id') |
||
154 | ->orderBy('pl_level') |
||
155 | ->orderBy('pl_id') |
||
156 | ->select([ |
||
157 | 'pl_id', |
||
158 | new Expression('CASE pl_parent_id WHEN 0 THEN NULL ELSE pl_parent_id END'), |
||
159 | 'pl_place', |
||
160 | new Expression("REPLACE(REPLACE(pl_lati, 'S', '-'), 'N', '')"), |
||
161 | new Expression("REPLACE(REPLACE(pl_long, 'W', '-'), 'E', '')"), |
||
162 | ]); |
||
163 | |||
164 | try { |
||
165 | DB::table('place_location') |
||
166 | ->insertUsing(['id', 'parent_id', 'place', 'latitude', 'longitude'], $select1); |
||
167 | } catch (PDOException $ex) { |
||
168 | DB::table('place_location') |
||
169 | ->insertUsing(['id', 'parent_id', 'place', 'latitude', 'longitude'], $select2); |
||
170 | } |
||
171 | |||
172 | DB::schema()->drop('placelocation'); |
||
173 | } |
||
174 | |||
175 | // Earlier versions of webtrees used 0 and NULL interchangeably. |
||
176 | // Assume 0 at the country-level and NULL at lower levels. |
||
177 | DB::table('place_location') |
||
178 | ->whereNotNull('parent_id') |
||
179 | ->where('latitude', '=', 0) |
||
180 | ->where('longitude', '=', 0) |
||
181 | ->update([ |
||
182 | 'latitude' => null, |
||
183 | 'longitude' => null, |
||
184 | ]); |
||
187 |