hranicka/yetorm

This package is abandoned and no longer maintained. The author suggests using the artfocus/jetorm package instead.

Lightweight ORM for Nette\Database

3.14.0 2015-09-15 07:49 UTC

README

Build Status

This package is abandoned and no longer maintained. The author suggests using the artfocus/jetorm package instead.

THIS IS NOT OFFICIAL YetORM LIBRARY. IT'S A MODIFIED FORK.
USE RATHER OFFICIAL ONE:
https://github.com/uestla/YetORM

YetORM

Lightweight ORM built on top of Nette\Database

Quickstart

Consider following database schema:

Database schema

Installation

Setup config.neon like this:

extensions:
	yetorm: YetORM\Extension

yetorm:
	# setup cache IStorage for better performance
	# setup this only on production otherwise Entity doesn't load new Refletion until cache will be deleted!
	storage: cacheStorage # for development, leave this value empty (without "cacheStorage")

Entities

Firstly we'll create entity classes according to the schema above. There are two ways of defining entity properties - via @property[-read] annotation, or simply via getter and setter.

Tag

/**
 * @property-read int $id
 * @property string $name
 *
 * @method int getId()
 * @method string getName()
 *
 * @method Tag setName(string $name)
 */
class Tag extends YetORM\Entity
{
	
}

Author

/**
 * @property-read int $id
 * @property string $name
 * @property string $web
 * @property \DateTime $born
 *
 * @method int getId()
 * @method string getName()
 * @method string getWeb()
 * @method \DateTime getBorn()
 *
 * @method Author setName(string $name)
 * @method Author setWeb(string $web)
 * @method Author setBorn(\DateTime $born)
 */
class Author extends YetORM\Entity
{
	
}

Book

There are some relations at the Book entity - two N:1 Author and M:N Tag relations. Every YetORM\Entity has an instance of YetORM\Row in it, which is a simple wrapper around Nette\Database\Table\ActiveRow. That means that we can access related rows or column values through it.

/**
 * @property-read int $id
 * @property string $title
 * @property string $web
 * @property string $slogan
 * @property-read Author $author
 *
 * @method int getId()
 * @method string getTitle()
 * @method string getWeb()
 * @method string getSlogan()
 *
 * @method Book setTitle(string $title)
 * @method Book setWeb(string $web)
 * @method Book setSlogan(string $slogan)
 */
class Book extends YetORM\Entity
{

	public function getAuthor()
	{
		return $this->getOne(Author::getClassName(), 'author', 'author_id', TRUE);
	}

	public function getMaintainer()
	{
		return $this->getOne(Author::getClassName(), 'author', 'maintainer_id', TRUE);
	}

	public function getTags()
	{
		return $this->getMany(Tag::getClassName(), 'book_tag', 'tag');
	}
	
}

With $row->ref($table, $column) we're accessing related table row in table $table through column $column - pretty simple.

The M:N relation is realized with YetORM\EntityCollection instance - which is a lazy collection of entities. In this case it iterates throw all related rows from book_tag table (first argument), creates instances of Tag (second argument) and on every related book_tag table row it accesses related tag table row (third argument), which then passes to the constructor of Tag entity :-)

This sounds crazy, but it's actually simple to get used to.

With this knowledge we can now simply add some helpful methods to Author entity:

// class Author
public function getBooksWritten()
{
	return $this->getMany(Book::getClassName(), 'book', 'book', 'author_id');
}

public function getBooksMaintained()
{
	return $this->getMany(Book::getClassName(), 'book', 'book', 'maintainer_id');
}

Repositories

Every repository has to have table and entity class name defined - either via @table and @entity annotation, or via protected $table and $entity class property.

/**
 * @table book
 * @entity Book
 */
class BookRepository extends YetORM\Repository
{
	
}

Persisting

To persist changes we make simply call $repository->persist($entity).

$book->setWeb('http://example.com');
$books->persist($book);

And that's it!

Additional notes

  • No identity map
  • Query efficiency - the collections (resp. YetORM\Row) use the power of Nette\Database efficiency
  • Collection operations - collections can be sorted via $coll->orderBy($column, $dir) and limitted via $coll->limit($limit, $offset)

More

For more examples please see the tests.