Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Definition.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,27 @@ public function withMany(Definition $definition, string $name, string $foreignCo
return $this;
}

/**
* Adds a one-to-one relationship through a joined table.
*
* @param Definition $definition
* @param string $name
* @param string $foreignColumn
* @param string $localColumn
* @param string $joinTable
* @param string $joinForeignColumn
* @param string $joinLocalColumn
* @return Definition
*/
public function withOneByJoin(Definition $definition, string $name, string $foreignColumn, string $localColumn, string $joinTable, string $joinForeignColumn, string $joinLocalColumn)
{
$property = new Property($name, false, $definition, $localColumn, $foreignColumn);
$property->join($joinTable, $joinLocalColumn, $joinForeignColumn);

$this->properties[] = $property;
return $this;
}

/**
* Adds a one-to-many relationship through a joined table.
*
Expand Down
11 changes: 11 additions & 0 deletions tests/Fixtures.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ CREATE TABLE discounts (id INTEGER PRIMARY KEY, order_id INTEGER, description TE
DROP TABLE IF EXISTS orders_fulfillments;
CREATE TABLE orders_fulfillments (order_id INTEGER, employee_id INTEGER);

DROP TABLE IF EXISTS employees;
CREATE TABLE employees (id INTEGER PRIMARY KEY, name TEXT);

-- Seed database
INSERT INTO customers (id, name) VALUES
(1, 'John Doe'),
Expand All @@ -34,3 +37,11 @@ INSERT INTO items (id, order_id, description, amount) VALUES

INSERT INTO discounts (id, order_id, description, amount) VALUES
(1, 2, '$10', 10);

INSERT INTO employees (id, name) VALUES
(1, 'Alice'),
(2, 'Bob');

INSERT INTO orders_fulfillments (order_id, employee_id) VALUES
(1, 1),
(2, 2);
79 changes: 79 additions & 0 deletions tests/MappingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,51 @@ public function testFindOneWithDirectAndSecondaryLeft()
$this->assertEquals(400, $customer['orders'][0]['items'][1]['amount']);
}

public function testFindAllWithOneByJoin()
{
$orders = $this->getWithOneByJoinMapping()->findAll();

$this->assertCount(3, $orders);

$this->assertEquals('Alice', $orders[0]['employee']['name']);
$this->assertEquals('Bob', $orders[1]['employee']['name']);
$this->assertNull($orders[2]['employee']);
}

public function testFindOneWithOneByJoin()
{
$order = $this->getWithOneByJoinMapping()->eq('id', 2)->findOne();

$this->assertNotNull($order);
$this->assertEquals(2, $order['id']);
$this->assertEquals('Bob', $order['employee']['name']);
}

public function testFindAllWithManyByJoin()
{
$employees = $this->getWithManyByJoinMapping()->findAll();

$this->assertCount(2, $employees);

$this->assertEquals('Alice', $employees[0]['name']);
$this->assertCount(1, $employees[0]['orders']);
$this->assertEquals('2018-01-01', $employees[0]['orders'][0]['date_created']);

$this->assertEquals('Bob', $employees[1]['name']);
$this->assertCount(1, $employees[1]['orders']);
$this->assertEquals('2018-01-02', $employees[1]['orders'][0]['date_created']);
}

public function testFindOneWithManyByJoin()
{
$employee = $this->getWithManyByJoinMapping()->eq('id', 1)->findOne();

$this->assertNotNull($employee);
$this->assertEquals('Alice', $employee['name']);
$this->assertCount(1, $employee['orders']);
$this->assertEquals('2018-01-01', $employee['orders'][0]['date_created']);
}

/**
* Returns a new mapping for testing.
*
Expand Down Expand Up @@ -599,6 +644,40 @@ public function getMapping()
]);
}

/**
* Returns a mapping using withOneByJoin for testing.
*
* @return Mapping
*/
public function getWithOneByJoinMapping()
{
$employee = (new Definition('employees'))
->withColumns('id', 'name');

$order = (new Definition('orders'))
->withColumns('id', 'date_created')
->withOneByJoin($employee, 'employee', 'id', 'id', 'orders_fulfillments', 'employee_id', 'order_id');

return new Mapping($this->db, $order);
}

/**
* Returns a mapping using withManyByJoin for testing.
*
* @return Mapping
*/
public function getWithManyByJoinMapping()
{
$order = (new Definition('orders'))
->withColumns('id', 'date_created');

$employee = (new Definition('employees'))
->withColumns('id', 'name')
->withManyByJoin($order, 'orders', 'id', 'id', 'orders_fulfillments', 'order_id', 'employee_id');

return new Mapping($this->db, $employee);
}

/**
* Returns a new mapping for testing.
*
Expand Down