ADR-002 - Abstração de Banco de Dados
ADR-002: Abstração de Banco de Dados
Seção intitulada “ADR-002: Abstração de Banco de Dados”Registro de Decisão de Arquitetura para padrão de acesso ao banco de dados orientado a objetos do XOOPS.
Aceito - Padrão principal desde XOOPS 2.0
Contexto
Seção intitulada “Contexto”XOOPS precisava de uma estratégia de interação com banco de dados que:
- Abstraísse sintaxe SQL específica do banco de dados
- Fornecesse operações CRUD consistentes em todos os módulos
- Permitisse desinfecção automática de dados e escape
- Suportasse futuras mudanças de mecanismo de banco de dados
- Simplificasse operações comuns para desenvolvedores
As alternativas eram:
- SQL bruto em toda a base de código
- ORM completo (Doctrine, Eloquent)
- Abstração customizada leve
Diagrama de Decisão
Seção intitulada “Diagrama de Decisão”graph TB subgraph "Camada de Aplicação" A[Código de Módulo] B[Métodos de Manipulador] end
subgraph "Camada de Abstração" C[XoopsObjectHandler] D[XoopsPersistableObjectHandler] E[Sistema de Critérios] end
subgraph "Camada de Banco de Dados" F[XoopsDatabase] G[MySQLDatabase] H[Wrapper PDO] end
subgraph "Armazenamento" I[(MySQL/MariaDB)] end
A --> B B --> C B --> D C --> E D --> E E --> F F --> G F --> H G --> I H --> IDecisão
Seção intitulada “Decisão”Implementaremos um Padrão de Manipulador com:
1. XoopsObject - Recipiente de Dados
Seção intitulada “1. XoopsObject - Recipiente de Dados”Cada entidade de dados estende 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. Manipulador - Gerenciador de Operações
Seção intitulada “2. Manipulador - Gerenciador de Operações”Cada objeto possui um manipulador correspondente:
class ItemHandler extends XoopsPersistableObjectHandler{ public function __construct($db) { parent::__construct($db, 'mymodule_items', Item::class, 'id', 'title'); }
// Métodos CRUD herdados: // - create(), get(), insert(), delete() // - getObjects(), getCount(), getAll()}3. Critérios - Construtor de Consultas
Seção intitulada “3. Critérios - Construtor de Consultas”Condições de consulta orientadas a objetos:
$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);Constantes de Tipo de Dados
Seção intitulada “Constantes de Tipo de Dados”// Tipos de variáveis com sanitização automáticaXOBJ_DTYPE_INT // InteiroXOBJ_DTYPE_TXTBOX // Texto de uma linha (escapado)XOBJ_DTYPE_TXTAREA // Texto de múltiplas linhas (escapado)XOBJ_DTYPE_EMAIL // Validação de emailXOBJ_DTYPE_URL // Validação de URLXOBJ_DTYPE_ARRAY // Array serializadoXOBJ_DTYPE_OTHER // Sem processamentoXOBJ_DTYPE_FLOAT // Ponto flutuanteHerança de Manipulador
Seção intitulada “Herança de Manipulador”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 <|-- ItemHandlerConsequências
Seção intitulada “Consequências”Positivas
Seção intitulada “Positivas”- Consistência: Todos os módulos usam os mesmos padrões
- Segurança: Escape automático previne injeção SQL
- Simplicidade: Operações comuns requerem código mínimo
- Manutenibilidade: Mudanças na camada de banco de dados não afetam módulos
- Testabilidade: Manipuladores podem ser simulados para testes
Negativas
Seção intitulada “Negativas”- Performance: Overhead de abstração extra
- Complexidade: Curva de aprendizado para novos desenvolvedores
- Limitações: Consultas complexas podem precisar de SQL bruto
- Problema N+1: Sem carregamento aprimorado integrado
Mitigações
Seção intitulada “Mitigações”- Performance: Cache de objetos acessados frequentemente
- Consultas complexas: Permitir SQL bruto quando necessário
- N+1: Use getAll() com critérios apropriados
Evolução para XOOPS 4.0
Seção intitulada “Evolução para XOOPS 4.0”flowchart LR subgraph "Atual (2.5.x)" A[XoopsDatabase] B[Handlers] C[Criteria] end
subgraph "Futuro (4.0.x)" D[PDO/DBAL] E[Padrão de Repositório] F[Construtor de Consultas] G[Contêiner DI] end
A --> D B --> E C --> F D --> G E --> GPlanos do XOOPS 4.0:
- Doctrine DBAL para abstração de banco de dados
- Padrão de repositório substituindo manipuladores
- Construtor de consultas para consultas complexas
- Integração completa de contêiner PSR-11
Exemplos de Código
Seção intitulada “Exemplos de Código”CRUD Básico
Seção intitulada “CRUD Básico”$helper = Helper::getInstance();$handler = $helper->getHandler('Item');
// Criar$item = $handler->create();$item->setVar('title', 'Novo Item');$handler->insert($item);
// Ler$item = $handler->get($id);$title = $item->getVar('title');
// Atualizar$item->setVar('title', 'Título Atualizado');$handler->insert($item);
// Deletar$handler->delete($item);Consulta Complexa
Seção intitulada “Consulta Complexa”$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);Decisões Relacionadas
Seção intitulada “Decisões Relacionadas”- ADR-001: Arquitetura Modular
- ADR-003: Motor de Template Smarty
Referências
Seção intitulada “Referências”- Martin Fowler - Patterns of Enterprise Application Architecture
- Conceitos de Domain-Driven Design
- Padrões Active Record vs Data Mapper
#xoops #architecture #adr #database #handler #design-decision