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