Skip to content

Commit

Permalink
delete-insert with unique key
Browse files Browse the repository at this point in the history
  • Loading branch information
gam6itko committed Jan 29, 2024
1 parent 589efc2 commit 585bf62
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 36 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ $ ./vendor/bin/phpunit
To run quick test suite:

```bash
$ ./vendor/bin/phpunit tests/ORM/Driver/SQLite
$ ./vendor/bin/phpunit tests/ORM/Functional/Driver/SQLite
```

## Help Needed In
Expand Down
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
convertWarningsToExceptions="true"
convertDeprecationsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
stopOnError="true"
stopOnFailure="false"
stopOnError="false"
>
<coverage>
<include>
Expand Down
125 changes: 108 additions & 17 deletions tests/ORM/Functional/Driver/Common/Integration/Issue380/CaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4;
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380;

use Cycle\Database\Exception\StatementException\ConstrainException;
use Cycle\ORM\EntityManager;
use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\IntegrationTestTrait;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;
use Cycle\ORM\Tests\Traits\TableTrait;

abstract class CaseTest extends BaseTest
Expand All @@ -22,10 +23,10 @@ public function setUp(): void
$this->makeTables();
$this->fillData();

$this->loadSchema(__DIR__.'/schema.php');
$this->loadSchema(__DIR__ . '/schema.php');
}

public function testOnce(): void
public function testInsertOnce(): void
{
/** @var User $user */
$user = $this->orm->getRepository(User::class)->findOne(['id' => 1]);
Expand All @@ -35,14 +36,14 @@ public function testOnce(): void

$i = 0;

$em->persist(new User\Alias($user, (string) ++$i));
$em->persist(new User\Alias($user, (string) ++$i));
$em->persist(new User\Alias($user, (string)++$i));
$em->persist(new User\Alias($user, (string)++$i));

$em->persist(new User\Email($user, (string) ++$i));
$em->persist(new User\Email($user, (string) ++$i));
$em->persist(new User\Email($user, (string)++$i));
$em->persist(new User\Email($user, (string)++$i));

$em->persist(new User\Phone($user, (string) ++$i));
$em->persist(new User\Phone($user, (string) ++$i));
$em->persist(new User\Phone($user, (string)++$i));
$em->persist(new User\Phone($user, (string)++$i));

$em->run();

Expand Down Expand Up @@ -72,7 +73,7 @@ public function testOnce(): void
/**
* @dataProvider dataMatrix
*/
public function testMatrix(int $cnt1, int $cnt2, int $cnt3): void
public function testInsertMatrix(int $cnt1, int $cnt2, int $cnt3): void
{
/** @var User $user */
$user = $this->orm->getRepository(User::class)->findOne(['id' => 1]);
Expand All @@ -84,17 +85,17 @@ public function testMatrix(int $cnt1, int $cnt2, int $cnt3): void

$expected = [];
for ($id = 1; $id <= $cnt1; $id++) {
$em->persist(new User\Alias($user, $v = (string) ++$i));
$em->persist(new User\Alias($user, $v = (string)++$i));
$expected['alias'][] = ['id' => $id, 'value' => $v];
}

for ($id = 1; $id <= $cnt2; $id++) {
$em->persist(new User\Email($user, $v = (string) ++$i));
$em->persist(new User\Email($user, $v = (string)++$i));
$expected['email'][] = ['id' => $id, 'value' => $v];
}

for ($id = 1; $id <= $cnt3; $id++) {
$em->persist(new User\Phone($user, $v = (string) ++$i));
$em->persist(new User\Phone($user, $v = (string)++$i));
$expected['phone'][] = ['id' => $id, 'value' => $v];
}
$em->run();
Expand All @@ -116,13 +117,100 @@ public function dataMatrix(): iterable
yield [1, 7, 4];
}

public function testFailOnInsertUniqueDuplicate(): void
{
self::expectException(ConstrainException::class);

/** @var User $user */
$user = $this->orm->getRepository(User::class)->findOne(['id' => 1]);

// insert unique
$em = (new EntityManager($this->orm));
$em->persist($user);
$em
->persist(new User\Alias($user, '1'))
->persist(new User\Alias($user, '1'))
->run();
}

public function testDeleteAndInsertFainOnDuplicateUniqueKey(): void
{
/** @var User $user */
$user = $this->orm->getRepository(User::class)->findOne(['id' => 1]);

// insert unique
$em = (new EntityManager($this->orm));
$em->persist($user);
$em
->persist($a0 = new User\Alias($user, '1'))
->persist($a1 = new User\Alias($user, '2'));
$em
->persist($e0 = new User\Email($user, '1'))
->persist($e1 = new User\Email($user, '2'));
$em
->persist($p0 = new User\Phone($user, '1'))
->persist($p1 = new User\Phone($user, '2'));
$em->run();

self::assertCount(2, \array_intersect([1, 2], [$a0->id, $a1->id]));
self::assertCount(2, \array_intersect([1, 2], [$e0->id, $e1->id]));
self::assertCount(2, \array_intersect([1, 2], [$p0->id, $p1->id]));
unset($a0, $a1, $e0, $e1, $p0, $p1);

$this->orm->getHeap()->clean();

// delete old and persist new with same unique value
$em = (new EntityManager($this->orm));

/** @var User $user */
$user = $this->orm->getRepository(User::class)->findOne(['id' => 1]);
$user->username = 'up-username';
$em->persist($user);

$a0 = $this->orm->get(User\Alias::class, ['id' => 1]);
$a1 = $this->orm->get(User\Alias::class, ['id' => 2]);

$e0 = $this->orm->get(User\Email::class, ['id' => 1]);
$e1 = $this->orm->get(User\Email::class, ['id' => 2]);

$p0 = $this->orm->get(User\Phone::class, ['id' => 1]);
$p1 = $this->orm->get(User\Phone::class, ['id' => 2]);

$em
->delete($a0)
->delete($a1);
$em
->persist(new User\Alias($user, '1'))
->persist(new User\Alias($user, '2'));
$em
->delete($e0)
->delete($e1);
$em
->persist(new User\Email($user, '1'))
->persist(new User\Email($user, '2'));
$em
->delete($p0)
->delete($p1);
$em
->persist(new User\Phone($user, '1'))
->persist(new User\Phone($user, '2'));

$em->run();

self::assertTrue(true);
}

private function fetchFromTable(string $tableName): array
{
$db = $this->orm->getSource(User::class)->getDatabase();
$rows = $db->select('id', 'value')->from($tableName)->orderBy('id')->fetchAll();
$rows = $db
->select('id', 'value')
->from($tableName)
->orderBy('id')
->fetchAll();
// cast id to int specially for mssql
return array_map(function (array $row): array {
$row['id'] = (int) $row['id'];
return \array_map(function (array $row): array {
$row['id'] = (int)$row['id'];
return $row;
}, $rows);
}
Expand All @@ -142,20 +230,23 @@ private function makeTables(): void
'user_id' => 'int',
]);
$this->makeFK('user_alias', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION');
$this->makeIndex('user_alias', ['value'], true);

$this->makeTable('user_email', [
'id' => 'primary',
'value' => 'string',
'user_id' => 'int',
]);
$this->makeFK('user_email', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION');
$this->makeIndex('user_email', ['value'], true);

$this->makeTable('user_phone', [
'id' => 'primary',
'value' => 'string',
'user_id' => 'int',
]);
$this->makeFK('user_phone', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION');
$this->makeIndex('user_phone', ['value'], true);
}

private function fillData(): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity;
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity;

class User
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

class Alias
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

class Email
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

declare(strict_types=1);

namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

class Phone
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
use Cycle\ORM\SchemaInterface as Schema;
use Cycle\ORM\Select\Repository;
use Cycle\ORM\Select\Source;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\Comment;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\Post;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\PostTag;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\Tag;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Entity\User;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\Entity\User;

return [
'user' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Cycle\ORM\Tests\Functional\Driver\MySQL\Integration\Issue380;

// phpcs:ignore
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\CaseTest as CommonClass;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\CaseTest as CommonClass;

/**
* @group driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Cycle\ORM\Tests\Functional\Driver\Postgres\Integration\Issue380;

// phpcs:ignore
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\CaseTest as CommonClass;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\CaseTest as CommonClass;

/**
* @group driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Cycle\ORM\Tests\Functional\Driver\SQLServer\Integration\Issue380;

// phpcs:ignore
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\CaseTest as CommonClass;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue380\CaseTest as CommonClass;

/**
* @group driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Cycle\ORM\Tests\Functional\Driver\SQLite\Integration\Issue380;

// phpcs:ignore
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\CaseTest as CommonClass;
use Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case4\Issue380 as CommonClass;

/**
* @group driver
Expand Down

0 comments on commit 585bf62

Please sign in to comment.