Skip to content

feat(sqlite): Add SQLite database engine support #141

@usernane

Description

@usernane

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions