mongoose-studio/phobos-framework-database-sqlite
Composer 安装命令:
composer require mongoose-studio/phobos-framework-database-sqlite
包简介
Phobos Framework SQLite Connector for Database Layer
README 文档
README
Driver SQLite para Phobos Framework Database Layer. Cero configuración de servidor: conecta a un archivo .sqlite o a una base de datos en memoria (:memory:), con las claves foráneas activadas por defecto y los PRAGMAs más útiles expuestos como opciones de conexión.
Es el driver ideal para tests (SQLite en memoria, rápido y aislado), prototipos y aplicaciones de escritorio o embebidas.
Características
- 🪶 Sin servidor - Un archivo o
:memory:, sin host, puerto ni credenciales - 🔒 Foreign keys activas por defecto - SQLite las trae apagadas; este driver las enciende
- ⚡ PRAGMAs comunes -
journal_mode(WAL),busy_timeout,synchronous - 🎯 Savepoints - Transacciones anidadas completas
- 🧪 Ideal para testing -
:memory:da una BD limpia por proceso - 🛡️ Valores validados - Los PRAGMAs pasan por lista blanca para evitar inyección
- 🏷️ Identificadores estándar - Citado con comillas dobles
Instalación
composer require mongoose-studio/phobos-framework-database-sqlite
Dependencias
Este driver requiere:
mongoose-studio/phobos-framework^3.1mongoose-studio/phobos-framework-database^3.2- Extensión
ext-pdohabilitada - Extensión
ext-pdo_sqlitehabilitada
Configuración
1. Registrar el Driver
En tu config/database.php:
<?php return [ 'default' => 'sqlite', 'drivers' => [ 'sqlite' => PhobosFramework\Database\Drivers\SQLite\SQLiteDriver::class, ], 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', 'database' => storage_path('database/app.sqlite'), 'foreign_keys' => true, 'journal_mode' => 'WAL', ], ], ];
2. Variables de Entorno
En tu archivo .env:
DB_CONNECTION=sqlite DB_DATABASE=/ruta/absoluta/a/database/app.sqlite
Opciones de Configuración
A diferencia de MySQL, SQLite no usa host, port, username, password, charset ni collation. La única opción obligatoria es database.
database (obligatorio)
'sqlite' => [ 'driver' => 'sqlite', 'database' => '/var/data/app.sqlite', // Ruta al archivo // 'database' => ':memory:', // Base de datos en memoria ]
| Valor | Resultado |
|---|---|
| Ruta a un archivo | sqlite:/var/data/app.sqlite — persiste en disco |
:memory: |
sqlite::memory: — vive en RAM, se pierde al cerrar la conexión |
Nota sobre
:memory:: cada conexión PDO nueva crea una base de datos en memoria independiente. Mientras reutilices la misma conexión (como hace elConnectionManager), los datos persisten durante todo el proceso — perfecto para una suite de tests.
foreign_keys (por defecto true)
SQLite trae las claves foráneas desactivadas por defecto (una de las trampas más comunes del motor). Este driver las activa salvo que lo indiques explícitamente:
'sqlite' => [ // ... 'foreign_keys' => true, // Default. Ejecuta PRAGMA foreign_keys = ON // 'foreign_keys' => false, // Desactiva las restricciones FK ]
journal_mode
Controla el modo de journaling. WAL (Write-Ahead Logging) suele ser la mejor opción para concurrencia:
'sqlite' => [ // ... 'journal_mode' => 'WAL', ]
Valores válidos: DELETE, TRUNCATE, PERSIST, MEMORY, WAL, OFF.
WAL- Mejor concurrencia (lectores no bloquean al escritor). Recomendado para archivos.MEMORY- Journal en RAM, más rápido pero menos seguro ante caídas.DELETE- Comportamiento clásico por defecto de SQLite.
busy_timeout
Milisegundos que SQLite espera ante un bloqueo antes de devolver SQLITE_BUSY:
'sqlite' => [ // ... 'busy_timeout' => 5000, // Espera hasta 5 segundos ]
synchronous
Nivel de sincronización con disco. Compromiso entre durabilidad y velocidad:
'sqlite' => [ // ... 'synchronous' => 'NORMAL', ]
Valores válidos: OFF, NORMAL, FULL, EXTRA (o sus equivalentes numéricos 0, 1, 2, 3).
FULL- Máxima durabilidad (default de SQLite).NORMAL- Buen equilibrio, recomendado con WAL.OFF- El más rápido, pero puede corromper datos ante un corte de energía.
Opciones PDO Adicionales
'sqlite' => [ // ... 'options' => [ PDO::ATTR_TIMEOUT => 5, ], ]
Características Específicas de SQLite
Identificadores con Comillas Dobles
El driver usa comillas dobles para identificadores (el estándar SQL):
// quoteIdentifier() genera: "users" "weird ""column""" // escapa comillas dobles internas
SQLite también acepta backticks (por compatibilidad con MySQL), por lo que el Query Builder del núcleo funciona sin cambios sobre este driver.
Transacciones Anidadas (Savepoints)
SQLite soporta savepoints, así que las transacciones anidadas del TransactionManager funcionan igual que en MySQL:
$tm = db()->getTransactionManager(); $tm->begin(); // BEGIN try { // ... operaciones ... $sp = $tm->begin(); // SAVEPOINT anidado try { // ... más operaciones ... $tm->commit($sp); // RELEASE SAVEPOINT } catch (Exception $e) { $tm->rollback($sp); // ROLLBACK TO SAVEPOINT (solo lo anidado) } $tm->commit(); // COMMIT de la transacción externa } catch (Exception $e) { $tm->rollback(); // ROLLBACK completo }
Niveles de Aislamiento
SQLite es SERIALIZABLE de forma nativa. A diferencia de MySQL, no soporta READ COMMITTED ni REPEATABLE READ. Lo único que puede relajarse es a READ UNCOMMITTED (y solo tiene efecto en modo shared-cache):
$driver = new SQLiteDriver(); $driver->getSetIsolationLevelSQL('SERIALIZABLE'); // PRAGMA read_uncommitted = 0 $driver->getSetIsolationLevelSQL('READ UNCOMMITTED'); // PRAGMA read_uncommitted = 1 $driver->getSetIsolationLevelSQL('READ COMMITTED'); // ❌ InvalidArgumentException $driver->getSetIsolationLevelSQL('REPEATABLE READ'); // ❌ InvalidArgumentException
Pedir un nivel que SQLite no soporta lanza una InvalidArgumentException explícita, en vez de generar SQL inválido silenciosamente.
Ejemplos de Uso
Testing (SQLite en memoria)
La configuración de oro para una suite de tests: rápida, aislada y sin dejar rastro en disco.
'sqlite_test' => [ 'driver' => 'sqlite', 'database' => ':memory:', 'foreign_keys' => true, ]
use PhobosFramework\Database\Connection\ConnectionManager; use PhobosFramework\Database\Drivers\SQLite\SQLiteDriver; $manager = ConnectionManager::getInstance(); $manager->registerDriver('sqlite', new SQLiteDriver()); $manager->addConnection('default', [ 'driver' => 'sqlite', 'database' => ':memory:', ]); $manager->setDefaultConnection('default'); // Crear el esquema una vez y ejercitar tus entidades contra él $manager->getConnection()->getPDO()->exec(' CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL ) ');
Aplicación con archivo persistente
'sqlite' => [ 'driver' => 'sqlite', 'database' => storage_path('database/app.sqlite'), 'foreign_keys' => true, 'journal_mode' => 'WAL', // Mejor concurrencia 'synchronous' => 'NORMAL', // Equilibrio con WAL 'busy_timeout' => 5000, // Tolera bloqueos breves ]
Arquitectura
Estructura del Driver
SQLiteDriver
├── getDSN() - Construye el DSN (archivo o :memory:)
├── getPDOOptions() - Opciones PDO seguras (heredadas de AbstractDriver)
├── configure() - Aplica PRAGMAs post-conexión
├── getName() - Retorna 'sqlite'
├── supportsSavepoints() - Retorna true
├── quoteIdentifier() - Envuelve en comillas dobles
├── getSetIsolationLevelSQL() - SERIALIZABLE / READ UNCOMMITTED (vía PRAGMA)
└── getLastInsertId() - ROWID de la última inserción (ignora la secuencia)
Proceso de Conexión
-
DSN Generation:
getDSN()construye la cadena- Archivo:
sqlite:/ruta/a/app.sqlite - Memoria:
sqlite::memory:
- Archivo:
-
PDO Creation: Se crea la instancia PDO con las opciones seguras por defecto (modo de error por excepción, fetch asociativo, prepares nativos).
-
Post-Connection Config:
configure()ejecuta los PRAGMAsPRAGMA foreign_keys(ON por defecto)PRAGMA journal_modesi se configuróPRAGMA busy_timeoutsi se configuróPRAGMA synchronoussi se configuró
Compatibilidad
- SQLite 3.x (vía
ext-pdo_sqlite) - Soporte completo de savepoints y claves foráneas (SQLite 3.6.19+)
- WAL disponible desde SQLite 3.7.0+
🐛 Troubleshooting
Las claves foráneas no se respetan
Si esperabas que un INSERT con una FK inválida fallara y no lo hace, revisa que no hayas puesto 'foreign_keys' => false. Recuerda que SQLite las trae apagadas por defecto: este driver las activa, pero solo si no las desactivas explícitamente.
SQLSTATE[HY000]: database is locked
SQLite bloquea el archivo completo durante una escritura. Mitiga con:
'journal_mode' => 'WAL', // Lectores no bloquean al escritor 'busy_timeout' => 5000, // Espera en vez de fallar de inmediato
unable to open database file
SQLSTATE[HY000] [14] unable to open database file
- Verifica que el directorio del archivo exista (SQLite crea el archivo, no las carpetas).
- Verifica permisos de escritura en el directorio.
- Usa una ruta absoluta para evitar sorpresas con el directorio de trabajo.
Los datos de :memory: desaparecen entre partes del código
Cada conexión PDO nueva a :memory: es una base distinta. Asegúrate de reutilizar la misma conexión (el ConnectionManager la cachea). No abras un PDO nuevo esperando ver los datos de otro.
Licencia
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
Autor
Marcel Rojas
marcelrojas16@gmail.com
Mongoose Studio
Contribuciones
Las contribuciones son bienvenidas. Por favor:
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/amazing-feature) - Commit tus cambios (
git commit -m 'Add amazing feature') - Push a la rama (
git push origin feature/amazing-feature) - Abre un Pull Request
Phobos Framework by Mongoose Studio
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-14