Skip to content

Commit

Permalink
Merge pull request #22 from roxblnfk/feature/order-by-in-relations
Browse files Browse the repository at this point in the history
Add supporting of orderBy option in relations
  • Loading branch information
wolfy-j committed Mar 31, 2021
2 parents ed8df4d + 18d525f commit 9de28bb
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 112 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Cycle ORM Schema Builder",
"require": {
"php": ">=7.2",
"cycle/orm": "^1.0",
"cycle/orm": "^1.4",
"yiisoft/friendly-exception": "^1.0"
},
"require-dev": {
Expand Down
1 change: 1 addition & 0 deletions src/Generator/GenerateRelations.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ final class GenerateRelations implements GeneratorInterface
'throughOuterKey' => Relation::THROUGH_OUTER_KEY,
'throughWhere' => Relation::THROUGH_WHERE,
'where' => Relation::WHERE,
'orderBy' => Relation::ORDER_BY,
'fkCreate' => RelationSchema::FK_CREATE,
'fkAction' => RelationSchema::FK_ACTION,
'indexCreate' => RelationSchema::INDEX_CREATE,
Expand Down
3 changes: 3 additions & 0 deletions src/Relation/HasMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ final class HasMany extends RelationSchema implements InversableInterface
// custom where condition
Relation::WHERE => [],

// custom orderBy rules
Relation::ORDER_BY => [],

// link to parent entity primary key by default
Relation::INNER_KEY => '{source:primaryKey}',

Expand Down
3 changes: 3 additions & 0 deletions src/Relation/ManyToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ final class ManyToMany extends RelationSchema implements InversableInterface
// custom where condition
Relation::WHERE => [],

// custom orderBy rules
Relation::ORDER_BY => [],

// inner key of parent record will be used to fill "THROUGH_INNER_KEY" in pivot table
Relation::INNER_KEY => '{source:primaryKey}',

Expand Down
12 changes: 5 additions & 7 deletions tests/Schema/ColumnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Cycle\Schema\Tests;

use Cycle\Schema\Definition\Field;
use Cycle\Schema\Exception\ColumnException;
use Cycle\Schema\Table\Column;
use Spiral\Database\Schema\AbstractTable;

Expand All @@ -32,15 +33,14 @@ public function testColumn(): void
$this->assertFalse($column->isNullable());
}

/**
* @expectedException \Cycle\Schema\Exception\ColumnException
*/
public function testInvalidDeclaration(): void
{
$field = new Field();
$field->setType('7');
$field->setColumn('name');

$this->expectException(ColumnException::class);

Column::parse($field);
}

Expand All @@ -60,18 +60,16 @@ public function testColumnNullableStrict(): void
$this->assertTrue($column->isNullable());
}

/**
* @expectedException \Cycle\Schema\Exception\ColumnException
*/
public function testNoDefaultValue(): void
{
$field = new Field();
$field->setType('string');
$field->setColumn('name');

$column = Column::parse($field);

$this->assertFalse($column->hasDefault());
$this->expectException(ColumnException::class);

$column->getDefault();
}

Expand Down
10 changes: 10 additions & 0 deletions tests/Schema/Driver/MySQL/GenerateRelationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Cycle\Schema\Tests\Driver\MySQL;

class GenerateRelationsTest extends \Cycle\Schema\Tests\Generator\GenerateRelationsTest
{
public const DRIVER = 'mysql';
}
10 changes: 10 additions & 0 deletions tests/Schema/Driver/Postgres/GenerateRelationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Cycle\Schema\Tests\Driver\Postgres;

class GenerateRelationsTest extends \Cycle\Schema\Tests\Generator\GenerateRelationsTest
{
public const DRIVER = 'postgres';
}
10 changes: 10 additions & 0 deletions tests/Schema/Driver/SQLServer/GenerateRelationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Cycle\Schema\Tests\Driver\SQLServer;

class GenerateRelationsTest extends \Cycle\Schema\Tests\Generator\GenerateRelationsTest
{
public const DRIVER = 'sqlserver';
}
10 changes: 10 additions & 0 deletions tests/Schema/Driver/SQLite/GenerateRelationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Cycle\Schema\Tests\Driver\SQLite;

class GenerateRelationsTest extends \Cycle\Schema\Tests\Generator\GenerateRelationsTest
{
public const DRIVER = 'sqlite';
}
33 changes: 14 additions & 19 deletions tests/Schema/EntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Cycle\Schema\Definition\Entity;
use Cycle\Schema\Definition\Field;
use Cycle\Schema\Definition\Relation;
use Cycle\Schema\Exception\RelationException;
use PHPUnit\Framework\TestCase;

class EntityTest extends TestCase
Expand Down Expand Up @@ -48,16 +49,14 @@ public function testFieldOptions(): void
$this->assertSame('value', $e->getFields()->get('id')->getOptions()->get('name'));
}

/**
* @expectedException \Cycle\Schema\Exception\OptionException
*/
public function testGetUndefinedOption(): void
{
$e = new Entity();
$e->setRole('role');

$e->getFields()->set('id', new Field());

$this->expectException(\Cycle\Schema\Exception\OptionException::class);

$e->getFields()->get('id')->getOptions()->get('name');
}

Expand All @@ -72,54 +71,50 @@ public function testSetRelation(): void
$this->assertTrue($e->getRelations()->has('test'));
}

/**
* @expectedException \Cycle\Schema\Exception\RelationException
*/
public function testGetUndefined(): void
{
$e = new Entity();
$e->setRole('role');
$this->assertSame('role', $e->getRole());

$this->expectException(RelationException::class);

$e->getRelations()->get('test');
}

/**
* @expectedException \Cycle\Schema\Exception\RelationException
*/
public function testSetRelationDouble(): void
{
$e = new Entity();
$e->setRole('role');
$this->assertSame('role', $e->getRole());

$e->getRelations()->set('test', new Relation());

$this->expectException(RelationException::class);

$e->getRelations()->set('test', new Relation());
}

/**
* @expectedException \Cycle\Schema\Exception\RelationException
*/
public function testRelationNoTarget(): void
{
$e = new Entity();
$e->setRole('role');
$this->assertSame('role', $e->getRole());

$e->getRelations()->set('test', new Relation());

$this->expectException(RelationException::class);

$e->getRelations()->get('test')->getTarget();
}

/**
* @expectedException \Cycle\Schema\Exception\RelationException
*/
public function testRelationNoType(): void
{
$e = new Entity();
$e->setRole('role');
$this->assertSame('role', $e->getRole());

$e->getRelations()->set('test', new Relation());

$this->expectException(RelationException::class);

$e->getRelations()->get('test')->getType();
}

Expand Down
28 changes: 13 additions & 15 deletions tests/Schema/FieldsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@

use Cycle\Schema\Definition\Field;
use Cycle\Schema\Definition\Map\FieldMap;
use Cycle\Schema\Exception\FieldException;
use PHPUnit\Framework\TestCase;

class FieldsTest extends TestCase
{
/**
* @expectedException \Cycle\Schema\Exception\FieldException
*/
public function testNoField(): void
{
$m = new FieldMap();

$this->expectException(FieldException::class);

$m->get('id');
}

Expand All @@ -38,36 +39,33 @@ public function testSetGet(): void
$this->assertSame(['id' => $f], iterator_to_array($m->getIterator()));
}

/**
* @expectedException \Cycle\Schema\Exception\FieldException
*/
public function testSetTwice(): void
{
$m = new FieldMap();

$m->set('id', $f = new Field());

$this->expectException(FieldException::class);

$m->set('id', $f = new Field());
}

/**
* @expectedException \Cycle\Schema\Exception\FieldException
*/
public function testNoType(): void
{
$m = new FieldMap();

$m->set('id', $f = new Field());

$this->expectException(FieldException::class);

$m->get('id')->getType();
}

/**
* @expectedException \Cycle\Schema\Exception\FieldException
*/
public function testNoColumn(): void
{
$m = new FieldMap();

$m->set('id', $f = new Field());

$this->expectException(FieldException::class);

$m->get('id')->getColumn();
}
}
84 changes: 84 additions & 0 deletions tests/Schema/Generator/GenerateRelationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace Cycle\Schema\Tests\Generator;

use Cycle\ORM\Relation;
use Cycle\ORM\Schema;
use Cycle\Schema\Compiler;
use Cycle\Schema\Definition\Relation as RelationDefinition;
use Cycle\Schema\Generator\GenerateRelations;
use Cycle\Schema\Generator\RenderTables;
use Cycle\Schema\Registry;
use Cycle\Schema\Tests\BaseTest;
use Cycle\Schema\Tests\Fixtures\Plain;
use Cycle\Schema\Tests\Fixtures\Post;
use Cycle\Schema\Tests\Fixtures\Tag;
use Cycle\Schema\Tests\Fixtures\TagContext;
use Cycle\Schema\Tests\Fixtures\User;

abstract class GenerateRelationsTest extends BaseTest
{
public function relationOptionsDataProvider(): array
{
return [
'default orderBy' => ['orderBy', [], Relation::ORDER_BY],
'custom orderBy' => ['orderBy', ['id' => 'DESC'], Relation::ORDER_BY],
'default where' => ['where', [], Relation::WHERE],
'custom where' => ['where', ['id' => '1'], Relation::WHERE],
];
}

/**
* @dataProvider relationOptionsDataProvider
*/
public function testHasManyToManyRelationOptions(string $optionKey, $optionValue, int $relationKey): void
{
$post = Post::define();
$tag = Tag::define();
$tagContext = TagContext::define();

$post->getRelations()->remove('author');

$post->getRelations()->set('tags', new RelationDefinition());
$post->getRelations()->get('tags')
->setType('manyToMany')
->setTarget('tag')
->getOptions()
->set('though', 'tagContext')
->set($optionKey, $optionValue);

$r = new Registry($this->dbal);
$r->register($post)->linkTable($post, 'default', 'post');
$r->register($tag)->linkTable($tag, 'default', 'tag');
$r->register($tagContext)->linkTable($tagContext, 'default', 'tag_context');

$c = new Compiler();
$schema = $c->compile($r, [new RenderTables(), new GenerateRelations()]);

$this->assertSame($optionValue, $schema['post'][Schema::RELATIONS]['tags'][Relation::SCHEMA][$relationKey]);
}

/**
* @dataProvider relationOptionsDataProvider
*/
public function testHasManyRelationOptions(string $optionKey, $optionValue, int $relationKey): void
{
$e = Plain::define();
$u = User::define();

$relation = $u->getRelations()->get('plain');
$relation->setType('hasMany');
$relation->getOptions()->set($optionKey, $optionValue);

$r = new Registry($this->dbal);
$r->register($e)->linkTable($e, 'default', 'plain');
$r->register($u)->linkTable($u, 'default', 'user');

$c = new Compiler();
$schema = $c->compile($r, [new RenderTables(), new GenerateRelations()]);

$this->assertSame($optionValue, $schema['user'][Schema::RELATIONS]['plain'][Relation::SCHEMA][$relationKey]);
}
}

0 comments on commit 9de28bb

Please sign in to comment.