Skip to content

Commit 6733e4b

Browse files
committed
Add collation to getCollections and getViews
Although it's not displayed anywhere other than `db:table` for now, the `collation` column is present in some of laravel's artisan dabase commands.
1 parent 48c9739 commit 6733e4b

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/Schema/Builder.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use function array_column;
1616
use function array_fill_keys;
1717
use function array_filter;
18+
use function array_key_exists;
1819
use function array_keys;
1920
use function array_map;
2021
use function array_merge;
@@ -26,6 +27,7 @@
2627
use function implode;
2728
use function in_array;
2829
use function is_array;
30+
use function is_bool;
2931
use function is_string;
3032
use function iterator_to_array;
3133
use function sort;
@@ -380,6 +382,9 @@ private function getCollectionRows(string $collectionType, $schema = null)
380382
continue;
381383
}
382384

385+
$options = $collectionInfo->getOptions();
386+
$collation = $options['collation'] ?? [];
387+
383388
// Aggregation is not supported on views
384389
$stats = $collectionType !== 'view' ? $db->selectCollection($collectionName)->aggregate([
385390
['$collStats' => ['storageStats' => ['scale' => 1]]],
@@ -392,7 +397,7 @@ private function getCollectionRows(string $collectionType, $schema = null)
392397
'schema_qualified_name' => $db->getDatabaseName() . '.' . $collectionName,
393398
'size' => $stats[0]?->storageStats?->totalSize ?? null,
394399
'comment' => null,
395-
'collation' => null,
400+
'collation' => $this->collationToString($collation),
396401
'engine' => null,
397402
];
398403
}
@@ -401,4 +406,30 @@ private function getCollectionRows(string $collectionType, $schema = null)
401406

402407
return $collections;
403408
}
409+
410+
private function collationToString(array $collation): string
411+
{
412+
$map = [
413+
'locale' => 'l',
414+
'strength' => 's',
415+
'caseLevel' => 'cl',
416+
'caseFirst' => 'cf',
417+
'numericOrdering' => 'no',
418+
'alternate' => 'a',
419+
'maxVariable' => 'mv',
420+
'normalization' => 'n',
421+
'backwards' => 'b',
422+
];
423+
424+
$parts = [];
425+
foreach ($collation as $key => $value) {
426+
if (array_key_exists($key, $map)) {
427+
$shortKey = $map[$key];
428+
$shortValue = is_bool($value) ? ($value ? '1' : '0') : $value;
429+
$parts[] = $shortKey . '=' . $shortValue;
430+
}
431+
}
432+
433+
return implode(';', $parts);
434+
}
404435
}

tests/SchemaTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@
2020

2121
class SchemaTest extends TestCase
2222
{
23+
private const COLL_WITH_COLLATION = 'collection_with_collation';
24+
2325
public function tearDown(): void
2426
{
2527
$database = $this->getConnection('mongodb')->getDatabase();
2628
assert($database instanceof Database);
2729
$database->dropCollection('newcollection');
2830
$database->dropCollection('newcollection_two');
31+
$database->dropCollection(self::COLL_WITH_COLLATION);
2932
$database->dropCollection('test_view');
3033

3134
parent::tearDown();
@@ -394,9 +397,17 @@ public function testHasColumns(): void
394397

395398
public function testGetTables()
396399
{
400+
$db = DB::connection('mongodb')->getDatabase();
401+
$db->createCollection(self::COLL_WITH_COLLATION, [
402+
'collation' => [
403+
'locale' => 'fr',
404+
'strength' => 2,
405+
],
406+
]);
407+
397408
DB::connection('mongodb')->table('newcollection')->insert(['test' => 'value']);
398409
DB::connection('mongodb')->table('newcollection_two')->insert(['test' => 'value']);
399-
DB::connection('mongodb')->getDatabase()->createCollection('test_view', ['viewOn' => 'newcollection']);
410+
$db->createCollection('test_view', ['viewOn' => 'newcollection']);
400411
$dbName = DB::connection('mongodb')->getDatabaseName();
401412

402413
$tables = Schema::getTables();
@@ -407,6 +418,7 @@ public function testGetTables()
407418
$this->assertArrayHasKey('name', $table);
408419
$this->assertArrayHasKey('size', $table);
409420
$this->assertArrayHasKey('schema', $table);
421+
$this->assertArrayHasKey('collation', $table);
410422
$this->assertArrayHasKey('schema_qualified_name', $table);
411423
$this->assertNotEquals('test_view', $table['name'], 'Standard views should not be included in the result of getTables.');
412424

@@ -416,6 +428,10 @@ public function testGetTables()
416428
$this->assertEquals($dbName . '.newcollection', $table['schema_qualified_name']);
417429
$found = true;
418430
}
431+
432+
if ($table['name'] === self::COLL_WITH_COLLATION) {
433+
$this->assertEquals('l=fr;cl=0;cf=off;s=2;no=0;a=non-ignorable;mv=punct;n=0;b=0', $table['collation']);
434+
}
419435
}
420436

421437
if (! $found) {

0 commit comments

Comments
 (0)