etel / sqlite-file-storage
File storage backed by a single SQLite database with streaming, compression and encryption support.
Requires (Dev)
- ext-sodium: *
- etel/phpunit-double: ^0.1.0
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^13.0
Suggests
- ext-brotli: Enables Brotli compression
- ext-fileinfo: Enables automatic MIME type detection
- ext-sodium: Required for XChaCha20-Poly1305 encryption
README
Etel SQLite file storage
File storage backed by a single SQLite database, with S3-like semantics: one database file is one storage node (bucket), objects are identified by flat path-like keys. Content is processed strictly in chunks (never fully in memory), with optional streaming compression (zlib family, brotli) and authenticated streaming encryption (libsodium secretstream, XChaCha20-Poly1305). Identical content is deduplicated via refcounting.
Quick start
use Etel\SqliteFileStorage\{ArrayKeyProvider, Compression, Encryption, PutOptions, StorageFactory, StorageOptions}; $storage = new StorageFactory()->open('/var/data/bucket-main.db', new StorageOptions( defaultCompression: Compression::Zlib, defaultEncryption: Encryption::XChaCha20Poly1305, keyProvider: new ArrayKeyProvider(['key-2026' => $rawKey32bytes], 'key-2026') )); $info = $storage->putObject('invoices/2026/0001.pdf', fopen('/tmp/upload.pdf', 'rb')); $object = $storage->getObject('invoices/2026/0001.pdf'); $stream = $object->getContentStream(); // decrypted + decompressed, lazy, chunked foreach ($storage->listObjects(prefix: 'invoices/2026/') as $item) { echo $item->key, ' ', $item->size, "\n"; }
Requirements
PHP >= 8.4 with ext-sqlite3, ext-zlib.
Optional: ext-sodium (encryption), ext-brotli (brotli compression), ext-fileinfo (MIME detection).
Development
Docker is the reference environment: PHP 8.4 (the minimum supported version) with all optional extensions, including ext-brotli, so the full test matrix runs there.
docker compose build docker compose run --rm php composer install docker compose run --rm php vendor/bin/phpunit docker compose run --rm php vendor/bin/phpunit --coverage-html coverage docker compose run --rm php vendor/bin/phpstan analyse --memory-limit=1G docker compose run --rm php vendor/bin/php-cs-fixer fix
Tests that need an extension missing on the host (e.g. brotli) are skipped automatically.