Skip to content

Commit 9933694

Browse files
committed
Add flowforgePositionColumn macro to Blueprint for database-specific collations
1 parent bc0bf4e commit 9933694

File tree

3 files changed

+91
-20
lines changed

3 files changed

+91
-20
lines changed

README.md

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,7 @@ php artisan make:migration add_position_to_tasks_table
3636
```php
3737
// migration
3838
Schema::table('tasks', function (Blueprint $table) {
39-
// Database-specific collations for binary sorting
40-
$driver = DB::connection()->getDriverName();
41-
$positionColumn = $table->string('position')->nullable();
42-
43-
match ($driver) {
44-
'pgsql' => $positionColumn->collation('C'),
45-
'mysql' => $positionColumn->collation('utf8mb4_bin'),
46-
default => null,
47-
};
39+
$table->flowforgePositionColumn('position'); // Handles database-specific collations automatically
4840
});
4941
```
5042

@@ -342,19 +334,12 @@ Schema::create('tasks', function (Blueprint $table) {
342334
$table->id();
343335
$table->string('title'); // Card title
344336
$table->string('status'); // Column identifier
345-
346-
// Position column with database-specific collations for binary sorting
347-
$driver = DB::connection()->getDriverName();
348-
$positionColumn = $table->string('position')->nullable();
349-
350-
match ($driver) {
351-
'pgsql' => $positionColumn->collation('C'), // PostgreSQL binary
352-
'mysql' => $positionColumn->collation('utf8mb4_bin'), // MySQL binary
353-
default => null,
354-
};
355-
337+
$table->flowforgePositionColumn(); // Drag-and-drop ordering (handles DB-specific collations)
356338
$table->timestamps();
357339
});
340+
341+
// Custom column name
342+
$table->flowforgePositionColumn('sort_order'); // Creates 'sort_order' column instead
358343
```
359344

360345
### Factory Integration

src/FlowforgeServiceProvider.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
use Filament\Support\Assets\Asset;
77
use Filament\Support\Facades\FilamentAsset;
88
use Filament\Support\Facades\FilamentIcon;
9+
use Illuminate\Database\Schema\Blueprint;
910
use Illuminate\Support\Facades\Blade;
11+
use Illuminate\Support\Facades\DB;
1012
use Relaticle\Flowforge\Commands\MakeKanbanBoardCommand;
1113
use Spatie\LaravelPackageTools\Commands\InstallCommand;
1214
use Spatie\LaravelPackageTools\Package;
@@ -70,6 +72,9 @@ public function packageBooted(): void
7072

7173
// Register Blade Components
7274
$this->registerBladeComponents();
75+
76+
// Register Blueprint Macros
77+
$this->registerBlueprintMacros();
7378
}
7479

7580
/**
@@ -139,4 +144,21 @@ protected function getScriptData(): array
139144
],
140145
];
141146
}
147+
148+
/**
149+
* Register Blueprint macros for Flowforge.
150+
*/
151+
private function registerBlueprintMacros(): void
152+
{
153+
Blueprint::macro('flowforgePositionColumn', function (string $name = 'position') {
154+
$driver = DB::connection()->getDriverName();
155+
$column = $this->string($name)->nullable();
156+
157+
return match ($driver) {
158+
'pgsql' => $column->collation('C'),
159+
'mysql' => $column->collation('utf8mb4_bin'),
160+
default => $column,
161+
};
162+
});
163+
}
142164
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
use Illuminate\Database\Schema\Blueprint;
4+
use Illuminate\Database\Schema\ColumnDefinition;
5+
use Illuminate\Support\Facades\DB;
6+
7+
test('flowforgePositionColumn macro creates position column with correct collation for MySQL', function () {
8+
// Mock MySQL connection
9+
DB::shouldReceive('connection->getDriverName')
10+
->once()
11+
->andReturn('mysql');
12+
13+
$blueprint = new Blueprint('test_table');
14+
$column = $blueprint->flowforgePositionColumn();
15+
16+
expect($column)->toBeInstanceOf(ColumnDefinition::class)
17+
->and($column->get('type'))->toBe('string')
18+
->and($column->get('nullable'))->toBeTrue()
19+
->and($column->get('collation'))->toBe('utf8mb4_bin');
20+
});
21+
22+
test('flowforgePositionColumn macro creates position column with correct collation for PostgreSQL', function () {
23+
// Mock PostgreSQL connection
24+
DB::shouldReceive('connection->getDriverName')
25+
->once()
26+
->andReturn('pgsql');
27+
28+
$blueprint = new Blueprint('test_table');
29+
$column = $blueprint->flowforgePositionColumn();
30+
31+
expect($column)->toBeInstanceOf(ColumnDefinition::class)
32+
->and($column->get('type'))->toBe('string')
33+
->and($column->get('nullable'))->toBeTrue()
34+
->and($column->get('collation'))->toBe('C');
35+
});
36+
37+
test('flowforgePositionColumn macro accepts custom column name', function () {
38+
// Mock MySQL connection
39+
DB::shouldReceive('connection->getDriverName')
40+
->once()
41+
->andReturn('mysql');
42+
43+
$blueprint = new Blueprint('test_table');
44+
$column = $blueprint->flowforgePositionColumn('sort_order');
45+
46+
expect($column)->toBeInstanceOf(ColumnDefinition::class)
47+
->and($column->get('name'))->toBe('sort_order')
48+
->and($column->get('collation'))->toBe('utf8mb4_bin');
49+
});
50+
51+
test('flowforgePositionColumn macro works with unsupported database driver', function () {
52+
// Mock unsupported driver
53+
DB::shouldReceive('connection->getDriverName')
54+
->once()
55+
->andReturn('sqlite');
56+
57+
$blueprint = new Blueprint('test_table');
58+
$column = $blueprint->flowforgePositionColumn();
59+
60+
expect($column)->toBeInstanceOf(ColumnDefinition::class)
61+
->and($column->get('type'))->toBe('string')
62+
->and($column->get('nullable'))->toBeTrue()
63+
->and($column->get('collation'))->toBeNull();
64+
});

0 commit comments

Comments
 (0)