Last active
October 4, 2019 14:19
-
-
Save mberizzo/013f49d89b96049c5e8c73284efdb071 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<?php | |
namespace Tests; | |
use Illuminate\Contracts\Console\Kernel; | |
/** | |
* Original source: https://gist.github.com/mberizzo/013f49d89b96049c5e8c73284efdb071 | |
* | |
*/ | |
trait DatabaseSetup | |
{ | |
protected static $migrated = false; | |
public function setupDatabase() | |
{ | |
if ($this->isInMemory()) { | |
$this->setupInMemoryDatabase(); | |
} else { | |
$this->setupTestDatabase(); | |
} | |
} | |
protected function isInMemory() | |
{ | |
return config('database.connections')[config('database.default')]['database'] == ':memory:'; | |
} | |
protected function setupInMemoryDatabase() | |
{ | |
$this->artisan('migrate'); | |
$this->app[Kernel::class]->setArtisan(null); | |
} | |
protected function setupTestDatabase() | |
{ | |
if (!static::$migrated) { | |
$this->whenMigrationsChange(function($command) { | |
$this->artisan($command); | |
$this->app[Kernel::class]->setArtisan(null); | |
}); | |
static::$migrated = true; | |
} | |
$this->beginDatabaseTransaction(); | |
} | |
public function beginDatabaseTransaction() | |
{ | |
$database = $this->app->make('db'); | |
foreach ($this->connectionsToTransact() as $name) { | |
$database->connection($name)->beginTransaction(); | |
} | |
$this->beforeApplicationDestroyed(function () use ($database) { | |
foreach ($this->connectionsToTransact() as $name) { | |
$database->connection($name)->rollBack(); | |
} | |
}); | |
} | |
protected function connectionsToTransact() | |
{ | |
return property_exists($this, 'connectionsToTransact') | |
? $this->connectionsToTransact : [null]; | |
} | |
protected function whenMigrationsChange($callback) | |
{ | |
$dbTracker = new DatabaseMigrationsTracker; | |
if ($dbTracker->dbNameOrMigrationsWereChanged()) { | |
$cmd = $dbTracker->getMigrationCommand(); | |
$callback($cmd); | |
$dbTracker->updateContentFiles(); | |
} | |
} | |
} | |
/** | |
* Track migrations and database name changes | |
* in 2 files stored in 'storage/app/*' | |
* | |
*/ | |
class DatabaseMigrationsTracker | |
{ | |
protected $storedMigration; | |
protected $currentMigration; | |
protected $storedDbName; | |
protected $currentDbName; | |
protected $migrationCommand = 'migrate'; | |
protected $filesPath = [ | |
'migrations' => 'app/testing_migrations.txt', | |
'db_name' => 'app/testing_database_name.txt', | |
]; | |
public function __construct() | |
{ | |
$this->readFilesContent(); | |
} | |
protected function readFilesContent() | |
{ | |
$this->storedMigration = $this->getStoredMigrationStr(); | |
$this->currentMigration = $this->getCurrentMigrationStr(); | |
$this->storedDbName = $this->getStoredDbName(); | |
$this->currentDbName = env('DB_DATABASE'); | |
} | |
protected function getStoredMigrationStr() | |
{ | |
$path = storage_path($this->filesPath['migrations']); | |
if (file_exists($path)) { | |
return file_get_contents($path); | |
} | |
return ''; | |
} | |
protected function getCurrentMigrationStr() | |
{ | |
return md5(collect(glob(base_path('database/migrations/*'))) | |
->map(function ($f) { | |
return file_get_contents($f); | |
})->implode('')); | |
} | |
protected function getStoredDbName() | |
{ | |
$path = storage_path($this->filesPath['db_name']); | |
if (file_exists($path)) { | |
return file_get_contents($path); | |
} | |
return ''; | |
} | |
public function migrationWasChanged() | |
{ | |
if ($this->storedMigration !== $this->currentMigration) { | |
return true; | |
} | |
return false; | |
} | |
public function dbNameWasChanged() | |
{ | |
if ($this->storedDbName !== $this->currentDbName) { | |
$this->migrationCommand = 'migrate:fresh'; | |
return true; | |
} | |
return false; | |
} | |
public function dbNameOrMigrationsWereChanged() | |
{ | |
if ($this->migrationWasChanged() || $this->dbNameWasChanged()) { | |
return true; | |
} | |
return false; | |
} | |
public function getMigrationCommand() | |
{ | |
return $this->migrationCommand; | |
} | |
public function updateContentFiles() | |
{ | |
file_put_contents( | |
storage_path($this->filesPath['migrations']), | |
$this->currentMigration | |
); | |
file_put_contents( | |
storage_path($this->filesPath['db_name']), | |
$this->currentDbName | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment