Skip to content

Commit

Permalink
README.md: usage of interfaces is recommended
Browse files Browse the repository at this point in the history
  • Loading branch information
fabik committed Jan 11, 2013
1 parent 4c78e16 commit 7e78088
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 18 deletions.
40 changes: 39 additions & 1 deletion Database/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

namespace Fabik\Database;

use Nette\InvalidStateException,
use Nette\InvalidArgumentException,
Nette\InvalidStateException,
Nette\Object;


Expand Down Expand Up @@ -157,6 +158,43 @@ public function createOrUpdate($uniqueKeys, $values = array())



/**
* Saves the given a row to the database.
* @param mixed[]|\Traversable
* @return \Nette\Database\Table\ActiveRow
* @throws \Nette\InvalidArgumentException
*/
public function save($row)
{
if ($row instanceof \Nette\Database\Table\ActiveRow && $row->getTable()->getConnection() === $this->manager->getConnection()) {
return $row->update();

} elseif ($row instanceof \Traversable) {
$data = iterator_to_array($row);

} elseif (is_array($row)) {
$data = $row;

} else {
throw new InvalidArgumentException('Argument must be an array or Traversable descendant.');
}

$selection = $this->getTable();

if (isset($data[$selection->getPrimary()])) {
$row = $selection->find($data[$selection->getPrimary()]);
foreach ($data as $key => $val) {
$row->$key = $val;
}
return $row->update();

} else {
return $selection->insert($data);
}
}



/**
* Inserts a row to the database.
* @param mixed[]
Expand Down
215 changes: 198 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,33 +57,151 @@ Get the source code using [Composer](http://getcomposer.org/) (add `"fabik/datab
database:
rowFactory:
classes:
articles: Blog\Article
users: Blog\User
articles: App\Model\Database\Article
users: App\Model\Database\User

services:
articles: Blog\Articles
users: Blog\Users
articleDao: App\Model\Database\Articles
userDao: App\Model\Database\Users
```

4. Create classes for rows (e.g. `Article`, `User`) and tables (e.g. `Articles`, `Users`):
4. Create interfaces for entities and data access objects.

```php
<?php
namespace App\Model;

namespace Blog;

use Fabik\Database\ActiveRow,
Fabik\Database\Table;

/**
* @property int $id
* @property string $title
* @property string $content
* @property IUser $author
*/
interface IArticle
{
}



/**
* @property int $id
* @property string $username
* @property string $password
* @property string $email
* @property string $firstname
* @property string $surname
* @property string $realname
* @property-read IArticle[]|\Traversable $authoredArticles
*/
interface IUser
{
}



interface IArticleDao
{
/**
* @return IArticle[]|\Traversable
*/
function findAll();

/**
* @param string
* @return IArticle[]|\Traversable
*/
function search($query);

/**
* @param int
* @return IArticle|NULL
*/
function find($id);

/**
* @param array
* @return IArticle
*/
function create($values);

/**
* @param IArticle|array
* @return IArticle
*/
function save($article);
}



interface IUserDao
{
/**
* @return IUser[]|\Traversable
*/
function findAll();

/**
* @param int
* @return IUser|NULL
*/
function find($id);

/**
* @param string
* @return IUser|NULL
*/
function findOneByEmail($email);

/**
* @param array
* @return IUser
*/
function create($values);

/**
* @param IUser|array
* @return IUser
*/
function save($user);
}
```

5. Create classes for rows and tables that implement these interfaces.

```php
namespace App\Model\Database;

use App\Model\IArticle,
App\Model\IArticleDao,
App\Model\IUser,
App\Model\IUserDao,
Fabik\Database\ActiveRow,
Fabik\Database\Table,
Nette\Database\SqlLiteral;


class Article extends ActiveRow

class Article extends ActiveRow implements IArticle
{
/** @return User */
public function getAuthor()
{
return $this->ref('users', 'author_id');
}



/** @param \App\Model\IUser */
public function setAuthor(IUser $user)
{
$this->author_id = $user->id;
}
}



class User extends ActiveRow
class User extends ActiveRow implements IUser
{
/** @return string */
public function getRealname()
Expand All @@ -98,29 +216,92 @@ Get the source code using [Composer](http://getcomposer.org/) (add `"fabik/datab
{
list($this->firstname, $this->surname) = explode(' ', $realname);
}



/** @return Article[]|\Traversable */
public function getAuthoredArticles()
{
return $this->related('articles', 'author_id');
}
}



class Articles extends Table
class Articles extends Table implements IArticleDao
{
protected $name = 'articles';



/**
* @param string
* @return IArticle[]|\Traversable
*/
public function search($query)
{
$pattern = $this->manager->getConnection()->getSupplementalDriver()->formatLike($query, 0);
return $this->findBy('title LIKE ?', new SqlLiteral($pattern));
}
}



class Users extends Table
class Users extends Table implements IUserDao
{
protected $name = 'users';



/**
* @param string
* @return IUser|NULL
*/
public function findOneByEmail($email)
{
return $this->findOneBy('email', $email);
}
}
```

5. Now you can use it as follows:
6. Now you can use it the following way:

```php
$articles = $container->articles;
namespace App\FrontModule;

use App\Model\IArticleDao;



foreach ($articles->findAll() as $article) {
echo "$article->title was written by $article->author->realname\n";
class ArticlesPresenter extends BasePresenter
{
/** @var \App\Model\IArticleDao */
protected $articleDao;



public function inject(IArticleDao $articleDao)
{
$this->articleDao = $articleDao;
}



public function renderDefault()
{
$this->template->articles = $this->articleDao->findAll();
}
}
```

```
{#content}

{foreach $articles as $article}
<h1>{$article->title}</h1>
<em>by {$article->author->realname}</em>
{!$article->content}
{/foreach}
```

It is not recommended using the row and table classes directly, so that the entire application does not depend on the implementation of model. Thus it is anytime possible to replace the storage with another one (e.g. a web service or a different database library).

0 comments on commit 7e78088

Please sign in to comment.