Skip to content

Commit

Permalink
Fixing issue with Schema functions and writing tests
Browse files Browse the repository at this point in the history
Signed-off-by: Dusan Malusev <[email protected]>
  • Loading branch information
CodeLieutenant committed Apr 20, 2024
1 parent b38c0ec commit d57817e
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static function formatNameForDatabase(Grammar $grammar, string $name): st
$name = Str::snake($reflection->getShortName());
}

return $grammar->wrap($name);
return '\''.$name.'\'';
}

public static function extractNameAndValueFromEnum(PDO $pdo, string $name): array
Expand Down
23 changes: 5 additions & 18 deletions src/Mixins/SchemaExtensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function createEnum(): Closure
$value = match ($values === null) {
true => Helpers::extractNameAndValueFromEnum($conn->getPdo(), $name),
false => [
'name' => Helpers::formatNameForDatabase($conn->getSchemaGrammar(), $name),
'name' => $name,
'values' => Helpers::formatPgEnumValuesForDatabase($conn->getPdo(), $values),
],
};
Expand All @@ -38,7 +38,7 @@ public function createEnumIfNotExists(): Closure
$value = match ($values === null) {
true => Helpers::extractNameAndValueFromEnum($conn->getPdo(), $name),
false => [
'name' => Helpers::formatNameForDatabase($conn->getSchemaGrammar(), $name),
'name' => $name,
'values' => Helpers::formatPgEnumValuesForDatabase($conn->getPdo(), $values),
],
};
Expand All @@ -60,7 +60,6 @@ public function dropEnum(): Closure
return function (string $name): void {
/** @var $this Builder */
$conn = $this->getConnection();
$name = Helpers::formatNameForDatabase($conn->getSchemaGrammar(), $name);
$conn->statement("DROP TYPE $name;");
};
}
Expand All @@ -70,7 +69,6 @@ public function dropEnumIfExists(): Closure
return function (string $name): void {
/** @var $this Builder */
$conn = $this->getConnection();
$name = Helpers::formatNameForDatabase($conn->getSchemaGrammar(), $name);
$conn->statement(
<<<SQL
DO $$
Expand All @@ -84,18 +82,6 @@ public function dropEnumIfExists(): Closure
};
}

public function renameEnum(): Closure
{
return function (string $type, string $newName): void {
/** @var $this Builder */
$conn = $this->getConnection();
$grammar = $conn->getSchemaGrammar();
$type = Helpers::formatNameForDatabase($grammar, $type);
$newName = Helpers::formatNameForDatabase($grammar, $newName);
$conn->statement("ALTER TYPE $type RENAME TO $newName;");
};
}

public function renameEnumValue(): Closure
{
return function (string $type, string $oldName, string $newName): void {
Expand All @@ -105,6 +91,7 @@ public function renameEnumValue(): Closure
$oldName = Helpers::formatNameForDatabase($grammar, $oldName);
$newName = Helpers::formatNameForDatabase($grammar, $newName);
$conn->statement("ALTER TYPE $type RENAME VALUE $oldName TO $newName;");
$conn->statement('COMMIT');
};
}

Expand All @@ -119,7 +106,6 @@ public function addEnumValue(): Closure
) {
/** @var $this Builder */
$conn = $this->getConnection();
$type = Helpers::formatNameForDatabase($conn->getSchemaGrammar(), $type);
$stmt = "ALTER TYPE $type ADD VALUE";

if ($ifNotExists) {
Expand All @@ -129,10 +115,11 @@ public function addEnumValue(): Closure
$stmt .= ' '.Helpers::formatPgEnumValuesForDatabase($conn->getPdo(), [$value]);

if ($direction && $otherValue) {
$stmt .= " $direction->value $otherValue";
$stmt .= " $direction->value '$otherValue'";
}

$conn->statement($stmt);
$conn->statement('COMMIT');
};
}
}
15 changes: 0 additions & 15 deletions tests/Feature/MigrationsTest.php

This file was deleted.

60 changes: 60 additions & 0 deletions tests/Feature/SchemaTests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

use CodeLieutenant\LaravelPgEnum\Enums\Direction;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

afterEach(function () {
try {
DB::statement('DROP TYPE test_enum;');
} catch (Exception$e) {
}
});

test('create new enum with values', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
assertEnumExists('test_enum');
assertEnumHasValues('test_enum', ['one', 'two', 'three']);
Schema::dropEnum('test_enum');
assertEnumNotExists('test_enum');
});

test('create same enum twice', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
Schema::createEnum('test_enum', ['one', 'two', 'three']);
})->expectExceptionObject(new PDOException('SQLSTATE[42710]: Duplicate object: 7 ERROR: type "test_enum" already exists', 42710));

test('create same enum twice using createIfNotExists', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
Schema::createEnumIfNotExists('test_enum', ['one', 'two', 'three']);
})->throwsNoExceptions();

test('add new value to existing enum', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
assertEnumExists('test_enum');
assertEnumHasValues('test_enum', ['one', 'two', 'three']);
Schema::addEnumValue('test_enum', 'four');
assertEnumHasValues('test_enum', ['one', 'two', 'three', 'four']);
});

test('add new value to existing enum before', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
Schema::addEnumValue('test_enum', 'four', Direction::BEFORE, 'one');

assertEnumHasValues('test_enum', ['four', 'one', 'two', 'three']);
});

test('add new value to existing enum after', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
Schema::addEnumValue('test_enum', 'four', Direction::AFTER, 'one');

assertEnumHasValues('test_enum', ['one', 'four', 'two', 'three']);
});

test('rename enum value', function () {
Schema::createEnum('test_enum', ['one', 'two', 'three']);
Schema::renameEnumValue('test_enum', 'one', 'newName');
assertEnumHasValues('test_enum', ['newName', 'two', 'three']);
});
30 changes: 30 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
<?php

declare(strict_types=1);

use CodeLieutenant\LaravelPgEnum\Tests\TestCase;
use Illuminate\Support\Facades\DB;

use function PHPUnit\Framework\assertEmpty;
use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertNotEmpty;

uses(TestCase::class)->in(__DIR__);

function assertEnumExists(string $name)
{
$values = DB::select('SELECT * FROM pg_type where typname = ?', [$name]);
assertNotEmpty($values);
}

function assertEnumNotExists(string $name)
{
$values = DB::select('SELECT * FROM pg_type where typname = ?', [$name]);
assertEmpty($values);
}

function assertEnumHasValues(string $name, array $values)
{
$vals = Str::of(DB::select("SELECT enum_range(null::$name)")[0]->enum_range)
->ltrim('{')
->rtrim('}')
->explode(',')
->toArray();

assertEquals($values, $vals);
}
2 changes: 1 addition & 1 deletion tests/Unit/HelpersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ enum NonBackedEnum

it('formats name for database usage', function () {
$name = Helpers::formatNameForDatabase(new PostgresGrammar(), 'name');
expect($name)->toBe('"name"');
expect($name)->toBe('\'name\'');
});

it('formats enum values', function (array $cases, string $expected) {
Expand Down

0 comments on commit d57817e

Please sign in to comment.