From d2c954e26f01ee89312a6a4bf2d952bb7bb5aaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 20 Sep 2024 02:39:01 +0200 Subject: [PATCH 1/4] PHPORM-243 Alias _id to id in Schema::getColumns --- src/Schema/Builder.php | 20 +++++++++++++++++--- tests/SchemaTest.php | 11 +++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Schema/Builder.php b/src/Schema/Builder.php index 630ff4c75..f28df6baf 100644 --- a/src/Schema/Builder.php +++ b/src/Schema/Builder.php @@ -9,11 +9,13 @@ use MongoDB\Model\IndexInfo; use function array_fill_keys; +use function array_filter; use function array_keys; 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; @@ -40,6 +42,13 @@ public function hasColumn($table, $column): bool */ public function hasColumns($table, array $columns): bool { + // The field "id" (alias of "_id") is required for all MongoDB documents + $columns = array_filter($columns, fn (string $column): bool => ! in_array($column, ['_id', 'id'], true)); + + if ($columns === []) { + return true; + } + $collection = $this->connection->table($table); return $collection @@ -187,16 +196,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, ]; } diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index 0f04ab6d4..0261110c5 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -374,6 +374,9 @@ public function testRenameColumn(): void public function testHasColumn(): void { + $this->assertTrue(Schema::hasColumn('newcollection', '_id')); + $this->assertTrue(Schema::hasColumn('newcollection', 'id')); + DB::connection()->table('newcollection')->insert(['column1' => 'value']); $this->assertTrue(Schema::hasColumn('newcollection', 'column1')); @@ -382,6 +385,9 @@ public function testHasColumn(): void 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'], @@ -451,8 +457,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']); From 85aa4deb079f29b1146b7e0a3092915c7a45a21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 20 Sep 2024 12:04:49 +0200 Subject: [PATCH 2/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0e383338..e9f973800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 From 91fad3fc35cec9665a5931f3d844be52d9b8300f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 20 Sep 2024 12:22:02 +0200 Subject: [PATCH 3/4] Support hasColumn for nested id --- src/Schema/Builder.php | 8 +++++++- tests/SchemaTest.php | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Schema/Builder.php b/src/Schema/Builder.php index f28df6baf..357f6ba22 100644 --- a/src/Schema/Builder.php +++ b/src/Schema/Builder.php @@ -11,6 +11,7 @@ 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; @@ -19,6 +20,8 @@ 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 @@ -42,9 +45,12 @@ public function hasColumn($table, $column): bool */ public function hasColumns($table, array $columns): bool { - // The field "id" (alias of "_id") is required for all MongoDB documents + // 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; } diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index 0261110c5..ff3dfe626 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -377,10 +377,12 @@ public function testHasColumn(): void $this->assertTrue(Schema::hasColumn('newcollection', '_id')); $this->assertTrue(Schema::hasColumn('newcollection', 'id')); - DB::connection()->table('newcollection')->insert(['column1' => 'value']); + 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 From 3618aef5b4a81d0467769fbd9432e39bb94d8071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 20 Sep 2024 13:53:06 +0200 Subject: [PATCH 4/4] Update src/Schema/Builder.php Co-authored-by: Andreas Braun --- src/Schema/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Schema/Builder.php b/src/Schema/Builder.php index 357f6ba22..ade4b0fb7 100644 --- a/src/Schema/Builder.php +++ b/src/Schema/Builder.php @@ -45,7 +45,7 @@ public function hasColumn($table, $column): bool */ public function hasColumns($table, array $columns): bool { - // The field "id" (alias of "_id") always exist on MongoDB collections + // The field "id" (alias of "_id") always exists in MongoDB documents $columns = array_filter($columns, fn (string $column): bool => ! in_array($column, ['_id', 'id'], true)); // Any subfield named "*.id" is an alias of "*._id"