Add indexes to the database. #60

Merged
krzysiej merged 1 commits from feature/add-database-indexes into master 2026-02-05 09:10:06 +01:00
3 changed files with 57 additions and 9 deletions
Showing only changes of commit 67019e3933 - Show all commits

View File

@@ -190,15 +190,63 @@ class Migrate extends Command
public function index(): void public function index(): void
{ {
if (!count(Capsule::select('SELECT name FROM sqlite_master WHERE type = "index" and name = "products_skuid_country_id_unique"'))) { if (!$this->hasIndex('products_skuid_country_id_unique')) {
Capsule::schema()->table('products', function (Blueprint $table) { Capsule::schema()->table('products', function (Blueprint $table) {
if ($this->hasIndex('products_skuid_unique')) {
$table->integer('skuID')->unique(false)->change(); $table->integer('skuID')->unique(false)->change();
}
$table->unique(['skuID', 'country_id']); $table->unique(['skuID', 'country_id']);
}); });
} }
if (!$this->hasIndex('prices_product_id_index')) {
Capsule::schema()->table('prices', function (Blueprint $table) {
$table->index('product_id');
});
}
if (!$this->hasIndex('products_id_index')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->index('id');
});
}
if (!$this->hasIndex('stocks_product_id_stock_index')) {
Capsule::schema()->table('stocks', function (Blueprint $table) {
$table->index(['product_id', 'stock']);
});
}
if (!$this->isFK('products', 'id', 'stocks', 'product_id')) {
Capsule::schema()->table('products', function (Blueprint $table) { Capsule::schema()->table('products', function (Blueprint $table) {
$table->foreign('id')->references('product_id')->on('stocks'); $table->foreign('id')->references('product_id')->on('stocks');
}); });
} }
if (!$this->isFK('products', 'id', 'prices', 'product_id')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->foreign('id')->references('product_id')->on('prices');
});
}
if (!$this->isFK('products', 'country_id', 'countries', 'id')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->foreign('country_id')->references('id')->on('countries');
});
}
}
private function isFK(string $table, string $column, string $fTable, string $fColumn): bool
{
$fkColumns = Capsule::schema()->getForeignKeys($table);
return !empty(array_filter($fkColumns, fn($fkColumn) => ($fkColumn['foreign_table'] == $fTable &&
in_array($fColumn, $fkColumn['foreign_columns']) &&
in_array($column, $fkColumn['columns']))
));
}
private function hasIndex(string $indexName): bool
{
return !!count(Capsule::select('SELECT name FROM sqlite_master WHERE type = "index" and name = ?', [$indexName]));
}
} }

View File

@@ -14,11 +14,11 @@ final class IndexController extends BaseController
if ($this->cache->getItem('list_all')->isHit()) { if ($this->cache->getItem('list_all')->isHit()) {
return $this->render('productList.html.twig', ['listType' => 'all']); return $this->render('productList.html.twig', ['listType' => 'all']);
} }
$products = Product::with(['currentStock']) $products = Product::orderByDesc('starred')
->orderByDesc('starred')
->orderByDesc('created_by') ->orderByDesc('created_by')
->get(); ->get();
return $this->render('productList.html.twig', ['products' => $products, 'listType' => 'all']); return $this->render('productList.html.twig', ['products' => $products, 'listType' => 'all']);
} }
} }

View File

@@ -63,7 +63,7 @@ class Product extends Model
public function newestPrice(): HasOne public function newestPrice(): HasOne
{ {
return $this->hasOne(Price::class)->latest(); return $this->hasOne(Price::class)->latest()->take(1);
} }
public function stock(): HasMany public function stock(): HasMany
@@ -73,7 +73,7 @@ class Product extends Model
public function currentStock(): HasOne public function currentStock(): HasOne
{ {
return $this->stock()->one()->ofMany()->withDefault(fn(Stock $stock) => $stock->stock = 0); return $this->stock()->one()->ofMany()->withDefault(fn(Stock $stock) => $stock->stock = 0)->take(1);
} }
public function toggleStarred(): self public function toggleStarred(): self