Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bcf97d2

Browse files
PHPORM-325 Add getViews and categorize table types (#3327)
1 parent c49a73f commit bcf97d2

File tree

2 files changed

+108
-11
lines changed

2 files changed

+108
-11
lines changed

‎src/Schema/Builder.php

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,22 @@
2121
use function assert;
2222
use function count;
2323
use function current;
24+
use function explode;
2425
use function implode;
2526
use function in_array;
2627
use function is_array;
2728
use function is_string;
2829
use function iterator_to_array;
2930
use function sort;
3031
use function sprintf;
32+
use function str_contains;
3133
use function str_ends_with;
3234
use function substr;
35+
use function trigger_error;
3336
use function usort;
3437

38+
use const E_USER_DEPRECATED;
39+
3540
/** @property Connection $connection */
3641
class Builder extends \Illuminate\Database\Schema\Builder
3742
{
@@ -47,7 +52,7 @@ public function hasColumn($table, $column): bool
4752
}
4853

4954
/**
50-
* Check if columns exists in the collection schema.
55+
* Check if columns exist in the collection schema.
5156
*
5257
* @param string $table
5358
* @param string[] $columns
@@ -134,12 +139,18 @@ public function drop($table)
134139
$blueprint->drop();
135140
}
136141

137-
/** @inheritdoc */
142+
/**
143+
* @inheritdoc
144+
*
145+
* Drops the entire database instead of deleting each collection individually.
146+
*
147+
* In MongoDB, dropping the whole database is much faster than dropping collections
148+
* one by one. The database will be automatically recreated when a new connection
149+
* writes to it.
150+
*/
138151
public function dropAllTables()
139152
{
140-
foreach ($this->getAllCollections() as $collection) {
141-
$this->drop($collection);
142-
}
153+
$this->connection->getDatabase()->drop();
143154
}
144155

145156
/** @param string|null $schema Database name */
@@ -148,7 +159,14 @@ public function getTables($schema = null)
148159
$db = $this->connection->getDatabase($schema);
149160
$collections = [];
150161

151-
foreach ($db->listCollectionNames() as $collectionName) {
162+
foreach ($db->listCollections() as $collectionInfo) {
163+
$collectionName = $collectionInfo->getName();
164+
165+
// Skip views, which don't support aggregate
166+
if ($collectionInfo->getType() === 'view') {
167+
continue;
168+
}
169+
152170
$stats = $db->selectCollection($collectionName)->aggregate([
153171
['$collStats' => ['storageStats' => ['scale' => 1]]],
154172
['$project' => ['storageStats.totalSize' => 1]],
@@ -165,9 +183,37 @@ public function getTables($schema = null)
165183
];
166184
}
167185

168-
usort($collections, function ($a, $b) {
169-
return $a['name'] <=> $b['name'];
170-
});
186+
usort($collections, fn ($a, $b) => $a['name'] <=> $b['name']);
187+
188+
return $collections;
189+
}
190+
191+
/** @param string|null $schema Database name */
192+
public function getViews($schema = null)
193+
{
194+
$db = $this->connection->getDatabase($schema);
195+
$collections = [];
196+
197+
foreach ($db->listCollections() as $collectionInfo) {
198+
$collectionName = $collectionInfo->getName();
199+
200+
// Skip normal type collection
201+
if ($collectionInfo->getType() !== 'view') {
202+
continue;
203+
}
204+
205+
$collections[] = [
206+
'name' => $collectionName,
207+
'schema' => $db->getDatabaseName(),
208+
'schema_qualified_name' => $db->getDatabaseName() . '.' . $collectionName,
209+
'size' => null,
210+
'comment' => null,
211+
'collation' => null,
212+
'engine' => null,
213+
];
214+
}
215+
216+
usort($collections, fn ($a, $b) => $a['name'] <=> $b['name']);
171217

172218
return $collections;
173219
}
@@ -203,7 +249,12 @@ public function getTableListing($schema = null, $schemaQualified = false)
203249

204250
public function getColumns($table)
205251
{
206-
$stats = $this->connection->getDatabase()->selectCollection($table)->aggregate([
252+
$db = null;
253+
if (str_contains($table, '.')) {
254+
[$db, $table] = explode('.', $table, 2);
255+
}
256+
257+
$stats = $this->connection->getDatabase($db)->selectCollection($table)->aggregate([
207258
// Sample 1,000 documents to get a representative sample of the collection
208259
['$sample' => ['size' => 1_000]],
209260
// Convert each document to an array of fields
@@ -340,10 +391,14 @@ public function getCollection($name)
340391
/**
341392
* Get all of the collections names for the database.
342393
*
394+
* @deprecated
395+
*
343396
* @return array
344397
*/
345398
protected function getAllCollections()
346399
{
400+
trigger_error(sprintf('Since mongodb/laravel-mongodb:5.4, Method "%s()" is deprecated without replacement.', __METHOD__), E_USER_DEPRECATED);
401+
347402
$collections = [];
348403
foreach ($this->connection->getDatabase()->listCollections() as $collection) {
349404
$collections[] = $collection->getName();

‎tests/SchemaTest.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ class SchemaTest extends TestCase
2222
{
2323
public function tearDown(): void
2424
{
25-
$database = $this->getConnection('mongodb')->getMongoDB();
25+
$database = $this->getConnection('mongodb')->getDatabase();
2626
assert($database instanceof Database);
2727
$database->dropCollection('newcollection');
2828
$database->dropCollection('newcollection_two');
29+
$database->dropCollection('test_view');
2930

3031
parent::tearDown();
3132
}
@@ -395,6 +396,7 @@ public function testGetTables()
395396
{
396397
DB::connection('mongodb')->table('newcollection')->insert(['test' => 'value']);
397398
DB::connection('mongodb')->table('newcollection_two')->insert(['test' => 'value']);
399+
DB::connection('mongodb')->getDatabase()->createCollection('test_view', ['viewOn' => 'newcollection']);
398400
$dbName = DB::connection('mongodb')->getDatabaseName();
399401

400402
$tables = Schema::getTables();
@@ -406,6 +408,7 @@ public function testGetTables()
406408
$this->assertArrayHasKey('size', $table);
407409
$this->assertArrayHasKey('schema', $table);
408410
$this->assertArrayHasKey('schema_qualified_name', $table);
411+
$this->assertNotEquals('test_view', $table['name'], 'Standard views should not be included in the result of getTables.');
409412

410413
if ($table['name'] === 'newcollection') {
411414
$this->assertEquals(8192, $table['size']);
@@ -420,6 +423,40 @@ public function testGetTables()
420423
}
421424
}
422425

426+
public function testGetViews()
427+
{
428+
DB::connection('mongodb')->table('newcollection')->insert(['test' => 'value']);
429+
DB::connection('mongodb')->table('newcollection_two')->insert(['test' => 'value']);
430+
$dbName = DB::connection('mongodb')->getDatabaseName();
431+
432+
DB::connection('mongodb')->getDatabase()->createCollection('test_view', ['viewOn' => 'newcollection']);
433+
434+
$tables = Schema::getViews();
435+
436+
$this->assertIsArray($tables);
437+
$this->assertGreaterThanOrEqual(1, count($tables));
438+
$found = false;
439+
foreach ($tables as $table) {
440+
$this->assertArrayHasKey('name', $table);
441+
$this->assertArrayHasKey('size', $table);
442+
$this->assertArrayHasKey('schema', $table);
443+
$this->assertArrayHasKey('schema_qualified_name', $table);
444+
445+
// Ensure "normal collections" are not in the views list
446+
$this->assertNotEquals('newcollection', $table['name'], 'Normal collections should not be included in the result of getViews.');
447+
448+
if ($table['name'] === 'test_view') {
449+
$this->assertEquals($dbName, $table['schema']);
450+
$this->assertEquals($dbName . '.test_view', $table['schema_qualified_name']);
451+
$found = true;
452+
}
453+
}
454+
455+
if (! $found) {
456+
$this->fail('Collection "test_view" not found');
457+
}
458+
}
459+
423460
public function testGetTableListing()
424461
{
425462
DB::connection('mongodb')->table('newcollection')->insert(['test' => 'value']);
@@ -489,6 +526,11 @@ public function testGetColumns()
489526
// Non-existent collection
490527
$columns = Schema::getColumns('missing');
491528
$this->assertSame([], $columns);
529+
530+
// Qualified table name
531+
$columns = Schema::getColumns(DB::getDatabaseName() . '.newcollection');
532+
$this->assertIsArray($columns);
533+
$this->assertCount(5, $columns);
492534
}
493535

494536
/** @see AtlasSearchTest::testGetIndexes() */

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /