Skip to content

Commit

Permalink
feat: add support for model parameter instead of table name
Browse files Browse the repository at this point in the history
  • Loading branch information
WatheqAlshowaiter committed Aug 22, 2024
1 parent 35a51b0 commit e53ea32
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 4 deletions.
30 changes: 30 additions & 0 deletions src/BackupTablesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace WatheqAlshowaiter\BackupTables;

use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
Expand Down Expand Up @@ -53,11 +54,19 @@ public function generateBackup($tablesToBackup)
protected function processBackup(array $tablesToBackup = [])
{
$currentDateTime = now()->format('Y_m_d_H_i_s');
$modelParent = "Illuminate\Database\Eloquent\Model";

foreach ($tablesToBackup as $table) {

//if ($table instanceof \Illuminate\Database\Eloquent\Model) {
// $table = $table->getTable();
//}
$table = $this->convertModelToTableName($table, $modelParent);

$newTableName = $table . '_backup_' . $currentDateTime;
$newTableName = str_replace(['-', ':'], '_', $newTableName);


if (Schema::hasTable($newTableName)) {
$this->response[] = "Table '$newTableName' already exists. Skipping cloning for '$table'.";

Expand Down Expand Up @@ -104,6 +113,7 @@ protected function processBackup(array $tablesToBackup = [])

protected function backupTablesForSqlite($newTableName, $table)
{

// Step 1: Create the new table structure, excluding generated columns
DB::statement(/**@lang SQLite */ "CREATE TABLE $newTableName AS SELECT * FROM $table WHERE 1=0;");

Expand All @@ -114,6 +124,7 @@ protected function backupTablesForSqlite($newTableName, $table)
$newCreatedTables[] = $newTableName;
$response[] = " Table '$table' cloned successfully.";


return [
'response' => $response,
'newCreatedTables' => $newCreatedTables,
Expand Down Expand Up @@ -173,8 +184,27 @@ protected function backupTablesForForSqlServer($newTableName, $table)
];
}

/**
* @param $table
* @param string $modelParent
* @return mixed|string
*/
public function convertModelToTableName($table, string $modelParent)
{
if (class_exists($table)) {
if (is_subclass_of($table, $modelParent)) {
$table = (new $table)->getTable();
}
}
return $table;
}

private function getMysqlVersion()
{
return (float) DB::select('select version()')[0]->{'version()'};
}
function hasParents($object) {
return (bool)class_parents($object);
}

}
58 changes: 54 additions & 4 deletions tests/BackupTablesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,58 @@ public function test_generate_multiple_table_backup()
$this->assertEquals(DB::table($tableName2)->value('father_id'), DB::table($newTableName2)->value('father_id')); // foreign key
}

//public function test_generate_multiple_models_backup()
//{
// $this->markTestSkipped();
//}
public function test_generate_multiple_models_backup()
{
Carbon::setTestNow();
$tableName = Father::class;
$tableName2 = Son::class;

Father::create([
'id' => 1,
'first_name' => 'Ahmed',
'last_name' => 'Saleh',
'email' => '[email protected]',
]);

Son::create([
'father_id' => Father::value('id')
]);

BackupTables::generateBackup([$tableName, $tableName2]);

$modelParent = "Illuminate\Database\Eloquent\Model";

$tableName = $this->convertModelToTableName($tableName, $modelParent);
$tableName2 = $this->convertModelToTableName($tableName2, $modelParent);

$newTableName = $tableName.'_backup_'.now()->format('Y_m_d_H_i_s');
$newTableName2 = $tableName2.'_backup_'.now()->format('Y_m_d_H_i_s');

$this->assertTrue(Schema::hasTable($newTableName));
$this->assertTrue(Schema::hasTable($newTableName2));

if (DB::getDriverName() == 'mysql') { // todo debugging
dump(Father::first()->first_name);
}

$this->assertEquals(DB::table($tableName)->value('first_name'), DB::table($newTableName)->value('first_name'));
$this->assertEquals(DB::table($tableName)->value('email'), DB::table($newTableName)->value('email'));

if (DB::getDriverName() == 'mysql' || DB::getDriverName() == 'mariadb' || (float) App::version() >= Constants::VERSION_AFTER_STORED_AS_VIRTUAL_AS_SUPPORT) {
$this->assertEquals(DB::table($tableName)->value('full_name'), DB::table($newTableName)->value('full_name')); // StoredAs tables
//$this->assertEquals(DB::table($tableName)->value('status'), DB::table($newTableName)->value('status')); // todo remove if not needed
}

$this->assertEquals(DB::table($tableName2)->value('father_id'), DB::table($newTableName2)->value('father_id')); // foreign key
}

public function convertModelToTableName($table, string $modelParent)
{
if (class_exists($table)) {
if (is_subclass_of($table, $modelParent)) {
$table = (new $table)->getTable();
}
}
return $table;
}
}

0 comments on commit e53ea32

Please sign in to comment.