Skip to content

Commit 1115f8e

Browse files
masterbaterGromNaN
authored andcommitted
feat: separate virtual view and table
1 parent b543b64 commit 1115f8e

File tree

2 files changed

+80
-8
lines changed

2 files changed

+80
-8
lines changed

src/Schema/Builder.php

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public function dropAllTables()
143143
}
144144
}
145145

146-
/** @param string|null $schema Database name */
146+
/** @param string|null $schema Database name */
147147
public function getTables($schema = null)
148148
{
149149
$db = $this->connection->getDatabase($schema);
@@ -161,12 +161,8 @@ public function getTables($schema = null)
161161
$isView = ($collectionInfo['type'] ?? '') === 'view';
162162
$stats = null;
163163

164-
if (! $isView) {
165-
// Only run aggregation if it's a normal collection
166-
$stats = $db->selectCollection($collectionName)->aggregate([
167-
['$collStats' => ['storageStats' => ['scale' => 1]]],
168-
['$project' => ['storageStats.totalSize' => 1]],
169-
])->toArray();
164+
if ($isView) {
165+
continue;
170166
}
171167

172168
$collections[] = [
@@ -176,7 +172,45 @@ public function getTables($schema = null)
176172
'size' => $stats[0]?->storageStats?->totalSize ?? null,
177173
'comment' => null,
178174
'collation' => null,
179-
'engine' => $isView ? 'view' : 'collection',
175+
'engine' => null,
176+
];
177+
}
178+
179+
usort($collections, fn ($a, $b) => $a['name'] <=> $b['name']);
180+
181+
return $collections;
182+
}
183+
184+
/** @param string|null $schema Database name */
185+
public function getViews($schema = null)
186+
{
187+
$db = $this->connection->getDatabase($schema);
188+
$collections = [];
189+
190+
foreach ($db->listCollections() as $collectionInfo) {
191+
$collectionName = $collectionInfo->getName();
192+
193+
// Skip system collections
194+
if (str_starts_with($collectionName, 'system.')) {
195+
continue;
196+
}
197+
198+
// Skip views it doesnt suport aggregate
199+
$isView = ($collectionInfo['type'] ?? '') === 'view';
200+
$stats = null;
201+
202+
if (! $isView) {
203+
continue;
204+
}
205+
206+
$collections[] = [
207+
'name' => $collectionName,
208+
'schema' => $db->getDatabaseName(),
209+
'schema_qualified_name' => $db->getDatabaseName() . '.' . $collectionName,
210+
'size' => null,
211+
'comment' => null,
212+
'collation' => null,
213+
'engine' => null,
180214
];
181215
}
182216

tests/SchemaTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,44 @@ public function testGetTables()
431431
$this->fail('Collection "newcollection" not found');
432432
}
433433
}
434+
public function testGetViews()
435+
{
436+
DB::connection('mongodb')->table('newcollection')->insert(['test' => 'value']);
437+
DB::connection('mongodb')->table('newcollection_two')->insert(['test' => 'value']);
438+
$dbName = DB::connection('mongodb')->getDatabaseName();
439+
440+
441+
DB::connection('mongodb')->getDatabase()->command([
442+
'create' => 'test_view',
443+
'viewOn' => 'newcollection',
444+
'pipeline' => [],
445+
]);
446+
447+
$tables = Schema::getViews();
448+
449+
$this->assertIsArray($tables);
450+
$this->assertGreaterThanOrEqual(1, count($tables));
451+
$found = false;
452+
foreach ($tables as $table) {
453+
$this->assertArrayHasKey('name', $table);
454+
$this->assertArrayHasKey('size', $table);
455+
$this->assertArrayHasKey('schema', $table);
456+
$this->assertArrayHasKey('schema_qualified_name', $table);
457+
458+
if ($table['name'] === 'test_view') {
459+
$this->assertEquals($dbName, $table['schema']);
460+
$this->assertEquals($dbName . '.test_view', $table['schema_qualified_name']);
461+
$found = true;
462+
}
463+
464+
// Ensure system collections are excluded
465+
$this->assertFalse(str_starts_with($table['name'], 'system.'));
466+
}
467+
468+
if (! $found) {
469+
$this->fail('Collection "test_view" not found');
470+
}
471+
}
434472

435473
public function testGetTableListing()
436474
{

0 commit comments

Comments
 (0)