Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
## [5.1.0] - next

* Convert `_id` and `UTCDateTime` in results of `Model::raw()` before hydratation by @GromNaN in [#3152](https://github.com/mongodb/laravel-mongodb/pull/3152)
* Alias `_id` to `id` in `Schema::getColumns()` by @GromNaN in [#3160](https://github.com/mongodb/laravel-mongodb/pull/3160)

## [5.0.2] - 2024-09-17

Expand Down
26 changes: 23 additions & 3 deletions src/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@
use MongoDB\Model\IndexInfo;

use function array_fill_keys;
use function array_filter;
use function array_keys;
use function array_map;
use function assert;
use function count;
use function current;
use function implode;
use function in_array;
use function iterator_to_array;
use function sort;
use function sprintf;
use function str_ends_with;
use function substr;
use function usort;

class Builder extends \Illuminate\Database\Schema\Builder
Expand All @@ -40,6 +45,16 @@ public function hasColumn($table, $column): bool
*/
public function hasColumns($table, array $columns): bool
{
// The field "id" (alias of "_id") always exist on MongoDB collections
$columns = array_filter($columns, fn (string $column): bool => ! in_array($column, ['_id', 'id'], true));

// Any subfield named "*.id" is an alias of "*._id"
$columns = array_map(fn (string $column): string => str_ends_with($column, '.id') ? substr($column, 0, -3) . '._id' : $column, $columns);

if ($columns === []) {
return true;
}

$collection = $this->connection->table($table);

return $collection
Expand Down Expand Up @@ -187,16 +202,21 @@ public function getColumns($table)
foreach ($stats as $stat) {
sort($stat->types);
$type = implode(', ', $stat->types);
$name = $stat->_id;
if ($name === '_id') {
$name = 'id';
}

$columns[] = [
'name' => $stat->_id,
'name' => $name,
'type_name' => $type,
'type' => $type,
'collation' => null,
'nullable' => $stat->_id !== '_id',
'nullable' => $name !== 'id',
'default' => null,
'auto_increment' => false,
'comment' => sprintf('%d occurrences', $stat->total),
'generation' => $stat->_id === '_id' ? ['type' => 'objectId', 'expression' => null] : null,
'generation' => $name === 'id' ? ['type' => 'objectId', 'expression' => null] : null,
];
}

Expand Down
15 changes: 12 additions & 3 deletions tests/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -374,14 +374,22 @@ public function testRenameColumn(): void

public function testHasColumn(): void
{
DB::connection()->table('newcollection')->insert(['column1' => 'value']);
$this->assertTrue(Schema::hasColumn('newcollection', '_id'));
$this->assertTrue(Schema::hasColumn('newcollection', 'id'));

DB::connection()->table('newcollection')->insert(['column1' => 'value', 'embed' => ['_id' => 1]]);

$this->assertTrue(Schema::hasColumn('newcollection', 'column1'));
$this->assertFalse(Schema::hasColumn('newcollection', 'column2'));
$this->assertTrue(Schema::hasColumn('newcollection', 'embed._id'));
$this->assertTrue(Schema::hasColumn('newcollection', 'embed.id'));
}

public function testHasColumns(): void
{
$this->assertTrue(Schema::hasColumns('newcollection', ['_id']));
$this->assertTrue(Schema::hasColumns('newcollection', ['id']));

// Insert documents with both column1 and column2
DB::connection()->table('newcollection')->insert([
['column1' => 'value1', 'column2' => 'value2'],
Expand Down Expand Up @@ -451,8 +459,9 @@ public function testGetColumns()
$this->assertIsString($column['comment']);
});

$this->assertEquals('objectId', $columns->get('_id')['type']);
$this->assertEquals('objectId', $columns->get('_id')['generation']['type']);
$this->assertNull($columns->get('_id'), '_id is renamed to id');
$this->assertEquals('objectId', $columns->get('id')['type']);
$this->assertEquals('objectId', $columns->get('id')['generation']['type']);
$this->assertNull($columns->get('text')['generation']);
$this->assertEquals('string', $columns->get('text')['type']);
$this->assertEquals('date', $columns->get('date')['type']);
Expand Down
Loading