@@ 11-314 (lines=304) @@ | ||
8 | use Nwidart\Modules\Module; |
|
9 | use Nwidart\Modules\Support\Config\GenerateConfigReader; |
|
10 | ||
11 | class LumenMigrator |
|
12 | { |
|
13 | /** |
|
14 | * Module instance. |
|
15 | * @var Module |
|
16 | */ |
|
17 | protected $module; |
|
18 | ||
19 | /** |
|
20 | * Laravel Application instance. |
|
21 | * |
|
22 | * @var Application. |
|
23 | */ |
|
24 | protected $laravel; |
|
25 | ||
26 | /** |
|
27 | * The database connection to be used |
|
28 | * |
|
29 | * @var string |
|
30 | */ |
|
31 | protected $database = ''; |
|
32 | ||
33 | /** |
|
34 | * Create new instance. |
|
35 | * @param Module $module |
|
36 | * @param Application $application |
|
37 | */ |
|
38 | public function __construct(Module $module, Application $application) |
|
39 | { |
|
40 | $this->module = $module; |
|
41 | $this->laravel = $application; |
|
42 | } |
|
43 | ||
44 | /** |
|
45 | * Set the database connection to be used |
|
46 | * |
|
47 | * @param $database |
|
48 | * |
|
49 | * @return $this |
|
50 | */ |
|
51 | public function setDatabase($database) |
|
52 | { |
|
53 | if (is_string($database) && $database) { |
|
54 | $this->database = $database; |
|
55 | } |
|
56 | ||
57 | return $this; |
|
58 | } |
|
59 | ||
60 | /** |
|
61 | * @return Module |
|
62 | */ |
|
63 | public function getModule() |
|
64 | { |
|
65 | return $this->module; |
|
66 | } |
|
67 | ||
68 | /** |
|
69 | * Get migration path. |
|
70 | * |
|
71 | * @return string |
|
72 | */ |
|
73 | public function getPath() |
|
74 | { |
|
75 | $config = $this->module->get('migration'); |
|
76 | ||
77 | $migrationPath = GenerateConfigReader::read('migration'); |
|
78 | $path = (is_array($config) && array_key_exists('path', $config)) ? $config['path'] : $migrationPath->getPath(); |
|
79 | ||
80 | return $this->module->getExtraPath($path); |
|
81 | } |
|
82 | ||
83 | /** |
|
84 | * Get migration files. |
|
85 | * |
|
86 | * @param boolean $reverse |
|
87 | * @return array |
|
88 | */ |
|
89 | public function getMigrations($reverse = false) |
|
90 | { |
|
91 | $files = $this->laravel['files']->glob($this->getPath() . '/*_*.php'); |
|
92 | ||
93 | // Once we have the array of files in the directory we will just remove the |
|
94 | // extension and take the basename of the file which is all we need when |
|
95 | // finding the migrations that haven't been run against the databases. |
|
96 | if ($files === false) { |
|
97 | return []; |
|
98 | } |
|
99 | ||
100 | $files = array_map(function ($file) { |
|
101 | return str_replace('.php', '', basename($file)); |
|
102 | }, $files); |
|
103 | ||
104 | // Once we have all of the formatted file names we will sort them and since |
|
105 | // they all start with a timestamp this should give us the migrations in |
|
106 | // the order they were actually created by the application developers. |
|
107 | sort($files); |
|
108 | ||
109 | if ($reverse) { |
|
110 | return array_reverse($files); |
|
111 | } |
|
112 | ||
113 | return $files; |
|
114 | } |
|
115 | ||
116 | /** |
|
117 | * Rollback migration. |
|
118 | * |
|
119 | * @return array |
|
120 | */ |
|
121 | public function rollback() |
|
122 | { |
|
123 | $migrations = $this->getLast($this->getMigrations(true)); |
|
124 | ||
125 | $this->requireFiles($migrations->toArray()); |
|
126 | ||
127 | $migrated = []; |
|
128 | ||
129 | foreach ($migrations as $migration) { |
|
130 | $data = $this->find($migration); |
|
131 | ||
132 | if ($data->count()) { |
|
133 | $migrated[] = $migration; |
|
134 | ||
135 | $this->down($migration); |
|
136 | ||
137 | $data->delete(); |
|
138 | } |
|
139 | } |
|
140 | ||
141 | return $migrated; |
|
142 | } |
|
143 | ||
144 | /** |
|
145 | * Reset migration. |
|
146 | * |
|
147 | * @return array |
|
148 | */ |
|
149 | public function reset() |
|
150 | { |
|
151 | $migrations = $this->getMigrations(true); |
|
152 | ||
153 | $this->requireFiles($migrations); |
|
154 | ||
155 | $migrated = []; |
|
156 | ||
157 | foreach ($migrations as $migration) { |
|
158 | $data = $this->find($migration); |
|
159 | ||
160 | if ($data->count()) { |
|
161 | $migrated[] = $migration; |
|
162 | ||
163 | $this->down($migration); |
|
164 | ||
165 | $data->delete(); |
|
166 | } |
|
167 | } |
|
168 | ||
169 | return $migrated; |
|
170 | } |
|
171 | ||
172 | /** |
|
173 | * Run down schema from the given migration name. |
|
174 | * |
|
175 | * @param string $migration |
|
176 | */ |
|
177 | public function down($migration) |
|
178 | { |
|
179 | $this->resolve($migration)->down(); |
|
180 | } |
|
181 | ||
182 | /** |
|
183 | * Run up schema from the given migration name. |
|
184 | * |
|
185 | * @param string $migration |
|
186 | */ |
|
187 | public function up($migration) |
|
188 | { |
|
189 | $this->resolve($migration)->up(); |
|
190 | } |
|
191 | ||
192 | /** |
|
193 | * Resolve a migration instance from a file. |
|
194 | * |
|
195 | * @param string $file |
|
196 | * |
|
197 | * @return object |
|
198 | */ |
|
199 | public function resolve($file) |
|
200 | { |
|
201 | $file = implode('_', array_slice(explode('_', $file), 4)); |
|
202 | ||
203 | $class = Str::studly($file); |
|
204 | ||
205 | return new $class(); |
|
206 | } |
|
207 | ||
208 | /** |
|
209 | * Require in all the migration files in a given path. |
|
210 | * |
|
211 | * @param array $files |
|
212 | */ |
|
213 | public function requireFiles(array $files) |
|
214 | { |
|
215 | $path = $this->getPath(); |
|
216 | foreach ($files as $file) { |
|
217 | $this->laravel['files']->requireOnce($path . '/' . $file . '.php'); |
|
218 | } |
|
219 | } |
|
220 | ||
221 | /** |
|
222 | * Get table instance. |
|
223 | * |
|
224 | * @return \Illuminate\Database\Query\Builder |
|
225 | */ |
|
226 | public function table() |
|
227 | { |
|
228 | return $this->laravel['db']->connection($this->database ?: null)->table(config('database.migrations')); |
|
229 | } |
|
230 | ||
231 | /** |
|
232 | * Find migration data from database by given migration name. |
|
233 | * |
|
234 | * @param string $migration |
|
235 | * |
|
236 | * @return object |
|
237 | */ |
|
238 | public function find($migration) |
|
239 | { |
|
240 | return $this->table()->whereMigration($migration); |
|
241 | } |
|
242 | ||
243 | /** |
|
244 | * Save new migration to database. |
|
245 | * |
|
246 | * @param string $migration |
|
247 | * |
|
248 | * @return mixed |
|
249 | */ |
|
250 | public function log($migration) |
|
251 | { |
|
252 | return $this->table()->insert([ |
|
253 | 'migration' => $migration, |
|
254 | 'batch' => $this->getNextBatchNumber(), |
|
255 | ]); |
|
256 | } |
|
257 | ||
258 | /** |
|
259 | * Get the next migration batch number. |
|
260 | * |
|
261 | * @return int |
|
262 | */ |
|
263 | public function getNextBatchNumber() |
|
264 | { |
|
265 | return $this->getLastBatchNumber() + 1; |
|
266 | } |
|
267 | ||
268 | /** |
|
269 | * Get the last migration batch number. |
|
270 | * |
|
271 | * @param array|null $migrations |
|
272 | * @return int |
|
273 | */ |
|
274 | public function getLastBatchNumber($migrations = null) |
|
275 | { |
|
276 | $table = $this->table(); |
|
277 | ||
278 | if (is_array($migrations)) { |
|
279 | $table = $table->whereIn('migration', $migrations); |
|
280 | } |
|
281 | ||
282 | return $table->max('batch'); |
|
283 | } |
|
284 | ||
285 | /** |
|
286 | * Get the last migration batch. |
|
287 | * |
|
288 | * @param array $migrations |
|
289 | * |
|
290 | * @return Collection |
|
291 | */ |
|
292 | public function getLast($migrations) |
|
293 | { |
|
294 | $query = $this->table() |
|
295 | ->where('batch', $this->getLastBatchNumber($migrations)) |
|
296 | ->whereIn('migration', $migrations); |
|
297 | ||
298 | $result = $query->orderBy('migration', 'desc')->get(); |
|
299 | ||
300 | return collect($result)->map(function ($item) { |
|
301 | return (array) $item; |
|
302 | })->pluck('migration'); |
|
303 | } |
|
304 | ||
305 | /** |
|
306 | * Get the ran migrations. |
|
307 | * |
|
308 | * @return Collection |
|
309 | */ |
|
310 | public function getRan() |
|
311 | { |
|
312 | return $this->table()->pluck('migration'); |
|
313 | } |
|
314 | } |
|
315 |
@@ 11-314 (lines=304) @@ | ||
8 | use Nwidart\Modules\Module; |
|
9 | use Nwidart\Modules\Support\Config\GenerateConfigReader; |
|
10 | ||
11 | class Migrator |
|
12 | { |
|
13 | /** |
|
14 | * Module instance. |
|
15 | * @var Module |
|
16 | */ |
|
17 | protected $module; |
|
18 | ||
19 | /** |
|
20 | * Laravel Application instance. |
|
21 | * |
|
22 | * @var Application. |
|
23 | */ |
|
24 | protected $laravel; |
|
25 | ||
26 | /** |
|
27 | * The database connection to be used |
|
28 | * |
|
29 | * @var string |
|
30 | */ |
|
31 | protected $database = ''; |
|
32 | ||
33 | /** |
|
34 | * Create new instance. |
|
35 | * @param Module $module |
|
36 | * @param Application $application |
|
37 | */ |
|
38 | public function __construct(Module $module, Application $application) |
|
39 | { |
|
40 | $this->module = $module; |
|
41 | $this->laravel = $application; |
|
42 | } |
|
43 | ||
44 | /** |
|
45 | * Set the database connection to be used |
|
46 | * |
|
47 | * @param $database |
|
48 | * |
|
49 | * @return $this |
|
50 | */ |
|
51 | public function setDatabase($database) |
|
52 | { |
|
53 | if (is_string($database) && $database) { |
|
54 | $this->database = $database; |
|
55 | } |
|
56 | ||
57 | return $this; |
|
58 | } |
|
59 | ||
60 | /** |
|
61 | * @return Module |
|
62 | */ |
|
63 | public function getModule() |
|
64 | { |
|
65 | return $this->module; |
|
66 | } |
|
67 | ||
68 | /** |
|
69 | * Get migration path. |
|
70 | * |
|
71 | * @return string |
|
72 | */ |
|
73 | public function getPath() |
|
74 | { |
|
75 | $config = $this->module->get('migration'); |
|
76 | ||
77 | $migrationPath = GenerateConfigReader::read('migration'); |
|
78 | $path = (is_array($config) && array_key_exists('path', $config)) ? $config['path'] : $migrationPath->getPath(); |
|
79 | ||
80 | return $this->module->getExtraPath($path); |
|
81 | } |
|
82 | ||
83 | /** |
|
84 | * Get migration files. |
|
85 | * |
|
86 | * @param boolean $reverse |
|
87 | * @return array |
|
88 | */ |
|
89 | public function getMigrations($reverse = false) |
|
90 | { |
|
91 | $files = $this->laravel['files']->glob($this->getPath() . '/*_*.php'); |
|
92 | ||
93 | // Once we have the array of files in the directory we will just remove the |
|
94 | // extension and take the basename of the file which is all we need when |
|
95 | // finding the migrations that haven't been run against the databases. |
|
96 | if ($files === false) { |
|
97 | return []; |
|
98 | } |
|
99 | ||
100 | $files = array_map(function ($file) { |
|
101 | return str_replace('.php', '', basename($file)); |
|
102 | }, $files); |
|
103 | ||
104 | // Once we have all of the formatted file names we will sort them and since |
|
105 | // they all start with a timestamp this should give us the migrations in |
|
106 | // the order they were actually created by the application developers. |
|
107 | sort($files); |
|
108 | ||
109 | if ($reverse) { |
|
110 | return array_reverse($files); |
|
111 | } |
|
112 | ||
113 | return $files; |
|
114 | } |
|
115 | ||
116 | /** |
|
117 | * Rollback migration. |
|
118 | * |
|
119 | * @return array |
|
120 | */ |
|
121 | public function rollback() |
|
122 | { |
|
123 | $migrations = $this->getLast($this->getMigrations(true)); |
|
124 | ||
125 | $this->requireFiles($migrations->toArray()); |
|
126 | ||
127 | $migrated = []; |
|
128 | ||
129 | foreach ($migrations as $migration) { |
|
130 | $data = $this->find($migration); |
|
131 | ||
132 | if ($data->count()) { |
|
133 | $migrated[] = $migration; |
|
134 | ||
135 | $this->down($migration); |
|
136 | ||
137 | $data->delete(); |
|
138 | } |
|
139 | } |
|
140 | ||
141 | return $migrated; |
|
142 | } |
|
143 | ||
144 | /** |
|
145 | * Reset migration. |
|
146 | * |
|
147 | * @return array |
|
148 | */ |
|
149 | public function reset() |
|
150 | { |
|
151 | $migrations = $this->getMigrations(true); |
|
152 | ||
153 | $this->requireFiles($migrations); |
|
154 | ||
155 | $migrated = []; |
|
156 | ||
157 | foreach ($migrations as $migration) { |
|
158 | $data = $this->find($migration); |
|
159 | ||
160 | if ($data->count()) { |
|
161 | $migrated[] = $migration; |
|
162 | ||
163 | $this->down($migration); |
|
164 | ||
165 | $data->delete(); |
|
166 | } |
|
167 | } |
|
168 | ||
169 | return $migrated; |
|
170 | } |
|
171 | ||
172 | /** |
|
173 | * Run down schema from the given migration name. |
|
174 | * |
|
175 | * @param string $migration |
|
176 | */ |
|
177 | public function down($migration) |
|
178 | { |
|
179 | $this->resolve($migration)->down(); |
|
180 | } |
|
181 | ||
182 | /** |
|
183 | * Run up schema from the given migration name. |
|
184 | * |
|
185 | * @param string $migration |
|
186 | */ |
|
187 | public function up($migration) |
|
188 | { |
|
189 | $this->resolve($migration)->up(); |
|
190 | } |
|
191 | ||
192 | /** |
|
193 | * Resolve a migration instance from a file. |
|
194 | * |
|
195 | * @param string $file |
|
196 | * |
|
197 | * @return object |
|
198 | */ |
|
199 | public function resolve($file) |
|
200 | { |
|
201 | $file = implode('_', array_slice(explode('_', $file), 4)); |
|
202 | ||
203 | $class = Str::studly($file); |
|
204 | ||
205 | return new $class(); |
|
206 | } |
|
207 | ||
208 | /** |
|
209 | * Require in all the migration files in a given path. |
|
210 | * |
|
211 | * @param array $files |
|
212 | */ |
|
213 | public function requireFiles(array $files) |
|
214 | { |
|
215 | $path = $this->getPath(); |
|
216 | foreach ($files as $file) { |
|
217 | $this->laravel['files']->requireOnce($path . '/' . $file . '.php'); |
|
218 | } |
|
219 | } |
|
220 | ||
221 | /** |
|
222 | * Get table instance. |
|
223 | * |
|
224 | * @return \Illuminate\Database\Query\Builder |
|
225 | */ |
|
226 | public function table() |
|
227 | { |
|
228 | return $this->laravel['db']->connection($this->database ?: null)->table(config('database.migrations')); |
|
229 | } |
|
230 | ||
231 | /** |
|
232 | * Find migration data from database by given migration name. |
|
233 | * |
|
234 | * @param string $migration |
|
235 | * |
|
236 | * @return object |
|
237 | */ |
|
238 | public function find($migration) |
|
239 | { |
|
240 | return $this->table()->whereMigration($migration); |
|
241 | } |
|
242 | ||
243 | /** |
|
244 | * Save new migration to database. |
|
245 | * |
|
246 | * @param string $migration |
|
247 | * |
|
248 | * @return mixed |
|
249 | */ |
|
250 | public function log($migration) |
|
251 | { |
|
252 | return $this->table()->insert([ |
|
253 | 'migration' => $migration, |
|
254 | 'batch' => $this->getNextBatchNumber(), |
|
255 | ]); |
|
256 | } |
|
257 | ||
258 | /** |
|
259 | * Get the next migration batch number. |
|
260 | * |
|
261 | * @return int |
|
262 | */ |
|
263 | public function getNextBatchNumber() |
|
264 | { |
|
265 | return $this->getLastBatchNumber() + 1; |
|
266 | } |
|
267 | ||
268 | /** |
|
269 | * Get the last migration batch number. |
|
270 | * |
|
271 | * @param array|null $migrations |
|
272 | * @return int |
|
273 | */ |
|
274 | public function getLastBatchNumber($migrations = null) |
|
275 | { |
|
276 | $table = $this->table(); |
|
277 | ||
278 | if (is_array($migrations)) { |
|
279 | $table = $table->whereIn('migration', $migrations); |
|
280 | } |
|
281 | ||
282 | return $table->max('batch'); |
|
283 | } |
|
284 | ||
285 | /** |
|
286 | * Get the last migration batch. |
|
287 | * |
|
288 | * @param array $migrations |
|
289 | * |
|
290 | * @return Collection |
|
291 | */ |
|
292 | public function getLast($migrations) |
|
293 | { |
|
294 | $query = $this->table() |
|
295 | ->where('batch', $this->getLastBatchNumber($migrations)) |
|
296 | ->whereIn('migration', $migrations); |
|
297 | ||
298 | $result = $query->orderBy('migration', 'desc')->get(); |
|
299 | ||
300 | return collect($result)->map(function ($item) { |
|
301 | return (array) $item; |
|
302 | })->pluck('migration'); |
|
303 | } |
|
304 | ||
305 | /** |
|
306 | * Get the ran migrations. |
|
307 | * |
|
308 | * @return Collection |
|
309 | */ |
|
310 | public function getRan() |
|
311 | { |
|
312 | return $this->table()->pluck('migration'); |
|
313 | } |
|
314 | } |
|
315 |