Skip to content

Working with Repository

Yo-An Lin edited this page Apr 24, 2017 · 12 revisions

Creating Repository instance

BaseRepo::masterRepo()

A repository consists of read connection / write connection and the related table information.

Each schema has its own repo class, which is generated by the schema generator. And this is for getting pre-built constants like SQL statements, table name constants, column names faster.

To create a Repository of Book schema, simply call masterRepo static method on Book class:

$repo = Book::masterRepo();

The above code creates an instance of BookRepo with connections to master database.

BaseRepo::repo(PDO|string $write, PDO|string $read) : BaseRepo

To customize the repository connection, like separating read/write connections, you can simply pass Maghead\Connection instances:

$repo = Book::repo($write, $read);

If $read is omit, then the read connection will be same as $write:

$repo = Book::repo($write);

You can also create the repository instance with the data source IDs, e.g.,

$repo = Book::repo('node1', 'node2');

Generally, if you don't need to customize the connections, calling ::masterRepo will be faster than ::repo since it doesn't check the parameter types.

Creating records

BaseRepo::create(array $args) : Maghead\Runtime\Result

To create a record, simply call ::create.

    $ret = Book::masterRepo()->create([
        'title' => 'Programming PHP',
    ]);

This method returns Maghead\Runtime\Result object.

Moving records between Repositories

BaseRepo::move(BaseRepo $target) : Maghead\Runtime\Result

Maghead Repository provides move method to let you move a record from repo A to repo B.

$order = Order::masterRepo()->create([ 'amount' => 100 ]);
$repo1 = Order::repo('shard1');
$ret = $order->move($repo1);

Please note that BaseRepo::move(BaseRepo $target) method removes the local primary key (auto incremental integer primary key) to prevent duplicated primary key issues.

BaseRepo::import(BaseRepo $target) : Maghead\Runtime\Result

To keep the local primary key, use ::import instead:

$order = Order::masterRepo()->create([ 'amount' => 100 ]);
$repo1 = Order::repo('shard1');
$ret = $order->import($repo1);

Finding records

BaseRepo::findWith(array $conditions)

Find the record base on the condition array.

BaseRepo::findByPrimaryKey($key)

Find the record by the given primary key.

$book = Book::masterRepo()->findByPrimaryKey(23);

BaseRepo::findByKeys(array $conditions, array $keys)

Find the record base on the condition array, the condition array will be filtered by the keys. This method calls ::findWith with the filtered condition array.

$book = Book::masterRepo()->findByKeys([
    'author' => 'John',
    'other_info' => '....',
], ['author']);

BaseRepo::load($condition)

Find the record base on either primary key or a condition array.

Note: this method is slower than findWith or findByPrimaryKey if you know what will be used to find the record.

BaseRepo::loadForUpdate($condition)

Find the record base on either primary key or a condition array.

This method executes SQL query with SELECT ... FOR UPDATE syntax to provide the row-level lock for the selected row.

Note: this method is only supported for MySQL.

Creating query object from Repository

After you created an instance of Repository for one schema, you can create query objects from it to customize your query rather than the simple CRUD operation for just one record object.

Currently Maghead supports 3 basic query factory methods:

  1. BaseRepo::select($sel) : SelectQuery
  2. BaseRepo::update($data) : UpdateQuery
  3. BaseRepo::delete() : DeleteQuery

Using SelectQuery

To create a simple select query and then query the collection from the db:

$books = Book::masterRepo()->select('*')->fetch(); // Returns BookCollection object.

$cnt = count($books); // BookCollection implements Countable interface.
foreach ($books as $book) {
    // do something with $book
}

To create a select query with complex conditions:

$query = Book::masterRepo()->select('*');
$query->where()
    ->equal('member_id', $memberId)
    ->in('status', [ VERIFIED, VIP ])
    ;
$query->orderBy('created_at', 'DESC');
$query->limit(10);
$books = $query->fetch();

To see more examples, please visit https://github.com/c9s/SQLBuilder for more details.

Using UpdateQuery

$query = Book::masterRepo()->update([
    'title' => 'Updated'
])
$query->where()->between('created_at', $from, $to)
$query->execute();

Using DeleteQuery

$q = Book::masterRepo()->delete();
$ret = $q->where()
        ->equal('title', 'Book 1')
        ->execute();

DeleteQuery implements Maghead\Query\Executable and therefore you can call execute method.

Extending Repository

Managing connections

To get the read connection inside the repository, simply use the read property to execute the query:

class BookRepo extends BookBaseRepo {

    public function queryOutdatedBooks()
    {
        return $this->read->query('...');
    }
}

To get the write connection inside the repository, simply use the write property to execute the query:

class BookRepo extends BookBaseRepo {

    public function increaseReadCount($bookId)
    {
        $stm = $this->write->prepare('...');
        $stm->execute(...);
    }
}

Utility Methods

(coming soon)

Clone this wiki locally