Skip to content

Commit 1fe921d

Browse files
authored
Merge pull request #5504 from Laravel-Backpack/load-on-demand-and-fix-index-query
DB schema was loading ALL tables when not necessary
2 parents 785f8f8 + 57b8c6e commit 1fe921d

File tree

3 files changed

+62
-60
lines changed

3 files changed

+62
-60
lines changed

src/app/Library/Database/DatabaseSchema.php

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Backpack\CRUD\app\Library\Database;
44

5+
use Illuminate\Support\Arr;
56
use Illuminate\Support\Facades\DB;
67
use Illuminate\Support\LazyCollection;
78

@@ -12,28 +13,39 @@ final class DatabaseSchema
1213
/**
1314
* Return the schema for the table.
1415
*/
15-
public static function getForTable(string $connection, string $table)
16+
public static function getForTable(string $table, string $connection)
1617
{
1718
$connection = $connection ?: config('database.default');
1819

19-
self::generateDatabaseSchema($connection);
20+
self::generateDatabaseSchema($connection, $table);
2021

2122
return self::$schema[$connection][$table] ?? null;
2223
}
2324

2425
public static function getTables(string $connection = null): array
2526
{
2627
$connection = $connection ?: config('database.default');
27-
self::generateDatabaseSchema($connection);
2828

29-
return self::$schema[$connection] ?? [];
29+
self::$schema[$connection] = LazyCollection::make(self::getCreateSchema($connection)->getTables())->mapWithKeys(function ($table, $key) use ($connection) {
30+
$tableName = is_array($table) ? $table['name'] : $table->getName();
31+
32+
if ($existingTable = self::$schema[$connection][$tableName] ?? false) {
33+
return [$tableName => $existingTable];
34+
}
35+
36+
$table = self::mapTable($connection, $tableName);
37+
38+
return [$tableName => $table];
39+
})->toArray();
40+
41+
return self::$schema[$connection];
3042
}
3143

3244
public function listTableColumnsNames(string $connection, string $table)
3345
{
34-
$table = self::getForTable($connection, $table);
46+
$table = self::getForTable($table, $connection);
3547

36-
return array_keys($table->getColumns());
48+
return $table ? array_keys($table->getColumns()) : [];
3749
}
3850

3951
public function listTableIndexes(string $connection, string $table)
@@ -51,59 +63,53 @@ public function getManager(string $connection = null)
5163
/**
5264
* Generates and store the database schema.
5365
*/
54-
private static function generateDatabaseSchema(string $connection)
66+
private static function generateDatabaseSchema(string $connection, string $table)
5567
{
56-
if (! isset(self::$schema[$connection])) {
57-
self::$schema[$connection] = self::mapTables($connection);
68+
if (! isset(self::$schema[$connection][$table])) {
69+
self::$schema[$connection][$table] = self::mapTable($connection, $table);
5870
}
5971
}
6072

61-
/**
62-
* Map the tables from raw db values into an usable array.
63-
*
64-
* @param string $connection
65-
* @return array
66-
*/
67-
private static function mapTables(string $connection)
73+
private static function mapTable(string $connection, string $tableName)
6874
{
69-
return LazyCollection::make(self::getCreateSchema($connection)->getTables())->mapWithKeys(function ($table, $key) use ($connection) {
70-
$tableName = is_array($table) ? $table['name'] : $table->getName();
71-
72-
if (self::$schema[$connection][$tableName] ?? false) {
73-
return [$tableName => self::$schema[$connection][$tableName]];
74-
}
75-
76-
if (is_array($table)) {
77-
$table = new Table($tableName, self::mapTableColumns($connection, $tableName));
78-
}
75+
try {
76+
$table = method_exists(self::getCreateSchema($connection), 'getTable') ?
77+
self::getCreateSchema($connection)->getTable($tableName) :
78+
self::getCreateSchema($connection)->getColumns($tableName);
79+
} catch (\Exception $e) {
80+
return new Table($tableName, []);
81+
}
7982

80-
return [$tableName => $table];
81-
})->toArray();
82-
}
83+
if (! is_array($table) || empty($table)) {
84+
return $table;
85+
}
8386

84-
private static function getIndexColumnNames(string $connection, string $table)
85-
{
8687
$schemaManager = self::getSchemaManager($connection);
87-
$indexes = method_exists($schemaManager, 'listTableIndexes') ? $schemaManager->listTableIndexes($table) : $schemaManager->getIndexes($table);
88+
$indexes = $schemaManager->getIndexes($tableName);
8889

8990
$indexes = array_map(function ($index) {
90-
return is_array($index) ? $index['columns'] : $index->getColumns();
91+
return $index['columns'];
9192
}, $indexes);
9293

93-
$indexes = \Illuminate\Support\Arr::flatten($indexes);
94+
$table = new Table($tableName, $table);
9495

95-
return array_unique($indexes);
96+
$indexes = Arr::flatten($indexes);
97+
$table->setIndexes(array_unique($indexes));
98+
99+
return $table;
96100
}
97101

98-
private static function mapTableColumns(string $connection, string $table)
102+
private static function getIndexColumnNames(string $connection, string $table)
99103
{
100-
$indexedColumns = self::getIndexColumnNames($connection, $table);
104+
self::generateDatabaseSchema($connection, $table);
101105

102-
return LazyCollection::make(self::getSchemaManager($connection)->getColumns($table))->mapWithKeys(function ($column, $key) use ($indexedColumns) {
103-
$column['index'] = array_key_exists($column['name'], $indexedColumns) ? true : false;
106+
$indexes = self::$schema[$connection][$table]->getIndexes();
104107

105-
return [$column['name'] => $column];
106-
})->toArray();
108+
$indexes = \Illuminate\Support\Arr::flatten(array_map(function ($index) {
109+
return is_string($index) ? $index : $index->getColumns();
110+
}, $indexes));
111+
112+
return array_unique($indexes);
107113
}
108114

109115
private static function getCreateSchema(string $connection)

src/app/Library/Database/Table.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ final class Table
66
{
77
private string $name;
88
private array $columns = [];
9+
private array $indexes = [];
910

1011
public function __construct(string $name, array $columns = [])
1112
{
@@ -74,4 +75,14 @@ public function getColumn(string $columnName)
7475
{
7576
return $this->columns[$columnName];
7677
}
78+
79+
public function getIndexes()
80+
{
81+
return $this->indexes;
82+
}
83+
84+
public function setIndexes(array $indexes)
85+
{
86+
$this->indexes = $indexes;
87+
}
7788
}

src/app/Library/Database/TableSchema.php

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class TableSchema
99

1010
public function __construct(string $connection, string $table)
1111
{
12-
$this->schema = app('DatabaseSchema')->getForTable($connection, $table);
12+
$this->schema = app('DatabaseSchema')->getForTable($table, $connection);
1313
}
1414

1515
/**
@@ -66,7 +66,7 @@ public function hasColumn($columnName)
6666
*/
6767
public function columnIsNullable($columnName)
6868
{
69-
if (! $this->columnExists($columnName)) {
69+
if (! $this->hasColumn($columnName)) {
7070
return true;
7171
}
7272

@@ -83,7 +83,7 @@ public function columnIsNullable($columnName)
8383
*/
8484
public function columnHasDefault($columnName)
8585
{
86-
if (! $this->columnExists($columnName)) {
86+
if (! $this->hasColumn($columnName)) {
8787
return false;
8888
}
8989

@@ -100,7 +100,7 @@ public function columnHasDefault($columnName)
100100
*/
101101
public function getColumnDefault($columnName)
102102
{
103-
if (! $this->columnExists($columnName)) {
103+
if (! $this->hasColumn($columnName)) {
104104
return false;
105105
}
106106

@@ -123,21 +123,6 @@ public function getColumns()
123123
return $this->schema->getColumns();
124124
}
125125

126-
/**
127-
* Make sure column exists or throw an exception.
128-
*
129-
* @param string $columnName
130-
* @return bool
131-
*/
132-
private function columnExists($columnName)
133-
{
134-
if (! $this->schemaExists()) {
135-
return false;
136-
}
137-
138-
return $this->schema->hasColumn($columnName);
139-
}
140-
141126
/**
142127
* Make sure the schema for the connection is initialized.
143128
*

0 commit comments

Comments
 (0)