marcojetson / freckle
A minimalistic ORM built on top of Doctrine DBAL and heavily inspired by Spot2
Requires
- php: >=5.6.0
- doctrine/dbal: 2.5.*
Requires (Dev)
- phpunit/phpunit: 5.*
This package is not auto-updated.
Last update: 2024-11-09 20:33:42 UTC
README
Freckle is an Object-Relational-Mapper built on top of Doctrine DBAL.
Freckle is inspired by Spot2.
Table of contents
Installation
Install with Composer
composer require marcojetson/freckle
Configuration
You can get a connection through the Freckle\Manager
class.
$connection = Freckle\Manager::getConnection([ 'driver' => 'pdo_sqlite', ]);
Entities
Entities must extend Freckle\Entity
and implement the definition
method.
/** * @method int getId() * * @method string getTitle() * @method setTitle(string $title) * * @method string getBody() * @method setBody(string $body) */ class Post extends Freckle\Entity { public static function definition() { return [ 'table' => 'post', 'fields' => [ 'id' => ['integer', 'sequence' => true, 'primary' => true], 'title' => 'string', 'body' => 'string', ], ]; } }
Definition
Defining an entity requires a table name and its fields. Fields are defined by an array with mandatory positional parameters and optional named parameters.
[ string $type, mixed default=null, // default value, callables supported! bool primary=false, bool require=false, bool|string sequence=false, // specify sequence name if required by database ]
Generation
Freckle is able to generate entities for you. Use Freckle\Connection::import()
to automatically generate mappings for your tables.
foreach ($connection->generate() as $mapping) { file_put_contents($mapping->entityClass() . '.php', (string)$mapping); }
Data manipulation
Interact with your entities using a mapper. You can get a mapper using the previously created connection.
$postMapper = $connection->mapper(Post::class);
Insert
// create entity and insert $post1 = $postMapper->entity([ 'title' => 'Hello World', 'body' => 'My very first post', ]); $postMapper->insert($entity); // ...or do it in a single step $post2 = $postMapper->create([ 'title' => 'Lorem Ipsum', 'body' => 'My second post', ]);
Update
$post2->setTitle('Lorem ipsum dolor'); $postMapper->update($post2);
Not sure if new entity or not? Then use Freckle\Mapper::save()
.
Delete
$postMapper->delete($post2);
Retrieval
Use Freckle\Mapper::find()
to initialize a query
$query = $postMapper->find(['title like' => '% post']); // queries are lazy, keep attaching parts till ready $query->not('id', 1)->gte('score', 10); foreach ($query as $post) { echo $post->getName(), PHP_EOL; } // or retrieve a single result $postMapper->find(['id' => 1])->first();
Where operators
Where operators can be appended to field when using Freckle\Query::where()
or being executed as query methods.
- eq, equals, =
- not, !=
- gt, greaterThan, >
- gte, greaterThanOrEquals, >=
- lt, lessThan, <
- lte, lessThanOrEquals, <=
- like
Custom operators
Add your own operators extending Freckle\Operator
.
class JsonExists extends Operator { public function __invoke(Query $query, $column, $value = null) { return 'jsonb_exists(' . $column . ', ' . $query->parameter($value) . ')'; } } Freckle\Operator::add('json_exists', JsonExists::class); $postMapper->find([ 'properties json_exists' => 'author', ]); // or use it as a method $postMapper->find()->json_exists('properties', 'author');
Relations
Related entity retrieval is supported.
/** * @method int getId() * * @method string getBody() * @method setBody(string $body) * * @method int getPostId() * @method setPostId(int $postId) * * @method Post getPost() */ class Comment extends Freckle\Entity { public static function definition() { return [ 'table' => 'comment', 'fields' => [ 'id' => ['integer', 'sequence' => true, 'primary' => true], 'body' => 'string', 'post_id' => 'integer', ], 'relations' => [ 'post' => ['one', Post::class, ['id' => 'this.id']], }, ], ]; } }
Definition
In the same fashion of fields, defining a relation consist in an array with mandatory positional parameters and optional named parameters.
[ string $type, string $entityClass, array $conditions, string through=null, // "table.column" for many-to-many relations string field='id', // related entity primary column ]