micoli / elql
Requires
- php: >=8.1
- symfony/expression-language: ^6.0
- symfony/filesystem: ^6.0
- symfony/lock: ^6.0
- symfony/property-access: ^6.0
- symfony/property-info: ^6.0
- symfony/serializer: ^6.0
- symfony/yaml: ^6.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.16
- php-coveralls/php-coveralls: ^0.1.0
- phpdocumentor/reflection-docblock: ^5.3
- phpunit/phpunit: ^10.0
- ramsey/uuid: ^4.7
- symfony/var-dumper: ^6.0
- vimeo/psalm: ^5.9
README
A flat database manager. Each models are read/persisted in a (YAML
|JSON
) file.
That library is based upon symfony/serializer
and symfony/expression-language
components. So basically, every model that can be serialized/deserialized by those components wan be used.
When select
ing, updat
ing, delet
ing records, each constraints are expressed as an expression-language
string.
A record
object is available in the constraint expression and represent the evaluated record.
Installation
This library is installable via Composer:
composer require micoli/elql
Requirements
This library requires PHP 8.0 or later.
Project status
While this library is still under development, it is still in early development status. It follows semver version tagging.
Quick start
Create an instance of Elql manager
Database are per directory. all models are persisted in a separate file.
$database = new Elql( new FilePersister( '/var/lib/database', new MetadataManager(), YamlEncoder::FORMAT, ), );
The persisted records are loaded in memory before each CRUD action if they were not already loaded.
Record in memory addition
Add some record of proper serializable model.
$database->add( new Baz(1, 'a', 'a'), new Baz(2, 'b', 'b'), new Baz(3, 'c', 'c'), new Baz(4, 'd', 'd'), new Foo(1, 'aa', new DateTimeImmutable()), );
Basic crud function are available
Select
$records = $database->find(Baz::class, 'record.id==3');
Update
An updater callback is used to help case/case model updates
$database->update(Baz::class, function (Baz $record) { $record->firstName = $record->firstName . '-updated'; return $record; }, 'record.id==3');
Delete
$database->delete(Baz::class, 'record.id in [1,4]');
Count
print $database->count(Baz::class, 'record.id in [1,4]');
You need to flush the in-memories tables to disk to persist them
$database->persister->flush();
/var/lib/database/Foo.yaml
/var/lib/database/Bar.yaml
Attributes
Table($name)
Instead of using the class-name as filename, you can specify a specific name using that attribute.
#[Table('b_a_z')] class Baz { public function __construct( public readonly int $id, public string $firstName, public string $lastName, ) { } }
N.B.:
if you don't want to use that attribute, you can specify some filenames in the MetadataManager
constructor.
$database = new Elql( new FilePersister( '/var/lib/database', new MetadataManager([ Foo::class=>'foo_table' ]), YamlEncoder::FORMAT, ), );
In that was, when Foo
records will be persisted, the filename will be foo_table.yaml
.
Unique($expression, $indexName)
Before adding a record to a model table, the unique constraints are evaluated to guarantee uniqueness of records.
#[Unique('record.id')] #[Unique('[record.firstName,record.lastName]', 'fullname')] class Baz { public function __construct( public readonly int $id, public string $firstName, public string $lastName, ) { } }
A Micoli\Elql\Exception\NonUniqueException
are triggered in case of a constraint is not respected.