Problem Statement
The library currently supports MySQL and MSSQL only. SQLite is widely used for local development, testing, embedded applications, and lightweight deployments. Adding SQLite support would also enable running the full test suite without external database servers (using :memory: databases).
Proposed Solution
Add a complete SQLite driver following the existing engine pattern.
New Files
WebFiori/Database/Sqlite/
├── SQLiteConnection.php (extends Connection, uses PDO sqlite:)
├── SQLiteQuery.php (extends AbstractQuery)
├── SQLiteColumn.php (extends Column)
├── SQLiteTable.php (extends Table)
└── SQLiteInsertBuilder.php (extends InsertBuilder)
Implementation Phases
Phase 1: Connection & Core
SQLiteConnection using PDO with sqlite: DSN (file path or :memory:)
ConnectionInfo accepts 'sqlite' type (host/port/user/password ignored)
- Add
'sqlite' branches in Database dispatch (~4 locations)
- Run
PRAGMA foreign_keys = ON on connect
Phase 2: Schema & DDL
SQLiteTable generates CREATE TABLE with SQLite syntax
SQLiteColumn maps types to SQLite affinity (INTEGER, REAL, TEXT, BLOB)
INTEGER PRIMARY KEY for autoincrement (rowid alias)
- No engine/charset clauses
Phase 3: Query Builder
SQLiteQuery with standard SQL (double-quote identifier quoting)
SQLiteInsertBuilder with PDO positional placeholders
- Boolean→int cast in bindings
- LIMIT/OFFSET pagination
Phase 4: Factory & Attribute Integration
- Add
'sqlite' branch in TableFactory::create()
- Add
'sqlite' branch in ColumnFactory::create()
- Add
'sqlite' to ConnectionInfo::SUPPORTED_DATABASES
- Add SQLite to
DataType::$EngineTypes
- No changes needed to
#[Table], #[Column], #[ForeignKey] attributes
Phase 5: Type Mapping (TypesMap additions)
| DataType Constant |
MySQL |
MSSQL |
SQLite |
INT |
int |
int |
INTEGER |
BIGINT |
bigint |
bigint |
INTEGER |
FLOAT |
float |
float |
REAL |
DOUBLE |
double |
float |
REAL |
DECIMAL |
decimal(p,s) |
decimal(p,s) |
REAL |
MONEY |
decimal(10,2) |
money |
REAL |
BOOL |
bit(1) |
bit |
INTEGER |
BIT |
bit |
bit |
INTEGER |
VARCHAR |
varchar(n) |
varchar(n) |
TEXT |
CHAR |
char(n) |
char(n) |
TEXT |
NCHAR |
char(n) |
nchar(n) |
TEXT |
NVARCHAR |
varchar(n) |
nvarchar(n) |
TEXT |
TEXT |
text |
nvarchar(max) |
TEXT |
TEXT_MEDIUM |
mediumtext |
nvarchar(max) |
TEXT |
DATETIME |
datetime |
datetime2 |
TEXT |
TIMESTAMP |
timestamp |
datetime2 |
TEXT |
DATE |
date |
date |
TEXT |
TIME |
time |
time |
TEXT |
BLOB |
blob |
varbinary(max) |
BLOB |
BLOB_MEDIUM |
mediumblob |
varbinary(max) |
BLOB |
BLOB_LONG |
longblob |
varbinary(max) |
BLOB |
BLOB_TINY |
tinyblob |
varbinary(255) |
BLOB |
BINARY |
blob |
binary(n) |
BLOB |
VARBINARY |
blob |
varbinary(n) |
BLOB |
Phase 6: Testing
- Unit tests for SQL generation (no connection needed)
- Integration tests using
:memory: (no Docker required)
- Mirror existing MySQL test cases for feature parity
SQLite-Specific Considerations
- Dates: Stored as ISO-8601 TEXT strings; PHP-layer validation still applies
- Size on strings: Ignored by SQLite but preserved in metadata for cross-engine migrations
- ALTER TABLE: Limited (no DROP COLUMN pre-3.35). Migrations may need table-rebuild strategy
- No stored procedures:
MultiResultSet not applicable
- Concurrent writes: File-level locking; best for dev/testing/single-writer apps
- DECIMAL precision: Stored as REAL (IEEE 754 double); lossy for financial data
Alternatives Considered
- Using a third-party SQLite adapter — rejected to keep the library self-contained and consistent with existing architecture.
Breaking Change
No
Additional Context
This would make the test suite runnable without Docker/external databases — a significant improvement for CI speed and contributor onboarding.
Problem Statement
The library currently supports MySQL and MSSQL only. SQLite is widely used for local development, testing, embedded applications, and lightweight deployments. Adding SQLite support would also enable running the full test suite without external database servers (using
:memory:databases).Proposed Solution
Add a complete SQLite driver following the existing engine pattern.
New Files
Implementation Phases
Phase 1: Connection & Core
SQLiteConnectionusing PDO withsqlite:DSN (file path or:memory:)ConnectionInfoaccepts'sqlite'type (host/port/user/password ignored)'sqlite'branches inDatabasedispatch (~4 locations)PRAGMA foreign_keys = ONon connectPhase 2: Schema & DDL
SQLiteTablegenerates CREATE TABLE with SQLite syntaxSQLiteColumnmaps types to SQLite affinity (INTEGER, REAL, TEXT, BLOB)INTEGER PRIMARY KEYfor autoincrement (rowid alias)Phase 3: Query Builder
SQLiteQuerywith standard SQL (double-quote identifier quoting)SQLiteInsertBuilderwith PDO positional placeholdersPhase 4: Factory & Attribute Integration
'sqlite'branch inTableFactory::create()'sqlite'branch inColumnFactory::create()'sqlite'toConnectionInfo::SUPPORTED_DATABASESDataType::$EngineTypes#[Table],#[Column],#[ForeignKey]attributesPhase 5: Type Mapping (TypesMap additions)
INTintintINTEGERBIGINTbigintbigintINTEGERFLOATfloatfloatREALDOUBLEdoublefloatREALDECIMALdecimal(p,s)decimal(p,s)REALMONEYdecimal(10,2)moneyREALBOOLbit(1)bitINTEGERBITbitbitINTEGERVARCHARvarchar(n)varchar(n)TEXTCHARchar(n)char(n)TEXTNCHARchar(n)nchar(n)TEXTNVARCHARvarchar(n)nvarchar(n)TEXTTEXTtextnvarchar(max)TEXTTEXT_MEDIUMmediumtextnvarchar(max)TEXTDATETIMEdatetimedatetime2TEXTTIMESTAMPtimestampdatetime2TEXTDATEdatedateTEXTTIMEtimetimeTEXTBLOBblobvarbinary(max)BLOBBLOB_MEDIUMmediumblobvarbinary(max)BLOBBLOB_LONGlongblobvarbinary(max)BLOBBLOB_TINYtinyblobvarbinary(255)BLOBBINARYblobbinary(n)BLOBVARBINARYblobvarbinary(n)BLOBPhase 6: Testing
:memory:(no Docker required)SQLite-Specific Considerations
MultiResultSetnot applicableAlternatives Considered
Breaking Change
No
Additional Context
This would make the test suite runnable without Docker/external databases — a significant improvement for CI speed and contributor onboarding.