ADR-002 - Abstrakce databáze
ADR-002: Abstrakce databáze
Sekce “ADR-002: Abstrakce databáze”Záznam rozhodnutí o architektuře pro vzor objektově orientovaného přístupu k databázi XOOPS.
Stav
Sekce “Stav”Přijato – Vzor jádra od XOOPS 2.0
Souvislosti
Sekce “Souvislosti”XOOPS potřeboval strategii interakce s databází, která by:
- Syntaxe SQL specifická pro databázi
- Zajistěte konzistentní operace CRUD napříč všemi moduly
- Povolte automatickou dezinfekci a únik dat
- Podporujte budoucí změny databázového stroje
- Zjednodušte vývojářům běžné operace
Alternativy byly:
- Nezpracované SQL v celé kódové základně
- Plná ORM (doktrína, výmluvná)
- Vlastní lehká abstrakce
Diagram rozhodnutí
Sekce “Diagram rozhodnutí”graph TB subgraph "Application Layer" A[Module Code] B[Handler Methods] end
subgraph "Abstraction Layer" C[XOOPSObjectHandler] D[XOOPSPersistableObjectHandler] E[Criteria System] end
subgraph "Database Layer" F[XOOPSDatabase] G[MySQLDatabase] H[PDO Wrapper] end
subgraph "Storage" I[(MySQL/MariaDB)] end
A --> B B --> C B --> D C --> E D --> E E --> F F --> G F --> H G --> I H --> IRozhodnutí
Sekce “Rozhodnutí”Implementujeme Vzor manipulátoru s:
1. XOOPSObject – datový kontejner
Sekce “1. XOOPSObject – datový kontejner”Každá datová entita rozšiřuje XOOPSObject:
class Item extends XOOPSObject{ public function __construct() { $this->initVar('id', XOBJ_DTYPE_INT, null, false); $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255); $this->initVar('content', XOBJ_DTYPE_TXTAREA, '', false); $this->initVar('status', XOBJ_DTYPE_INT, 0, false); }}2. Handler - Operations Manager
Sekce “2. Handler - Operations Manager”Každý objekt má odpovídající handler:
class ItemHandler extends XOOPSPersistableObjectHandler{ public function __construct($db) { parent::__construct($db, 'mymodule_items', Item::class, 'id', 'title'); }
// CRUD methods inherited: // - create(), get(), insert(), delete() // - getObjects(), getCount(), getAll()}3. Kritéria – Tvůrce dotazů
Sekce “3. Kritéria – Tvůrce dotazů”Podmínky objektově orientovaného dotazu:
$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 1));$criteria->add(new Criteria('created', time() - 86400, '>='));$criteria->setSort('created');$criteria->setOrder('DESC');$criteria->setLimit(10);
$items = $handler->getObjects($criteria);Konstanty datového typu
Sekce “Konstanty datového typu”// Variable types with automatic sanitizationXOBJ_DTYPE_INT // IntegerXOBJ_DTYPE_TXTBOX // Single-line text (escaped)XOBJ_DTYPE_TXTAREA // Multi-line text (escaped)XOBJ_DTYPE_EMAIL // Email validationXOBJ_DTYPE_URL // URL validationXOBJ_DTYPE_ARRAY // Serialized arrayXOBJ_DTYPE_OTHER // No processingXOBJ_DTYPE_FLOAT // Floating pointDědičnost manipulátoru
Sekce “Dědičnost manipulátoru”classDiagram class XOOPSObjectHandler { <<abstract>> #db: XOOPSDatabase +create(): XOOPSObject +get(id): XOOPSObject +insert(object): bool +delete(object): bool }
class XOOPSPersistableObjectHandler { +getObjects(criteria): array +getCount(criteria): int +getAll(criteria): array +deleteAll(criteria): bool +updateAll(field, value, criteria): bool }
class ItemHandler { +getPublishedItems(): array +getByCategory(catId): array }
XOOPSObjectHandler <|-- XOOPSPersistableObjectHandler XOOPSPersistableObjectHandler <|-- ItemHandlerNásledky
Sekce “Následky”Pozitivní
Sekce “Pozitivní”- Konzistence: Všechny moduly používají stejné vzory
- Zabezpečení: Automatický únik zabraňuje vstřikování SQL
- Jednoduchost: Běžné operace vyžadují minimální kód
- Udržovatelnost: Změny v databázové vrstvě neovlivňují moduly
- Testovatelnost: Obslužné rutiny lze pro testování zesměšňovat
Negativní
Sekce “Negativní”- Výkon: Extra režie abstrakce
- Složitost: Křivka učení pro nové vývojáře
- Omezení: Komplexní dotazy mohou vyžadovat nezpracovaný SQL
- N+1 Problém: Žádné vestavěné dychtivé načítání
Zmírnění
Sekce “Zmírnění”- Výkon: Ukládání často používaných objektů do mezipaměti
- Složité dotazy: V případě potřeby povolte nezpracované SQL
- N+1: Použijte getAll() se správnými kritérii
Evolution to XOOPS 4.0
Sekce “Evolution to XOOPS 4.0”flowchart LR subgraph "Current (2.5.x)" A[XOOPSDatabase] B[Handlers] C[Criteria] end
subgraph "Future (4.0.x)" D[PDO/DBAL] E[Repository Pattern] F[Query Builder] G[DI Container] end
A --> D B --> E C --> F D --> G E --> GPlány XOOPS 4.0:
- Doktrína DBAL pro abstrakci databáze
- Vzor úložiště nahrazující handlery
- Tvůrce dotazů pro složité dotazy
- Plná integrace kontejneru PSR-11
Příklady kódu
Sekce “Příklady kódu”Základní CRUD
Sekce “Základní CRUD”$helper = Helper::getInstance();$handler = $helper->getHandler('Item');
// Create$item = $handler->create();$item->setVar('title', 'New Item');$handler->insert($item);
// Read$item = $handler->get($id);$title = $item->getVar('title');
// Update$item->setVar('title', 'Updated Title');$handler->insert($item);
// Delete$handler->delete($item);Komplexní dotaz
Sekce “Komplexní dotaz”$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 'published'));$criteria->add(new Criteria('category_id', '(1,2,3)', 'IN'));$criteria->add(new Criteria('created', strtotime('-30 days'), '>='));$criteria->setSort('views');$criteria->setOrder('DESC');$criteria->setLimit(10);$criteria->setStart(0);
$items = $handler->getObjects($criteria);$total = $handler->getCount($criteria);Související rozhodnutí
Sekce “Související rozhodnutí”- ADR-001: Modulární architektura
- ADR-003: Smarty šablonový modul
Reference
Sekce “Reference”- Martin Fowler - Vzory podnikové aplikační architektury
- Domain-Driven Design koncepty
- Vzory Active Record vs Data Mapper
#xoops #architecture #adr #database #handler #design-decision