-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
30974af
commit 1b5b638
Showing
9 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "adrienpoupa/migrate-routines", | ||
"description": "Generate Laravel Migrations from existing MySQL routines: views, procedures, functions and triggers.", | ||
"keywords": ["laravel", "migration", "generator", "migrations", "artisan", "procedure"], | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Adrien Poupa", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"require": { | ||
"php": ">=7.0", | ||
"illuminate/support": "^5.5|^6" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"AdrienPoupa\\MigrateRoutines\\": "src/" | ||
} | ||
}, | ||
"minimum-stability": "dev", | ||
"prefer-stable": true, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"AdrienPoupa\\MigrateRoutines\\MigrateRoutinesServiceProvider" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
## Migrate Routines for Laravel | ||
|
||
[![Latest Stable Version](https://poser.pugx.org/adrienpoupa/migrate-routines/version.png)](https://packagist.org/packages/adrienpoupa/migrate-routines) | ||
[![Total Downloads](https://poser.pugx.org/adrienpoupa/migrate-routines/d/total.png)](https://packagist.org/packages/adrienpoupa/migrate-routines) | ||
|
||
Generate Laravel Migrations from existing MySQL routines: views, procedures, functions and triggers | ||
|
||
### Installation | ||
|
||
|
||
Require this package with composer. It is recommended to only require the package for development. | ||
|
||
```shell | ||
composer require adrienpoupa/migrate-routines --dev | ||
``` | ||
|
||
### Usage | ||
|
||
Convert the existing views into migrations | ||
|
||
```shell | ||
php artisan migrate:views | ||
``` | ||
|
||
Convert the existing procedures into migrations | ||
|
||
```shell | ||
php artisan migrate:procedures | ||
``` | ||
|
||
Convert the existing functions into migrations | ||
|
||
```shell | ||
php artisan migrate:functions | ||
``` | ||
|
||
Convert the existing triggers into migrations | ||
|
||
```shell | ||
php artisan migrate:triggers | ||
``` | ||
|
||
For all the commands, is possible to specify the database from which to retrieve the routines with the `--database` option, like this: | ||
|
||
```shell | ||
php artisan migrate:views --database=database_name | ||
``` | ||
|
||
For this package to work, your database connection should be done with a user privileged enough to run elevated queries | ||
from the information_schema and the mysql.proc tables. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace AdrienPoupa\MigrateRoutines\Console; | ||
|
||
use Illuminate\Support\Facades\DB; | ||
use stdClass; | ||
|
||
/** | ||
* Class MigrateFunctionsCommand | ||
* @package AdrienPoupa\MigrateRoutines\Console | ||
*/ | ||
class MigrateFunctionsCommand extends MigrateRoutines | ||
{ | ||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'migrate:functions {--database=default}'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Convert the existing functions into migrations'; | ||
|
||
/** | ||
* Create a new command instance. | ||
* | ||
* @return void | ||
*/ | ||
public function __construct() | ||
{ | ||
parent::__construct(); | ||
|
||
$this->migrationType = 'procedure'; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getData() | ||
{ | ||
return DB::select("SELECT name, param_list, body, returns FROM mysql.proc WHERE db='$this->database' and type='FUNCTION' "); | ||
} | ||
|
||
/** | ||
* Generate the up function | ||
* We use unprepared to avoid error 2014 | ||
* @param stdClass $function | ||
* @return string | ||
*/ | ||
public function up(stdClass $function) | ||
{ | ||
return 'DB::unprepared("CREATE FUNCTION `'.$function->name.'` (' . $function->param_list . ') | ||
RETURNS ' . $function->returns . ' | ||
'.$this->escape($function->body).'");'; | ||
} | ||
|
||
/** | ||
* Generate the down function | ||
* @param stdClass $function | ||
* @return string | ||
*/ | ||
public function down(stdClass $function) | ||
{ | ||
return 'DB::unprepared("DROP FUNCTION IF EXISTS `'.$function->name.'`");'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
namespace AdrienPoupa\MigrateRoutines\Console; | ||
|
||
use Illuminate\Support\Facades\DB; | ||
use stdClass; | ||
|
||
/** | ||
* Class MigrateProceduresCommand | ||
* @package AdrienPoupa\MigrateRoutines\Console | ||
*/ | ||
class MigrateProceduresCommand extends MigrateRoutines | ||
{ | ||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'migrate:procedures {--database=default}'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Convert the existing procedures into migrations'; | ||
|
||
/** | ||
* Create a new command instance. | ||
* | ||
* @return void | ||
*/ | ||
public function __construct() | ||
{ | ||
parent::__construct(); | ||
|
||
$this->migrationType = 'procedure'; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function getData() | ||
{ | ||
return DB::select("SELECT name, param_list, body FROM mysql.proc WHERE db='$this->database' and type='PROCEDURE' "); | ||
} | ||
|
||
/** | ||
* Generate the up function | ||
* We use unprepared to avoid error 2014 | ||
* @param stdClass $routine | ||
* @return string | ||
*/ | ||
public function up(stdClass $routine) | ||
{ | ||
return 'DB::unprepared("CREATE PROCEDURE `'.$routine->name.'` ( | ||
'.$this->escape($routine->param_list).' | ||
) | ||
'.$this->escape($routine->body).'");'; | ||
} | ||
|
||
/** | ||
* Generate the down function | ||
* @param stdClass $routine | ||
* @return string | ||
*/ | ||
public function down(stdClass $routine) | ||
{ | ||
return 'DB::unprepared("DROP PROCEDURE IF EXISTS `'.$this->escape($routine->name).'`");'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
<?php | ||
|
||
namespace AdrienPoupa\MigrateRoutines\Console; | ||
|
||
use Illuminate\Database\Console\Migrations\BaseCommand; | ||
use Illuminate\Filesystem\Filesystem; | ||
use Illuminate\Support\Str; | ||
use stdClass; | ||
|
||
/** | ||
* Class MigrateRoutines | ||
* @package AdrienPoupa\MigrateRoutines\Console | ||
*/ | ||
abstract class MigrateRoutines extends BaseCommand | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected $database; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $migrationType; | ||
|
||
/** | ||
* @var Filesystem | ||
*/ | ||
protected $filesystem; | ||
|
||
/** | ||
* @var Str | ||
*/ | ||
protected $str; | ||
|
||
/** | ||
* Create a new command instance. | ||
* | ||
*/ | ||
public function __construct() | ||
{ | ||
parent::__construct(); | ||
} | ||
|
||
/** | ||
* Execute the console command. | ||
* | ||
* @param Filesystem $filesystem | ||
* @param Str $str | ||
* @return void | ||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException | ||
*/ | ||
public function handle(Filesystem $filesystem, Str $str) | ||
{ | ||
$this->filesystem = $filesystem; | ||
$this->str = $str; | ||
|
||
$this->database = $this->option('database'); | ||
|
||
if ($this->database === 'default') { | ||
$this->database = config('database.connections.mysql.database'); | ||
} | ||
|
||
$this->convert(); | ||
} | ||
|
||
/** | ||
* Convert the existing routines | ||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException | ||
*/ | ||
private function convert() | ||
{ | ||
$routines = $this->getData(); | ||
|
||
if (!$routines) { | ||
$this->info('Nothing to migrate.'); | ||
return; | ||
} | ||
|
||
foreach ($routines as $routine) { | ||
$migrationName = $this->str->snake($routine->name); | ||
$up = $this->up($routine); | ||
$down = $this->down($routine); | ||
$this->write($migrationName, $up, $down); | ||
} | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
abstract public function getData(); | ||
|
||
/** | ||
* Generate the up function | ||
* We use unprepared to avoid error 2014 | ||
* @param stdClass $routine | ||
* @return string | ||
*/ | ||
abstract public function up(stdClass $routine); | ||
|
||
/** | ||
* Generate the down function | ||
* @param stdClass $routine | ||
* @return string | ||
*/ | ||
abstract public function down(stdClass $routine); | ||
|
||
/** | ||
* Write the migration | ||
* @param string $migrationName | ||
* @param string $up | ||
* @param string $down | ||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException | ||
*/ | ||
public function write(string $migrationName, string $up, string $down) | ||
{ | ||
$filename = date('Y_m_d_His') . '_create_' . $this->migrationType . '_' . $migrationName . '.php'; | ||
|
||
$path = $this->getMigrationPath() . '/' . $filename; | ||
|
||
$content = $this->generateMigrationContent($migrationName, $up, $down); | ||
|
||
$this->filesystem->put($path, $content); | ||
|
||
$this->line("<info>Created Migration:</info> {$filename}"); | ||
} | ||
|
||
/** | ||
* Insert the migration information into the stub | ||
* @param string $migrationName | ||
* @param string $up | ||
* @param string $down | ||
* @return string|string[] | ||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException | ||
*/ | ||
public function generateMigrationContent(string $migrationName, string $up, string $down) | ||
{ | ||
return str_replace( | ||
['DummyClass', 'schema_up', 'schema_down'], | ||
[$this->getClassName($migrationName), $this->indent($up), $this->indent($down)], | ||
$this->filesystem->get(__DIR__ . '/stubs/migration.stub') | ||
); | ||
} | ||
|
||
/** | ||
* Get the class name of the new migration file | ||
* @param string $migrationName | ||
* @return string | ||
*/ | ||
protected function getClassName(string $migrationName) | ||
{ | ||
return 'Create' . ucfirst($this->migrationType) . str_replace('_', '', $this->str->title($migrationName)); | ||
} | ||
|
||
/** | ||
* Indent the migration | ||
* @param string $text | ||
* @return mixed | ||
*/ | ||
protected function indent(string $text) | ||
{ | ||
return str_replace("\n", "\n ", $text); | ||
} | ||
|
||
/** | ||
* Escape the double quotes | ||
* @param string $text | ||
* @return mixed | ||
*/ | ||
protected function escape(string $text) | ||
{ | ||
return str_replace('"', '\"', $text); | ||
} | ||
} |
Oops, something went wrong.