Skip to content

Commit

Permalink
Merge pull request #3 from envor/main
Browse files Browse the repository at this point in the history
refactor to invokable classes
  • Loading branch information
inmanturbo authored Feb 4, 2024
2 parents 011c16d + 2780f5b commit bf95146
Show file tree
Hide file tree
Showing 15 changed files with 526 additions and 251 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Schema::connection('mariadb')->trashDatabase('schema_demo');
The `emptyTrash()` method will erase all `trashed` databases from disk which are reachable from the current connection:

> [!TIP]
> To only permanently erase databases trahed later than a given age and keep those which are newer,
> To only permanently erase databases trashed later than a given age and keep those which are newer,
> you may pass the maximum age in days for the databases you want to keep.
```php
Expand All @@ -144,7 +144,7 @@ Schema::connection('mysql')->emptyTrash();

> [!IMPORTANT]
> Tests use [spatie/docker](https://github.com/spatie/docker) for testing against various database servers.
> Docker is required for running tests!
> Docker is required for running tests locally!
```bash
composer test
Expand Down
80 changes: 20 additions & 60 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,96 +1,56 @@
parameters:
ignoreErrors:
-
message: "#^Call to method createDatabase\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 2
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Call to method createDatabaseIfNotExists\\(\\) on an unknown class Illuminate\\\\Database\\\\SQLiteBuilder\\.$#"
message: "#^Call to an undefined method Illuminate\\\\Database\\\\Schema\\\\MySqlBuilder\\:\\:mysqlDatabaseExists\\(\\)\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Call to method dropDatabaseIfExists\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 3
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlCreateDatabaseIfNotExists.php

-
message: "#^Call to method getConnection\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 3
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Call to method getTableListing\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Call to method mysqlDatabaseExists\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 2
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Call to method setConnection\\(\\) on an unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Instanceof between \\$this\\(Envor\\\\SchemaMacros\\\\SchemaMacrosServiceProvider\\) and Illuminate\\\\Database\\\\Schema\\\\MySqlBuilder will always evaluate to false\\.$#"
count: 4
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Instanceof between \\$this\\(Envor\\\\SchemaMacros\\\\SchemaMacrosServiceProvider\\) and Illuminate\\\\Database\\\\Schema\\\\SQLiteBuilder will always evaluate to false\\.$#"
count: 3
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlDatabaseExists.php

-
message: "#^PHPDoc tag @var for variable \\$this contains unknown class Illuminate\\\\Database\\\\MySqlBuilder\\.$#"
count: 4
path: src/SchemaMacrosServiceProvider.php

-
message: "#^PHPDoc tag @var for variable \\$this contains unknown class Illuminate\\\\Database\\\\SQLiteBuilder\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlDatabaseExists.php

-
message: "#^Parameter \\#1 \\$format of method Carbon\\\\Carbon\\:\\:format\\(\\) expects string, mixed given\\.$#"
message: "#^Cannot cast mixed to string\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlEmptyTrash.php

-
message: "#^Parameter \\#1 \\$format of static method Carbon\\\\Carbon\\:\\:createFromFormat\\(\\) expects string, mixed given\\.$#"
message: "#^Call to an undefined method Illuminate\\\\Database\\\\Schema\\\\MySqlBuilder\\:\\:mysqlDatabaseExists\\(\\)\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlTrashDatabase.php

-
message: "#^Parameter \\#1 \\$object of function get_object_vars expects object, mixed given\\.$#"
message: "#^Parameter \\#1 \\.\\.\\.\\$arrays of function array_merge expects array, mixed given\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/MySql/MySqlTrashDatabase.php

-
message: "#^Parameter \\#1 \\.\\.\\.\\$arrays of function array_merge expects array, mixed given\\.$#"
message: "#^Negated boolean expression is always true\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/SQLite/SQLiteCreateDatabaseIfNotExists.php

-
message: "#^Parameter \\#2 \\$string of function explode expects string, mixed given\\.$#"
message: "#^Unreachable statement \\- code above always terminates\\.$#"
count: 1
path: src/SchemaMacrosServiceProvider.php
path: src/SQLite/SQLiteCreateDatabaseIfNotExists.php

-
message: "#^Unable to resolve the template type TKey in call to function collect$#"
count: 1
message: "#^Instanceof between \\$this\\(Envor\\\\SchemaMacros\\\\SchemaMacrosServiceProvider\\) and Illuminate\\\\Database\\\\Schema\\\\MySqlBuilder will always evaluate to false\\.$#"
count: 4
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Unable to resolve the template type TValue in call to function collect$#"
count: 1
message: "#^Instanceof between \\$this\\(Envor\\\\SchemaMacros\\\\SchemaMacrosServiceProvider\\) and Illuminate\\\\Database\\\\Schema\\\\SQLiteBuilder will always evaluate to false\\.$#"
count: 4
path: src/SchemaMacrosServiceProvider.php

-
message: "#^Unreachable statement \\- code above always terminates\\.$#"
count: 4
message: "#^Trying to invoke mixed but it's not a callable\\.$#"
count: 2
path: src/SchemaMacrosServiceProvider.php
31 changes: 31 additions & 0 deletions src/MySql/MySqlCreateDatabaseIfNotExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Envor\SchemaMacros\MySql;

use Stringable;

/**
* Create the database if it does not exist
*
* @param string|Stringable $database
*
* @mixin \Illuminate\Database\Schema\MySqlBuilder
*
* @return bool
*/
class MySqlCreateDatabaseIfNotExists
{
public function __invoke(): callable
{
return function (string|Stringable $database): bool {
$database = (string) $database;

/** @var \Illuminate\Database\Schema\MySqlBuilder $this */
if ($this->mysqlDatabaseExists($database)) {
return false;
}

return $this->createDatabase($database);
};
}
}
27 changes: 27 additions & 0 deletions src/MySql/MySqlDatabaseExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Envor\SchemaMacros\MySql;

use Stringable;

/**
* determine if the database exists
*
* @param string|Stringable $database
*
* @mixin \Illuminate\Database\Schema\MySqlBuilder
*
* @return bool
*/
class MySqlDatabaseExists
{
public function __invoke(): callable
{
return function (string|Stringable $database): bool {
$database = (string) $database;

/** @var \Illuminate\Database\MySqlBuilder $this */
return (bool) $this->getConnection()->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '{$database}'");
};
}
}
49 changes: 49 additions & 0 deletions src/MySql/MySqlEmptyTrash.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Envor\SchemaMacros\MySql;

use Envor\SchemaMacros\SchemaMacros;
use Illuminate\Support\Carbon;

/**
* Erase trashed databases
*
* @param int $daysOld
*
* @mixin \Illuminate\Database\Schema\MySqlBuilder
*
* @return int
*/
class MySqlEmptyTrash
{
public function __invoke(): callable
{
return function (int $daysOld = 0): int {
/** @var \Illuminate\Database\Schema\MySqlBuilder $this */
$trashDatabases = collect($this->getConnection()->select("SHOW DATABASES LIKE 'trashed_%'"))
->map(fn ($database) => array_values(get_object_vars($database))[0]);

$deleted = 0;

foreach ($trashDatabases as $trashDatabase) {
$trashDatabase = (string) $trashDatabase;

if ($daysOld > 0) {
$dateSlice = array_slice(explode('_', $trashDatabase), 1, 6);
$dateString = implode('_', $dateSlice);
$date = Carbon::createFromFormat(SchemaMacros::TRASH_DATE_FORMAT, $dateString)->getTimestamp();

if ($date > now()->subDays($daysOld)->getTimestamp()) {
continue;
}
}

if ($this->dropDatabaseIfExists($trashDatabase)) {
$deleted++;
}
}

return $deleted;
};
}
}
64 changes: 64 additions & 0 deletions src/MySql/MySqlTrashDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Envor\SchemaMacros\MySql;

use Envor\SchemaMacros\SchemaMacros;
use Illuminate\Support\Facades\DB;
use Stringable;

/**
* Move the database to the trash
*
* @param string|Stringable $database
*
* @mixin \Illuminate\Database\Schema\MySqlBuilder
*
* @return bool|string
*/
class MySqlTrashDatabase
{
public function __invoke(): callable
{
return function (string|Stringable $database) {
$database = (string) $database;

/** @var \Illuminate\Database\Schema\MySqlBuilder $this */
if (! $this->mysqlDatabaseExists($database)) {
return false;
}

try {

$trashedAt = now()->format(SchemaMacros::TRASH_DATE_FORMAT);
$trashedDatabase = "trashed_{$trashedAt}_{$database}";
$this->dropDatabaseIfExists($trashedDatabase);
$this->createDatabase($trashedDatabase);

$currentConnection = $this->getConnection();
$currentConnectionName = $currentConnection->getName();

config(['database.connections.new_connection_for_database' => array_merge(config("database.connections.{$currentConnectionName}"), [
'database' => $database,
])]);

$db = DB::connection('new_connection_for_database');

$db->statement("SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';");

$tables = $this->getTableListing();

foreach ($tables as $table) {
$db->statement("create table if not exists `{$trashedDatabase}`.`{$table}` like `{$database}`.`{$table}`;");
$db->statement("insert into `{$trashedDatabase}`.`{$table}` select * from `{$database}`.`{$table}`;");
}

$this->dropDatabaseIfExists($database);
$this->setConnection($currentConnection);

return $trashedDatabase;
} catch (\Exception $e) {
return false;
}
};
}
}
44 changes: 44 additions & 0 deletions src/SQLite/SQLiteCreateDatabaseIfNotExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Envor\SchemaMacros\SQLite;

use Illuminate\Support\Facades\File;
use Stringable;

/**
* Create the database if it does not exist
*
* @param string|Stringable $database
* @param bool $recursive = true
*
* @mixin \Illuminate\Database\Schema\SQLiteBuilder
*
* @return bool
*/
class SQLiteCreateDatabaseIfNotExists
{
public function __invoke(): callable
{
return function (string|Stringable $database, bool $recursive = true): bool {
$database = (string) $database;

if (File::exists($database)) {
return false;
}

$directory = dirname($database);

if (! File::isDirectory($directory) && $recursive) {
File::makeDirectory($directory, 0755, true);
}

if (! File::exists($database)) {

/** @var \Illuminate\Database\Schema\SQLiteBuilder $this */
return $this->createDatabase($database);
}

return false;
};
}
}
27 changes: 27 additions & 0 deletions src/SQLite/SQLiteDatabaseExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Envor\SchemaMacros\SQLite;

use Illuminate\Support\Facades\File;
use Stringable;

/**
* determine if the database exists
*
* @param string|Stringable $database
*
* @mixin \Illuminate\Database\Schema\SQLiteBuilder
*
* @return bool
*/
class SQLiteDatabaseExists
{
public function __invoke(): callable
{
return function (string|Stringable $database): bool {
$database = (string) $database;

return File::exists($database);
};
}
}
Loading

0 comments on commit bf95146

Please sign in to comment.